]> granicus.if.org Git - imagemagick/blob - coders/msl.c
(no commit message)
[imagemagick] / coders / msl.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                             M   M  SSSSS  L                                 %
7 %                             MM MM  SS     L                                 %
8 %                             M M M   SSS   L                                 %
9 %                             M   M     SS  L                                 %
10 %                             M   M  SSSSS  LLLLL                             %
11 %                                                                             %
12 %                                                                             %
13 %                    Execute Magick Scripting Language Scripts.               %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                John Cristy                                  %
17 %                             Leonard Rosenthol                               %
18 %                             William Radcliffe                               %
19 %                               December 2001                                 %
20 %                                                                             %
21 %                                                                             %
22 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
23 %  dedicated to making software imaging solutions freely available.           %
24 %                                                                             %
25 %  You may not use this file except in compliance with the License.  You may  %
26 %  obtain a copy of the License at                                            %
27 %                                                                             %
28 %    http://www.imagemagick.org/script/license.php                            %
29 %                                                                             %
30 %  Unless required by applicable law or agreed to in writing, software        %
31 %  distributed under the License is distributed on an "AS IS" BASIS,          %
32 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
33 %  See the License for the specific language governing permissions and        %
34 %  limitations under the License.                                             %
35 %                                                                             %
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37 %
38 %
39 */
40 \f
41 /*
42   Include declarations.
43 */
44 #include "magick/studio.h"
45 #include "magick/annotate.h"
46 #include "magick/artifact.h"
47 #include "magick/blob.h"
48 #include "magick/blob-private.h"
49 #include "magick/cache.h"
50 #include "magick/cache-view.h"
51 #include "magick/color.h"
52 #include "magick/colormap.h"
53 #include "magick/color-private.h"
54 #include "magick/composite.h"
55 #include "magick/constitute.h"
56 #include "magick/decorate.h"
57 #include "magick/display.h"
58 #include "magick/draw.h"
59 #include "magick/effect.h"
60 #include "magick/enhance.h"
61 #include "magick/exception.h"
62 #include "magick/exception-private.h"
63 #include "magick/fx.h"
64 #include "magick/geometry.h"
65 #include "magick/image.h"
66 #include "magick/image-private.h"
67 #include "magick/list.h"
68 #include "magick/log.h"
69 #include "magick/magick.h"
70 #include "magick/memory_.h"
71 #include "magick/module.h"
72 #include "magick/option.h"
73 #include "magick/paint.h"
74 #include "magick/profile.h"
75 #include "magick/property.h"
76 #include "magick/quantize.h"
77 #include "magick/quantum-private.h"
78 #include "magick/registry.h"
79 #include "magick/resize.h"
80 #include "magick/resource_.h"
81 #include "magick/segment.h"
82 #include "magick/shear.h"
83 #include "magick/signature.h"
84 #include "magick/static.h"
85 #include "magick/string_.h"
86 #include "magick/string-private.h"
87 #include "magick/transform.h"
88 #include "magick/threshold.h"
89 #include "magick/utility.h"
90 #if defined(MAGICKCORE_XML_DELEGATE)
91 #  if defined(MAGICKCORE_WINDOWS_SUPPORT)
92 #    if defined(__MINGW32__)
93 #      define _MSC_VER
94 #    else
95 #      include <win32config.h>
96 #    endif
97 #  endif
98 #  include <libxml/parser.h>
99 #  include <libxml/xmlmemory.h>
100 #  include <libxml/parserInternals.h>
101 #  include <libxml/xmlerror.h>
102 #endif
103 \f
104 /*
105   Define Declatations.
106 */
107 #define ThrowMSLException(severity,tag,reason) \
108   (void) ThrowMagickException(msl_info->exception,GetMagickModule(),severity, \
109     tag,"`%s'",reason);
110 \f
111 /*
112   Typedef declaractions.
113 */
114 typedef struct _MSLGroupInfo
115 {
116   size_t
117     numImages;  /* how many images are in this group */
118 } MSLGroupInfo;
119
120 typedef struct _MSLInfo
121 {
122   ExceptionInfo
123     *exception;
124
125   ssize_t
126     n,
127     number_groups;
128
129   ImageInfo
130     **image_info;
131
132   DrawInfo
133    **draw_info;
134
135   Image
136     **attributes,
137     **image;
138
139   char
140     *content;
141
142   MSLGroupInfo
143     *group_info;
144
145 #if defined(MAGICKCORE_XML_DELEGATE)
146   xmlParserCtxtPtr
147     parser;
148
149   xmlDocPtr
150     document;
151 #endif
152 } MSLInfo;
153 \f
154 /*
155   Forward declarations.
156 */
157 #if defined(MAGICKCORE_XML_DELEGATE)
158 static MagickBooleanType
159   WriteMSLImage(const ImageInfo *,Image *);
160
161 static MagickBooleanType
162   SetMSLAttributes(MSLInfo *,const char *,const char *);
163 #endif
164 \f
165 #if defined(MAGICKCORE_XML_DELEGATE)
166 \f
167 /*
168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169 %                                                                             %
170 %                                                                             %
171 %                                                                             %
172 %   R e a d M S L I m a g e                                                   %
173 %                                                                             %
174 %                                                                             %
175 %                                                                             %
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 %
178 %  ReadMSLImage() reads a Magick Scripting Language file and returns it.
179 %  It allocates the memory necessary for the new Image structure and returns a
180 %  pointer to the new image.
181 %
182 %  The format of the ReadMSLImage method is:
183 %
184 %      Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
185 %
186 %  A description of each parameter follows:
187 %
188 %    o image_info: the image info.
189 %
190 %    o exception: return any errors or warnings in this structure.
191 %
192 */
193
194 #if defined(__cplusplus) || defined(c_plusplus)
195 extern "C" {
196 #endif
197
198 static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
199   ExceptionInfo *exception)
200 {
201   char
202     key[MaxTextExtent];
203
204   ExceptionInfo
205     *sans_exception;
206
207   Image
208     *image;
209
210   ImageInfo
211     *read_info;
212
213   (void) FormatMagickString(key,MaxTextExtent,"cache:%s",path);
214   sans_exception=AcquireExceptionInfo();
215   image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
216   sans_exception=DestroyExceptionInfo(sans_exception);
217   if (image != (Image *) NULL)
218     return(image);
219   read_info=CloneImageInfo(image_info);
220   (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
221   image=ReadImage(read_info,exception);
222   read_info=DestroyImageInfo(read_info);
223   if (image != (Image *) NULL)
224     (void) SetImageRegistry(ImageRegistryType,key,image,exception);
225   return(image);
226 }
227
228 static int IsPathDirectory(const char *path)
229 {
230   MagickBooleanType
231     status;
232
233   struct stat
234     attributes;
235
236   if ((path == (const char *) NULL) || (*path == '\0'))
237     return(MagickFalse);
238   status=GetPathAttributes(path,&attributes);
239   if (status == MagickFalse)
240     return(-1);
241   if (S_ISDIR(attributes.st_mode) == 0)
242     return(0);
243   return(1);
244 }
245
246 static int MSLIsStandalone(void *context)
247 {
248   MSLInfo
249     *msl_info;
250
251   /*
252     Is this document tagged standalone?
253   */
254   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.MSLIsStandalone()");
255   msl_info=(MSLInfo *) context;
256   return(msl_info->document->standalone == 1);
257 }
258
259 static int MSLHasInternalSubset(void *context)
260 {
261   MSLInfo
262     *msl_info;
263
264   /*
265     Does this document has an internal subset?
266   */
267   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
268     "  SAX.MSLHasInternalSubset()");
269   msl_info=(MSLInfo *) context;
270   return(msl_info->document->intSubset != NULL);
271 }
272
273 static int MSLHasExternalSubset(void *context)
274 {
275   MSLInfo
276     *msl_info;
277
278   /*
279     Does this document has an external subset?
280   */
281   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
282     "  SAX.MSLHasExternalSubset()");
283   msl_info=(MSLInfo *) context;
284   return(msl_info->document->extSubset != NULL);
285 }
286
287 static void MSLInternalSubset(void *context,const xmlChar *name,
288   const xmlChar *external_id,const xmlChar *system_id)
289 {
290   MSLInfo
291     *msl_info;
292
293   /*
294     Does this document has an internal subset?
295   */
296   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
297     "  SAX.internalSubset(%s %s %s)",name,
298     (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
299     (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
300   msl_info=(MSLInfo *) context;
301   (void) xmlCreateIntSubset(msl_info->document,name,external_id,system_id);
302 }
303
304 static xmlParserInputPtr MSLResolveEntity(void *context,
305   const xmlChar *public_id,const xmlChar *system_id)
306 {
307   MSLInfo
308     *msl_info;
309
310   xmlParserInputPtr
311     stream;
312
313   /*
314     Special entity resolver, better left to the parser, it has more
315     context than the application layer.  The default behaviour is to
316     not resolve the entities, in that case the ENTITY_REF nodes are
317     built in the structure (and the parameter values).
318   */
319   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
320     "  SAX.resolveEntity(%s, %s)",
321     (public_id != (const xmlChar *) NULL ? (const char *) public_id : "none"),
322     (system_id != (const xmlChar *) NULL ? (const char *) system_id : "none"));
323   msl_info=(MSLInfo *) context;
324   stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
325     public_id,msl_info->parser);
326   return(stream);
327 }
328
329 static xmlEntityPtr MSLGetEntity(void *context,const xmlChar *name)
330 {
331   MSLInfo
332     *msl_info;
333
334   /*
335     Get an entity by name.
336   */
337   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
338     "  SAX.MSLGetEntity(%s)",(const char *) name);
339   msl_info=(MSLInfo *) context;
340   return(xmlGetDocEntity(msl_info->document,name));
341 }
342
343 static xmlEntityPtr MSLGetParameterEntity(void *context,const xmlChar *name)
344 {
345   MSLInfo
346     *msl_info;
347
348   /*
349     Get a parameter entity by name.
350   */
351   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
352     "  SAX.getParameterEntity(%s)",(const char *) name);
353   msl_info=(MSLInfo *) context;
354   return(xmlGetParameterEntity(msl_info->document,name));
355 }
356
357 static void MSLEntityDeclaration(void *context,const xmlChar *name,int type,
358   const xmlChar *public_id,const xmlChar *system_id,xmlChar *content)
359 {
360   MSLInfo
361     *msl_info;
362
363   /*
364     An entity definition has been parsed.
365   */
366   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
367     "  SAX.entityDecl(%s, %d, %s, %s, %s)",name,type,
368     public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
369     system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
370     content);
371   msl_info=(MSLInfo *) context;
372   if (msl_info->parser->inSubset == 1)
373     (void) xmlAddDocEntity(msl_info->document,name,type,public_id,system_id,
374       content);
375   else
376     if (msl_info->parser->inSubset == 2)
377       (void) xmlAddDtdEntity(msl_info->document,name,type,public_id,system_id,
378         content);
379 }
380
381 static void MSLAttributeDeclaration(void *context,const xmlChar *element,
382   const xmlChar *name,int type,int value,const xmlChar *default_value,
383   xmlEnumerationPtr tree)
384 {
385   MSLInfo
386     *msl_info;
387
388   xmlChar
389     *fullname,
390     *prefix;
391
392   xmlParserCtxtPtr
393     parser;
394
395   /*
396     An attribute definition has been parsed.
397   */
398   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
399     "  SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",element,name,type,value,
400     default_value);
401   msl_info=(MSLInfo *) context;
402   fullname=(xmlChar *) NULL;
403   prefix=(xmlChar *) NULL;
404   parser=msl_info->parser;
405   fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
406   if (parser->inSubset == 1)
407     (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->intSubset,
408       element,fullname,prefix,(xmlAttributeType) type,
409       (xmlAttributeDefault) value,default_value,tree);
410   else
411     if (parser->inSubset == 2)
412       (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->extSubset,
413         element,fullname,prefix,(xmlAttributeType) type,
414         (xmlAttributeDefault) value,default_value,tree);
415   if (prefix != (xmlChar *) NULL)
416     xmlFree(prefix);
417   if (fullname != (xmlChar *) NULL)
418     xmlFree(fullname);
419 }
420
421 static void MSLElementDeclaration(void *context,const xmlChar *name,int type,
422   xmlElementContentPtr content)
423 {
424   MSLInfo
425     *msl_info;
426
427   xmlParserCtxtPtr
428     parser;
429
430   /*
431     An element definition has been parsed.
432   */
433   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
434     "  SAX.elementDecl(%s, %d, ...)",name,type);
435   msl_info=(MSLInfo *) context;
436   parser=msl_info->parser;
437   if (parser->inSubset == 1)
438     (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->intSubset,
439       name,(xmlElementTypeVal) type,content);
440   else
441     if (parser->inSubset == 2)
442       (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->extSubset,
443         name,(xmlElementTypeVal) type,content);
444 }
445
446 static void MSLNotationDeclaration(void *context,const xmlChar *name,
447   const xmlChar *public_id,const xmlChar *system_id)
448 {
449   MSLInfo
450     *msl_info;
451
452   xmlParserCtxtPtr
453     parser;
454
455   /*
456     What to do when a notation declaration has been parsed.
457   */
458   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
459     "  SAX.notationDecl(%s, %s, %s)",name,
460     public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
461     system_id != (const xmlChar *) NULL ? (const char *) system_id : "none");
462   msl_info=(MSLInfo *) context;
463   parser=msl_info->parser;
464   if (parser->inSubset == 1)
465     (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
466       name,public_id,system_id);
467   else
468     if (parser->inSubset == 2)
469       (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
470         name,public_id,system_id);
471 }
472
473 static void MSLUnparsedEntityDeclaration(void *context,const xmlChar *name,
474   const xmlChar *public_id,const xmlChar *system_id,const xmlChar *notation)
475 {
476   MSLInfo
477     *msl_info;
478
479   /*
480     What to do when an unparsed entity declaration is parsed.
481   */
482   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
483     "  SAX.unparsedEntityDecl(%s, %s, %s, %s)",name,
484     public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
485     system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
486     notation);
487   msl_info=(MSLInfo *) context;
488   (void) xmlAddDocEntity(msl_info->document,name,
489     XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,public_id,system_id,notation);
490
491 }
492
493 static void MSLSetDocumentLocator(void *context,xmlSAXLocatorPtr location)
494 {
495   MSLInfo
496     *msl_info;
497
498   /*
499     Receive the document locator at startup, actually xmlDefaultSAXLocator.
500   */
501   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
502     "  SAX.setDocumentLocator()\n");
503   (void) location;
504   msl_info=(MSLInfo *) context;
505   (void) msl_info;
506 }
507
508 static void MSLStartDocument(void *context)
509 {
510   MSLInfo
511     *msl_info;
512
513   xmlParserCtxtPtr
514     parser;
515
516   /*
517     Called when the document start being processed.
518   */
519   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
520     "  SAX.startDocument()");
521   msl_info=(MSLInfo *) context;
522   parser=msl_info->parser;
523   msl_info->document=xmlNewDoc(parser->version);
524   if (msl_info->document == (xmlDocPtr) NULL)
525     return;
526   if (parser->encoding == NULL)
527     msl_info->document->encoding=NULL;
528   else
529     msl_info->document->encoding=xmlStrdup(parser->encoding);
530   msl_info->document->standalone=parser->standalone;
531 }
532
533 static void MSLEndDocument(void *context)
534 {
535   MSLInfo
536     *msl_info;
537
538   /*
539     Called when the document end has been detected.
540   */
541   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.endDocument()");
542   msl_info=(MSLInfo *) context;
543   if (msl_info->content != (char *) NULL)
544     msl_info->content=DestroyString(msl_info->content);
545 }
546
547 static void MSLPushImage(MSLInfo *msl_info,Image *image)
548 {
549   ssize_t
550     n;
551
552   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
553   assert(msl_info != (MSLInfo *) NULL);
554   msl_info->n++;
555   n=msl_info->n;
556   msl_info->image_info=(ImageInfo **) ResizeQuantumMemory(msl_info->image_info,
557     (n+1),sizeof(*msl_info->image_info));
558   msl_info->draw_info=(DrawInfo **) ResizeQuantumMemory(msl_info->draw_info,
559     (n+1),sizeof(*msl_info->draw_info));
560   msl_info->attributes=(Image **) ResizeQuantumMemory(msl_info->attributes,
561     (n+1),sizeof(*msl_info->attributes));
562   msl_info->image=(Image **) ResizeQuantumMemory(msl_info->image,(n+1),
563     sizeof(*msl_info->image));
564   if ((msl_info->image_info == (ImageInfo **) NULL) ||
565     (msl_info->draw_info == (DrawInfo **) NULL) ||
566     (msl_info->attributes == (Image **) NULL) ||
567     (msl_info->image == (Image **) NULL))
568       ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
569   msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
570   msl_info->draw_info[n]=CloneDrawInfo(msl_info->image_info[n-1],
571     msl_info->draw_info[n-1]);
572   if (image == (Image *) NULL)
573     msl_info->attributes[n]=AcquireImage(msl_info->image_info[n]);
574   else
575     msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,&image->exception);
576   msl_info->image[n]=(Image *) image;
577   if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
578     (msl_info->attributes[n] == (Image *) NULL))
579     ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
580   if (msl_info->number_groups != 0)
581     msl_info->group_info[msl_info->number_groups-1].numImages++;
582 }
583
584 static void MSLPopImage(MSLInfo *msl_info)
585 {
586   if (msl_info->number_groups != 0)
587     return;
588   if (msl_info->image[msl_info->n] != (Image *) NULL)
589     msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
590   msl_info->attributes[msl_info->n]=DestroyImage(
591     msl_info->attributes[msl_info->n]);
592   msl_info->image_info[msl_info->n]=DestroyImageInfo(
593     msl_info->image_info[msl_info->n]);
594   msl_info->n--;
595 }
596
597 static void MSLStartElement(void *context,const xmlChar *tag,
598   const xmlChar **attributes)
599 {
600   AffineMatrix
601     affine,
602     current;
603
604   ChannelType
605     channel;
606
607   char
608     key[MaxTextExtent],
609     *value;
610
611   const char
612     *attribute,
613     *keyword;
614
615   double
616     angle;
617
618   DrawInfo
619     *draw_info;
620
621   ExceptionInfo
622     exception;
623
624   GeometryInfo
625     geometry_info;
626
627   Image
628     *image;
629
630   int
631     flags;
632
633   ssize_t
634     option,
635     j,
636     n,
637     x,
638     y;
639
640   MSLInfo
641     *msl_info;
642
643   RectangleInfo
644     geometry;
645
646   register ssize_t
647     i;
648
649   size_t
650     height,
651     width;
652
653   /*
654     Called when an opening tag has been processed.
655   */
656   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
657     "  SAX.startElement(%s",tag);
658   GetExceptionInfo(&exception);
659   msl_info=(MSLInfo *) context;
660   n=msl_info->n;
661   keyword=(const char *) NULL;
662   value=(char *) NULL;
663   SetGeometryInfo(&geometry_info);
664   channel=DefaultChannels;
665   switch (*tag)
666   {
667     case 'A':
668     case 'a':
669     {
670       if (LocaleCompare((const char *) tag,"add-noise") == 0)
671         {
672           Image
673             *noise_image;
674
675           NoiseType
676             noise;
677
678           /*
679             Add noise image.
680           */
681           if (msl_info->image[n] == (Image *) NULL)
682             {
683               ThrowMSLException(OptionError,"NoImagesDefined",
684                 (const char *) tag);
685               break;
686             }
687           noise=UniformNoise;
688           if (attributes != (const xmlChar **) NULL)
689             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
690             {
691               keyword=(const char *) attributes[i++];
692               attribute=InterpretImageProperties(msl_info->image_info[n],
693                 msl_info->attributes[n],(const char *) attributes[i]);
694               CloneString(&value,attribute);
695               switch (*keyword)
696               {
697                 case 'C':
698                 case 'c':
699                 {
700                   if (LocaleCompare(keyword,"channel") == 0)
701                     {
702                       option=ParseChannelOption(value);
703                       if (option < 0)
704                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
705                           value);
706                       channel=(ChannelType) option;
707                       break;
708                     }
709                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
710                     keyword);
711                   break;
712                 }
713                 case 'N':
714                 case 'n':
715                 {
716                   if (LocaleCompare(keyword,"noise") == 0)
717                     {
718                       option=ParseMagickOption(MagickNoiseOptions,MagickFalse,
719                         value);
720                       if (option < 0)
721                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
722                           value);
723                       noise=(NoiseType) option;
724                       break;
725                     }
726                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
727                     keyword);
728                   break;
729                 }
730                 default:
731                 {
732                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
733                     keyword);
734                   break;
735                 }
736               }
737             }
738           noise_image=AddNoiseImageChannel(msl_info->image[n],channel,noise,
739             &msl_info->image[n]->exception);
740           if (noise_image == (Image *) NULL)
741             break;
742           msl_info->image[n]=DestroyImage(msl_info->image[n]);
743           msl_info->image[n]=noise_image;
744           break;
745         }
746       if (LocaleCompare((const char *) tag,"annotate") == 0)
747         {
748           char
749             text[MaxTextExtent];
750
751           /*
752             Annotate image.
753           */
754           if (msl_info->image[n] == (Image *) NULL)
755             {
756               ThrowMSLException(OptionError,"NoImagesDefined",
757                 (const char *) tag);
758               break;
759             }
760           draw_info=CloneDrawInfo(msl_info->image_info[n],
761             msl_info->draw_info[n]);
762           angle=0.0;
763           current=draw_info->affine;
764           GetAffineMatrix(&affine);
765           if (attributes != (const xmlChar **) NULL)
766             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
767             {
768               keyword=(const char *) attributes[i++];
769               attribute=InterpretImageProperties(msl_info->image_info[n],
770                 msl_info->attributes[n],(const char *) attributes[i]);
771               CloneString(&value,attribute);
772               switch (*keyword)
773               {
774                 case 'A':
775                 case 'a':
776                 {
777                   if (LocaleCompare(keyword,"affine") == 0)
778                     {
779                       char
780                         *p;
781
782                       p=value;
783                       draw_info->affine.sx=strtod(p,&p);
784                       if (*p ==',')
785                         p++;
786                       draw_info->affine.rx=strtod(p,&p);
787                       if (*p ==',')
788                         p++;
789                       draw_info->affine.ry=strtod(p,&p);
790                       if (*p ==',')
791                         p++;
792                       draw_info->affine.sy=strtod(p,&p);
793                       if (*p ==',')
794                         p++;
795                       draw_info->affine.tx=strtod(p,&p);
796                       if (*p ==',')
797                         p++;
798                       draw_info->affine.ty=strtod(p,&p);
799                       break;
800                     }
801                   if (LocaleCompare(keyword,"align") == 0)
802                     {
803                       option=ParseMagickOption(MagickAlignOptions,MagickFalse,
804                         value);
805                       if (option < 0)
806                         ThrowMSLException(OptionError,"UnrecognizedAlignType",
807                           value);
808                       draw_info->align=(AlignType) option;
809                       break;
810                     }
811                   if (LocaleCompare(keyword,"antialias") == 0)
812                     {
813                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
814                         value);
815                       if (option < 0)
816                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
817                           value);
818                       draw_info->stroke_antialias=(MagickBooleanType) option;
819                       draw_info->text_antialias=(MagickBooleanType) option;
820                       break;
821                     }
822                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
823                     keyword);
824                   break;
825                 }
826                 case 'D':
827                 case 'd':
828                 {
829                   if (LocaleCompare(keyword,"density") == 0)
830                     {
831                       CloneString(&draw_info->density,value);
832                       break;
833                     }
834                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
835                     keyword);
836                   break;
837                 }
838                 case 'E':
839                 case 'e':
840                 {
841                   if (LocaleCompare(keyword,"encoding") == 0)
842                     {
843                       CloneString(&draw_info->encoding,value);
844                       break;
845                     }
846                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
847                     keyword);
848                   break;
849                 }
850                 case 'F':
851                 case 'f':
852                 {
853                   if (LocaleCompare(keyword, "fill") == 0)
854                     {
855                       (void) QueryColorDatabase(value,&draw_info->fill,
856                         &exception);
857                       break;
858                     }
859                   if (LocaleCompare(keyword,"family") == 0)
860                     {
861                       CloneString(&draw_info->family,value);
862                       break;
863                     }
864                   if (LocaleCompare(keyword,"font") == 0)
865                     {
866                       CloneString(&draw_info->font,value);
867                       break;
868                     }
869                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
870                     keyword);
871                   break;
872                 }
873                 case 'G':
874                 case 'g':
875                 {
876                   if (LocaleCompare(keyword,"geometry") == 0)
877                     {
878                       flags=ParsePageGeometry(msl_info->image[n],value,
879                         &geometry,&exception);
880                       if ((flags & HeightValue) == 0)
881                         geometry.height=geometry.width;
882                       break;
883                     }
884                   if (LocaleCompare(keyword,"gravity") == 0)
885                     {
886                       option=ParseMagickOption(MagickGravityOptions,MagickFalse,
887                         value);
888                       if (option < 0)
889                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
890                           value);
891                       draw_info->gravity=(GravityType) option;
892                       break;
893                     }
894                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
895                     keyword);
896                   break;
897                 }
898                 case 'P':
899                 case 'p':
900                 {
901                   if (LocaleCompare(keyword,"pointsize") == 0)
902                     {
903                       draw_info->pointsize=StringToDouble(value);
904                       break;
905                     }
906                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
907                     keyword);
908                   break;
909                 }
910                 case 'R':
911                 case 'r':
912                 {
913                   if (LocaleCompare(keyword,"rotate") == 0)
914                     {
915                       angle=StringToDouble(value);
916                       affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
917                       affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
918                       affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
919                       affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
920                       break;
921                     }
922                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
923                     keyword);
924                   break;
925                 }
926                 case 'S':
927                 case 's':
928                 {
929                   if (LocaleCompare(keyword,"scale") == 0)
930                     {
931                       flags=ParseGeometry(value,&geometry_info);
932                       if ((flags & SigmaValue) == 0)
933                         geometry_info.sigma=1.0;
934                       affine.sx=geometry_info.rho;
935                       affine.sy=geometry_info.sigma;
936                       break;
937                     }
938                   if (LocaleCompare(keyword,"skewX") == 0)
939                     {
940                       angle=StringToDouble(value);
941                       affine.ry=tan(DegreesToRadians(fmod((double) angle,
942                         360.0)));
943                       break;
944                     }
945                   if (LocaleCompare(keyword,"skewY") == 0)
946                     {
947                       angle=StringToDouble(value);
948                       affine.rx=tan(DegreesToRadians(fmod((double) angle,
949                         360.0)));
950                       break;
951                     }
952                   if (LocaleCompare(keyword,"stretch") == 0)
953                     {
954                       option=ParseMagickOption(MagickStretchOptions,MagickFalse,
955                         value);
956                       if (option < 0)
957                         ThrowMSLException(OptionError,"UnrecognizedStretchType",
958                           value);
959                       draw_info->stretch=(StretchType) option;
960                       break;
961                     }
962                   if (LocaleCompare(keyword, "stroke") == 0)
963                     {
964                       (void) QueryColorDatabase(value,&draw_info->stroke,
965                         &exception);
966                       break;
967                     }
968                   if (LocaleCompare(keyword,"strokewidth") == 0)
969                     {
970                       draw_info->stroke_width=StringToLong(value);
971                       break;
972                     }
973                   if (LocaleCompare(keyword,"style") == 0)
974                     {
975                       option=ParseMagickOption(MagickStyleOptions,MagickFalse,
976                         value);
977                       if (option < 0)
978                         ThrowMSLException(OptionError,"UnrecognizedStyleType",
979                           value);
980                       draw_info->style=(StyleType) option;
981                       break;
982                     }
983                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
984                     keyword);
985                   break;
986                 }
987                 case 'T':
988                 case 't':
989                 {
990                   if (LocaleCompare(keyword,"text") == 0)
991                     {
992                       CloneString(&draw_info->text,value);
993                       break;
994                     }
995                   if (LocaleCompare(keyword,"translate") == 0)
996                     {
997                       flags=ParseGeometry(value,&geometry_info);
998                       if ((flags & SigmaValue) == 0)
999                         geometry_info.sigma=1.0;
1000                       affine.tx=geometry_info.rho;
1001                       affine.ty=geometry_info.sigma;
1002                       break;
1003                     }
1004                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1005                     keyword);
1006                   break;
1007                 }
1008                 case 'U':
1009                 case 'u':
1010                 {
1011                   if (LocaleCompare(keyword, "undercolor") == 0)
1012                     {
1013                       (void) QueryColorDatabase(value,&draw_info->undercolor,
1014                         &exception);
1015                       break;
1016                     }
1017                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1018                     keyword);
1019                   break;
1020                 }
1021                 case 'W':
1022                 case 'w':
1023                 {
1024                   if (LocaleCompare(keyword,"weight") == 0)
1025                     {
1026                       draw_info->weight=StringToLong(value);
1027                       break;
1028                     }
1029                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1030                     keyword);
1031                   break;
1032                 }
1033                 case 'X':
1034                 case 'x':
1035                 {
1036                   if (LocaleCompare(keyword,"x") == 0)
1037                     {
1038                       geometry.x=StringToLong(value);
1039                       break;
1040                     }
1041                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1042                     keyword);
1043                   break;
1044                 }
1045                 case 'Y':
1046                 case 'y':
1047                 {
1048                   if (LocaleCompare(keyword,"y") == 0)
1049                     {
1050                       geometry.y=StringToLong(value);
1051                       break;
1052                     }
1053                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1054                     keyword);
1055                   break;
1056                 }
1057                 default:
1058                 {
1059                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1060                     keyword);
1061                   break;
1062                 }
1063               }
1064             }
1065           (void) FormatMagickString(text,MaxTextExtent,
1066             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
1067             geometry.height,(double) geometry.x,(double) geometry.y);
1068           CloneString(&draw_info->geometry,text);
1069           draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
1070           draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
1071           draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
1072           draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
1073           draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
1074             affine.tx;
1075           draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
1076             affine.ty;
1077           (void) AnnotateImage(msl_info->image[n],draw_info);
1078           draw_info=DestroyDrawInfo(draw_info);
1079           break;
1080         }
1081       if (LocaleCompare((const char *) tag,"append") == 0)
1082         {
1083           Image
1084             *append_image;
1085
1086           MagickBooleanType
1087             stack;
1088
1089           if (msl_info->image[n] == (Image *) NULL)
1090             {
1091               ThrowMSLException(OptionError,"NoImagesDefined",
1092                 (const char *) tag);
1093               break;
1094             }
1095           stack=MagickFalse;
1096           if (attributes != (const xmlChar **) NULL)
1097             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1098             {
1099               keyword=(const char *) attributes[i++];
1100               attribute=InterpretImageProperties(msl_info->image_info[n],
1101                 msl_info->attributes[n],(const char *) attributes[i]);
1102               CloneString(&value,attribute);
1103               switch (*keyword)
1104               {
1105                 case 'S':
1106                 case 's':
1107                 {
1108                   if (LocaleCompare(keyword,"stack") == 0)
1109                     {
1110                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
1111                         value);
1112                       if (option < 0)
1113                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1114                           value);
1115                       stack=(MagickBooleanType) option;
1116                       break;
1117                     }
1118                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1119                     keyword);
1120                   break;
1121                 }
1122                 default:
1123                 {
1124                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1125                     keyword);
1126                   break;
1127                 }
1128               }
1129             }
1130           append_image=AppendImages(msl_info->image[n],stack,
1131             &msl_info->image[n]->exception);
1132           if (append_image == (Image *) NULL)
1133             break;
1134           msl_info->image[n]=DestroyImage(msl_info->image[n]);
1135           msl_info->image[n]=append_image;
1136           break;
1137         }
1138       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1139       break;
1140     }
1141     case 'B':
1142     case 'b':
1143     {
1144       if (LocaleCompare((const char *) tag,"blur") == 0)
1145         {
1146           Image
1147             *blur_image;
1148
1149           /*
1150             Blur image.
1151           */
1152           if (msl_info->image[n] == (Image *) NULL)
1153             {
1154               ThrowMSLException(OptionError,"NoImagesDefined",
1155                 (const char *) tag);
1156               break;
1157             }
1158           if (attributes != (const xmlChar **) NULL)
1159             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1160             {
1161               keyword=(const char *) attributes[i++];
1162               attribute=InterpretImageProperties(msl_info->image_info[n],
1163                 msl_info->attributes[n],(const char *) attributes[i]);
1164               CloneString(&value,attribute);
1165               switch (*keyword)
1166               {
1167                 case 'C':
1168                 case 'c':
1169                 {
1170                   if (LocaleCompare(keyword,"channel") == 0)
1171                     {
1172                       option=ParseChannelOption(value);
1173                       if (option < 0)
1174                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
1175                           value);
1176                       channel=(ChannelType) option;
1177                       break;
1178                     }
1179                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1180                     keyword);
1181                   break;
1182                 }
1183                 case 'G':
1184                 case 'g':
1185                 {
1186                   if (LocaleCompare(keyword,"geometry") == 0)
1187                     {
1188                       flags=ParseGeometry(value,&geometry_info);
1189                       if ((flags & SigmaValue) == 0)
1190                         geometry_info.sigma=1.0;
1191                       break;
1192                     }
1193                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1194                     keyword);
1195                   break;
1196                 }
1197                 case 'R':
1198                 case 'r':
1199                 {
1200                   if (LocaleCompare(keyword,"radius") == 0)
1201                     {
1202                       geometry_info.rho=StringToDouble(value);
1203                       break;
1204                     }
1205                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1206                     keyword);
1207                   break;
1208                 }
1209                 case 'S':
1210                 case 's':
1211                 {
1212                   if (LocaleCompare(keyword,"sigma") == 0)
1213                     {
1214                       geometry_info.sigma=StringToLong(value);
1215                       break;
1216                     }
1217                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1218                     keyword);
1219                   break;
1220                 }
1221                 default:
1222                 {
1223                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1224                     keyword);
1225                   break;
1226                 }
1227               }
1228             }
1229           blur_image=BlurImageChannel(msl_info->image[n],channel,
1230             geometry_info.rho,geometry_info.sigma,
1231             &msl_info->image[n]->exception);
1232           if (blur_image == (Image *) NULL)
1233             break;
1234           msl_info->image[n]=DestroyImage(msl_info->image[n]);
1235           msl_info->image[n]=blur_image;
1236           break;
1237         }
1238       if (LocaleCompare((const char *) tag,"border") == 0)
1239         {
1240           Image
1241             *border_image;
1242
1243           /*
1244             Border image.
1245           */
1246           if (msl_info->image[n] == (Image *) NULL)
1247             {
1248               ThrowMSLException(OptionError,"NoImagesDefined",
1249                 (const char *) tag);
1250               break;
1251             }
1252           SetGeometry(msl_info->image[n],&geometry);
1253           if (attributes != (const xmlChar **) NULL)
1254             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1255             {
1256               keyword=(const char *) attributes[i++];
1257               attribute=InterpretImageProperties(msl_info->image_info[n],
1258                 msl_info->attributes[n],(const char *) attributes[i]);
1259               CloneString(&value,attribute);
1260               switch (*keyword)
1261               {
1262                 case 'C':
1263                 case 'c':
1264                 {
1265                   if (LocaleCompare(keyword,"compose") == 0)
1266                     {
1267                       option=ParseMagickOption(MagickComposeOptions,MagickFalse,
1268                         value);
1269                       if (option < 0)
1270                         ThrowMSLException(OptionError,"UnrecognizedComposeType",
1271                           value);
1272                       msl_info->image[n]->compose=(CompositeOperator) option;
1273                       break;
1274                     }
1275                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1276                     keyword);
1277                   break;
1278                 }
1279                 case 'F':
1280                 case 'f':
1281                 {
1282                   if (LocaleCompare(keyword, "fill") == 0)
1283                     {
1284                       (void) QueryColorDatabase(value,
1285                         &msl_info->image[n]->border_color,&exception);
1286                       break;
1287                     }
1288                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1289                     keyword);
1290                   break;
1291                 }
1292                 case 'G':
1293                 case 'g':
1294                 {
1295                   if (LocaleCompare(keyword,"geometry") == 0)
1296                     {
1297                       flags=ParsePageGeometry(msl_info->image[n],value,
1298                         &geometry,&exception);
1299                       if ((flags & HeightValue) == 0)
1300                         geometry.height=geometry.width;
1301                       break;
1302                     }
1303                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1304                     keyword);
1305                   break;
1306                 }
1307                 case 'H':
1308                 case 'h':
1309                 {
1310                   if (LocaleCompare(keyword,"height") == 0)
1311                     {
1312                       geometry.height=StringToLong(value);
1313                       break;
1314                     }
1315                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1316                     keyword);
1317                   break;
1318                 }
1319                 case 'W':
1320                 case 'w':
1321                 {
1322                   if (LocaleCompare(keyword,"width") == 0)
1323                     {
1324                       geometry.width=StringToLong(value);
1325                       break;
1326                     }
1327                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1328                     keyword);
1329                   break;
1330                 }
1331                 default:
1332                 {
1333                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1334                     keyword);
1335                   break;
1336                 }
1337               }
1338             }
1339           border_image=BorderImage(msl_info->image[n],&geometry,
1340             &msl_info->image[n]->exception);
1341           if (border_image == (Image *) NULL)
1342             break;
1343           msl_info->image[n]=DestroyImage(msl_info->image[n]);
1344           msl_info->image[n]=border_image;
1345           break;
1346         }
1347       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1348     }
1349     case 'C':
1350     case 'c':
1351     {
1352       if (LocaleCompare((const char *) tag,"colorize") == 0)
1353         {
1354           char
1355             opacity[MaxTextExtent];
1356
1357           Image
1358             *colorize_image;
1359
1360           PixelPacket
1361             target;
1362
1363           /*
1364             Add noise image.
1365           */
1366           if (msl_info->image[n] == (Image *) NULL)
1367             {
1368               ThrowMSLException(OptionError,"NoImagesDefined",
1369                 (const char *) tag);
1370               break;
1371             }
1372           target=msl_info->image[n]->background_color;
1373           (void) CopyMagickString(opacity,"100",MaxTextExtent);
1374           if (attributes != (const xmlChar **) NULL)
1375             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1376             {
1377               keyword=(const char *) attributes[i++];
1378               attribute=InterpretImageProperties(msl_info->image_info[n],
1379                 msl_info->attributes[n],(const char *) attributes[i]);
1380               CloneString(&value,attribute);
1381               switch (*keyword)
1382               {
1383                 case 'F':
1384                 case 'f':
1385                 {
1386                   if (LocaleCompare(keyword,"fill") == 0)
1387                     {
1388                       (void) QueryColorDatabase(value,&target,
1389                         &msl_info->image[n]->exception);
1390                       break;
1391                     }
1392                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1393                     keyword);
1394                   break;
1395                 }
1396                 case 'O':
1397                 case 'o':
1398                 {
1399                   if (LocaleCompare(keyword,"opacity") == 0)
1400                     {
1401                       (void) CopyMagickString(opacity,value,MaxTextExtent);
1402                       break;
1403                     }
1404                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1405                     keyword);
1406                   break;
1407                 }
1408                 default:
1409                 {
1410                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1411                     keyword);
1412                   break;
1413                 }
1414               }
1415             }
1416           colorize_image=ColorizeImage(msl_info->image[n],opacity,target,
1417             &msl_info->image[n]->exception);
1418           if (colorize_image == (Image *) NULL)
1419             break;
1420           msl_info->image[n]=DestroyImage(msl_info->image[n]);
1421           msl_info->image[n]=colorize_image;
1422           break;
1423         }
1424       if (LocaleCompare((const char *) tag, "charcoal") == 0)
1425       {
1426         double  radius = 0.0,
1427             sigma = 1.0;
1428
1429         if (msl_info->image[n] == (Image *) NULL)
1430         {
1431           ThrowMSLException(OptionError,"NoImagesDefined",
1432             (const char *) tag);
1433           break;
1434         }
1435         /*
1436         NOTE: charcoal can have no attributes, since we use all the defaults!
1437         */
1438         if (attributes != (const xmlChar **) NULL)
1439         {
1440           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1441           {
1442           keyword=(const char *) attributes[i++];
1443           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
1444             msl_info->attributes[n],(const char *) attributes[i]));
1445           switch (*keyword)
1446           {
1447             case 'R':
1448             case 'r':
1449             {
1450               if (LocaleCompare(keyword, "radius") == 0)
1451               {
1452                 radius = StringToDouble( value );
1453                 break;
1454               }
1455               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1456               break;
1457             }
1458             case 'S':
1459             case 's':
1460             {
1461               if (LocaleCompare(keyword,"sigma") == 0)
1462               {
1463                 sigma = StringToLong( value );
1464                 break;
1465               }
1466               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1467               break;
1468             }
1469             default:
1470             {
1471               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1472               break;
1473             }
1474           }
1475           }
1476         }
1477
1478         /*
1479           charcoal image.
1480         */
1481         {
1482         Image
1483           *newImage;
1484
1485         newImage=CharcoalImage(msl_info->image[n],radius,sigma,
1486           &msl_info->image[n]->exception);
1487         if (newImage == (Image *) NULL)
1488           break;
1489         msl_info->image[n]=DestroyImage(msl_info->image[n]);
1490         msl_info->image[n]=newImage;
1491         break;
1492         }
1493       }
1494       if (LocaleCompare((const char *) tag,"chop") == 0)
1495         {
1496           Image
1497             *chop_image;
1498
1499           /*
1500             Chop image.
1501           */
1502           if (msl_info->image[n] == (Image *) NULL)
1503             {
1504               ThrowMSLException(OptionError,"NoImagesDefined",
1505                 (const char *) tag);
1506               break;
1507             }
1508           SetGeometry(msl_info->image[n],&geometry);
1509           if (attributes != (const xmlChar **) NULL)
1510             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1511             {
1512               keyword=(const char *) attributes[i++];
1513               attribute=InterpretImageProperties(msl_info->image_info[n],
1514                 msl_info->attributes[n],(const char *) attributes[i]);
1515               CloneString(&value,attribute);
1516               switch (*keyword)
1517               {
1518                 case 'G':
1519                 case 'g':
1520                 {
1521                   if (LocaleCompare(keyword,"geometry") == 0)
1522                     {
1523                       flags=ParsePageGeometry(msl_info->image[n],value,
1524                         &geometry,&exception);
1525                       if ((flags & HeightValue) == 0)
1526                         geometry.height=geometry.width;
1527                       break;
1528                     }
1529                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1530                     keyword);
1531                   break;
1532                 }
1533                 case 'H':
1534                 case 'h':
1535                 {
1536                   if (LocaleCompare(keyword,"height") == 0)
1537                     {
1538                       geometry.height=StringToLong(value);
1539                       break;
1540                     }
1541                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1542                     keyword);
1543                   break;
1544                 }
1545                 case 'W':
1546                 case 'w':
1547                 {
1548                   if (LocaleCompare(keyword,"width") == 0)
1549                     {
1550                       geometry.width=StringToLong(value);
1551                       break;
1552                     }
1553                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1554                     keyword);
1555                   break;
1556                 }
1557                 case 'X':
1558                 case 'x':
1559                 {
1560                   if (LocaleCompare(keyword,"x") == 0)
1561                     {
1562                       geometry.x=StringToLong(value);
1563                       break;
1564                     }
1565                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1566                     keyword);
1567                   break;
1568                 }
1569                 case 'Y':
1570                 case 'y':
1571                 {
1572                   if (LocaleCompare(keyword,"y") == 0)
1573                     {
1574                       geometry.y=StringToLong(value);
1575                       break;
1576                     }
1577                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1578                     keyword);
1579                   break;
1580                 }
1581                 default:
1582                 {
1583                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1584                     keyword);
1585                   break;
1586                 }
1587               }
1588             }
1589           chop_image=ChopImage(msl_info->image[n],&geometry,
1590             &msl_info->image[n]->exception);
1591           if (chop_image == (Image *) NULL)
1592             break;
1593           msl_info->image[n]=DestroyImage(msl_info->image[n]);
1594           msl_info->image[n]=chop_image;
1595           break;
1596         }
1597       if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
1598         {
1599           PaintMethod
1600             paint_method;
1601
1602           MagickPixelPacket
1603             target;
1604
1605           /*
1606             Color floodfill image.
1607           */
1608           if (msl_info->image[n] == (Image *) NULL)
1609             {
1610               ThrowMSLException(OptionError,"NoImagesDefined",
1611                 (const char *) tag);
1612               break;
1613             }
1614           draw_info=CloneDrawInfo(msl_info->image_info[n],
1615             msl_info->draw_info[n]);
1616           SetGeometry(msl_info->image[n],&geometry);
1617           paint_method=FloodfillMethod;
1618           if (attributes != (const xmlChar **) NULL)
1619             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1620             {
1621               keyword=(const char *) attributes[i++];
1622               attribute=InterpretImageProperties(msl_info->image_info[n],
1623                 msl_info->attributes[n],(const char *) attributes[i]);
1624               CloneString(&value,attribute);
1625               switch (*keyword)
1626               {
1627                 case 'B':
1628                 case 'b':
1629                 {
1630                   if (LocaleCompare(keyword,"bordercolor") == 0)
1631                     {
1632                       (void) QueryMagickColor(value,&target,&exception);
1633                       paint_method=FillToBorderMethod;
1634                       break;
1635                     }
1636                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1637                     keyword);
1638                   break;
1639                 }
1640                 case 'F':
1641                 case 'f':
1642                 {
1643                   if (LocaleCompare(keyword,"fill") == 0)
1644                     {
1645                       (void) QueryColorDatabase(value,&draw_info->fill,
1646                         &exception);
1647                       break;
1648                     }
1649                   if (LocaleCompare(keyword,"fuzz") == 0)
1650                     {
1651                       msl_info->image[n]->fuzz=StringToDouble(value);
1652                       break;
1653                     }
1654                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1655                     keyword);
1656                   break;
1657                 }
1658                 case 'G':
1659                 case 'g':
1660                 {
1661                   if (LocaleCompare(keyword,"geometry") == 0)
1662                     {
1663                       flags=ParsePageGeometry(msl_info->image[n],value,
1664                         &geometry,&exception);
1665                       if ((flags & HeightValue) == 0)
1666                         geometry.height=geometry.width;
1667                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
1668                         geometry.x,geometry.y,&target,&exception);
1669                       break;
1670                     }
1671                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1672                     keyword);
1673                   break;
1674                 }
1675                 case 'X':
1676                 case 'x':
1677                 {
1678                   if (LocaleCompare(keyword,"x") == 0)
1679                     {
1680                       geometry.x=StringToLong(value);
1681                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
1682                         geometry.x,geometry.y,&target,&exception);
1683                       break;
1684                     }
1685                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1686                     keyword);
1687                   break;
1688                 }
1689                 case 'Y':
1690                 case 'y':
1691                 {
1692                   if (LocaleCompare(keyword,"y") == 0)
1693                     {
1694                       geometry.y=StringToLong(value);
1695                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
1696                         geometry.x,geometry.y,&target,&exception);
1697                       break;
1698                     }
1699                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1700                     keyword);
1701                   break;
1702                 }
1703                 default:
1704                 {
1705                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1706                     keyword);
1707                   break;
1708                 }
1709               }
1710             }
1711           (void) FloodfillPaintImage(msl_info->image[n],DefaultChannels,
1712             draw_info,&target,geometry.x,geometry.y,
1713             paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
1714           draw_info=DestroyDrawInfo(draw_info);
1715           break;
1716         }
1717       if (LocaleCompare((const char *) tag,"comment") == 0)
1718         break;
1719       if (LocaleCompare((const char *) tag,"composite") == 0)
1720         {
1721           char
1722             composite_geometry[MaxTextExtent];
1723
1724           CompositeOperator
1725             compose;
1726
1727           Image
1728             *composite_image,
1729             *rotate_image;
1730
1731           PixelPacket
1732             target;
1733
1734           /*
1735             Composite image.
1736           */
1737           if (msl_info->image[n] == (Image *) NULL)
1738             {
1739               ThrowMSLException(OptionError,"NoImagesDefined",
1740                 (const char *) tag);
1741               break;
1742             }
1743           composite_image=NewImageList();
1744           compose=OverCompositeOp;
1745           if (attributes != (const xmlChar **) NULL)
1746             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1747             {
1748               keyword=(const char *) attributes[i++];
1749               attribute=InterpretImageProperties(msl_info->image_info[n],
1750                 msl_info->attributes[n],(const char *) attributes[i]);
1751               CloneString(&value,attribute);
1752               switch (*keyword)
1753               {
1754                 case 'C':
1755                 case 'c':
1756                 {
1757                   if (LocaleCompare(keyword,"compose") == 0)
1758                     {
1759                       option=ParseMagickOption(MagickComposeOptions,MagickFalse,
1760                         value);
1761                       if (option < 0)
1762                         ThrowMSLException(OptionError,"UnrecognizedComposeType",
1763                           value);
1764                       compose=(CompositeOperator) option;
1765                       break;
1766                     }
1767                   break;
1768                 }
1769                 case 'I':
1770                 case 'i':
1771                 {
1772                   if (LocaleCompare(keyword,"image") == 0)
1773                     for (j=0; j < msl_info->n; j++)
1774                     {
1775                       const char
1776                         *attribute;
1777
1778                       attribute=GetImageProperty(msl_info->attributes[j],"id");
1779                       if ((attribute != (const char *) NULL)  &&
1780                           (LocaleCompare(attribute,value) == 0))
1781                         {
1782                           composite_image=CloneImage(msl_info->image[j],0,0,
1783                             MagickFalse,&exception);
1784                           break;
1785                         }
1786                     }
1787                   break;
1788                 }
1789                 default:
1790                   break;
1791               }
1792             }
1793           if (composite_image == (Image *) NULL)
1794             break;
1795           rotate_image=NewImageList();
1796           SetGeometry(msl_info->image[n],&geometry);
1797           if (attributes != (const xmlChar **) NULL)
1798             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1799             {
1800               keyword=(const char *) attributes[i++];
1801               attribute=InterpretImageProperties(msl_info->image_info[n],
1802                 msl_info->attributes[n],(const char *) attributes[i]);
1803               CloneString(&value,attribute);
1804               switch (*keyword)
1805               {
1806                 case 'B':
1807                 case 'b':
1808                 {
1809                   if (LocaleCompare(keyword,"blend") == 0)
1810                     {
1811                       (void) SetImageArtifact(composite_image,
1812                                             "compose:args",value);
1813                       break;
1814                     }
1815                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1816                     keyword);
1817                   break;
1818                 }
1819                 case 'C':
1820                 case 'c':
1821                 {
1822                   if (LocaleCompare(keyword,"channel") == 0)
1823                     {
1824                       option=ParseChannelOption(value);
1825                       if (option < 0)
1826                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
1827                           value);
1828                       channel=(ChannelType) option;
1829                       break;
1830                     }
1831                   if (LocaleCompare(keyword, "color") == 0)
1832                     {
1833                       (void) QueryColorDatabase(value,
1834                         &composite_image->background_color,&exception);
1835                       break;
1836                     }
1837                   if (LocaleCompare(keyword,"compose") == 0)
1838                     break;
1839                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1840                     keyword);
1841                   break;
1842                 }
1843                 case 'G':
1844                 case 'g':
1845                 {
1846                   if (LocaleCompare(keyword,"geometry") == 0)
1847                     {
1848                       flags=ParsePageGeometry(msl_info->image[n],value,
1849                         &geometry,&exception);
1850                       if ((flags & HeightValue) == 0)
1851                         geometry.height=geometry.width;
1852                       (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
1853                         geometry.y,&target,&exception);
1854                       break;
1855                     }
1856                   if (LocaleCompare(keyword,"gravity") == 0)
1857                     {
1858                       option=ParseMagickOption(MagickGravityOptions,MagickFalse,
1859                         value);
1860                       if (option < 0)
1861                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
1862                           value);
1863                       msl_info->image[n]->gravity=(GravityType) option;
1864                       break;
1865                     }
1866                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1867                     keyword);
1868                   break;
1869                 }
1870                 case 'I':
1871                 case 'i':
1872                 {
1873                   if (LocaleCompare(keyword,"image") == 0)
1874                     break;
1875                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1876                     keyword);
1877                   break;
1878                 }
1879                 case 'M':
1880                 case 'm':
1881                 {
1882                   if (LocaleCompare(keyword,"mask") == 0)
1883                     for (j=0; j < msl_info->n; j++)
1884                     {
1885                       const char
1886                         *attribute;
1887
1888                       attribute=GetImageProperty(msl_info->attributes[j],"id");
1889                       if ((attribute != (const char *) NULL)  &&
1890                           (LocaleCompare(value,value) == 0))
1891                         {
1892                           SetImageType(composite_image,TrueColorMatteType);
1893                           (void) CompositeImage(composite_image,
1894                             CopyOpacityCompositeOp,msl_info->image[j],0,0);
1895                           break;
1896                         }
1897                     }
1898                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1899                     keyword);
1900                   break;
1901                 }
1902                 case 'O':
1903                 case 'o':
1904                 {
1905                   if (LocaleCompare(keyword,"opacity") == 0)
1906                     {
1907                       ssize_t
1908                         opacity,
1909                         y;
1910
1911                       register ssize_t
1912                         x;
1913
1914                       register PixelPacket
1915                         *q;
1916
1917                       CacheView
1918                         *composite_view;
1919
1920                       opacity=QuantumRange-StringToLong(value);
1921                       if (compose != DissolveCompositeOp)
1922                         {
1923                           (void) SetImageOpacity(composite_image,(Quantum)
1924                             opacity);
1925                           break;
1926                         }
1927                       (void) SetImageArtifact(msl_info->image[n],
1928                                             "compose:args",value);
1929                       if (composite_image->matte != MagickTrue)
1930                         (void) SetImageOpacity(composite_image,OpaqueOpacity);
1931                       composite_view=AcquireCacheView(composite_image);
1932                       for (y=0; y < (ssize_t) composite_image->rows ; y++)
1933                       {
1934                         q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
1935                           composite_image->columns,1,&exception);
1936                         for (x=0; x < (ssize_t) composite_image->columns; x++)
1937                         {
1938                           if (q->opacity == OpaqueOpacity)
1939                             q->opacity=ClampToQuantum(opacity);
1940                           q++;
1941                         }
1942                         if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1943                           break;
1944                       }
1945                       composite_view=DestroyCacheView(composite_view);
1946                       break;
1947                     }
1948                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1949                     keyword);
1950                   break;
1951                 }
1952                 case 'R':
1953                 case 'r':
1954                 {
1955                   if (LocaleCompare(keyword,"rotate") == 0)
1956                     {
1957                       rotate_image=RotateImage(composite_image,StringToDouble(value),
1958                         &exception);
1959                       break;
1960                     }
1961                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1962                     keyword);
1963                   break;
1964                 }
1965                 case 'T':
1966                 case 't':
1967                 {
1968                   if (LocaleCompare(keyword,"tile") == 0)
1969                     {
1970                       MagickBooleanType
1971                         tile;
1972
1973                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
1974                         value);
1975                       if (option < 0)
1976                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1977                           value);
1978                       tile=(MagickBooleanType) option;
1979                       (void) tile;
1980                       if (rotate_image != (Image *) NULL)
1981                         (void) SetImageArtifact(rotate_image,
1982                           "compose:outside-overlay","false");
1983                       else
1984                         (void) SetImageArtifact(composite_image,
1985                           "compose:outside-overlay","false");
1986                        image=msl_info->image[n];
1987                        height=composite_image->rows;
1988                        width=composite_image->columns;
1989                        for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
1990                          for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
1991                          {
1992                            if (rotate_image != (Image *) NULL)
1993                              (void) CompositeImage(image,compose,rotate_image,
1994                                x,y);
1995                            else
1996                              (void) CompositeImage(image,compose,
1997                                composite_image,x,y);
1998                          }
1999                       if (rotate_image != (Image *) NULL)
2000                         rotate_image=DestroyImage(rotate_image);
2001                       break;
2002                     }
2003                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2004                     keyword);
2005                   break;
2006                 }
2007                 case 'X':
2008                 case 'x':
2009                 {
2010                   if (LocaleCompare(keyword,"x") == 0)
2011                     {
2012                       geometry.x=StringToLong(value);
2013                       (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2014                         geometry.y,&target,&exception);
2015                       break;
2016                     }
2017                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2018                     keyword);
2019                   break;
2020                 }
2021                 case 'Y':
2022                 case 'y':
2023                 {
2024                   if (LocaleCompare(keyword,"y") == 0)
2025                     {
2026                       geometry.y=StringToLong(value);
2027                       (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2028                         geometry.y,&target,&exception);
2029                       break;
2030                     }
2031                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2032                     keyword);
2033                   break;
2034                 }
2035                 default:
2036                 {
2037                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2038                     keyword);
2039                   break;
2040                 }
2041               }
2042             }
2043           image=msl_info->image[n];
2044           (void) FormatMagickString(composite_geometry,MaxTextExtent,
2045             "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2046             (double) composite_image->rows,(double) geometry.x,(double)
2047             geometry.y);
2048           flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2049             &exception);
2050           if (rotate_image == (Image *) NULL)
2051             CompositeImageChannel(image,channel,compose,composite_image,
2052               geometry.x,geometry.y);
2053           else
2054             {
2055               /*
2056                 Rotate image.
2057               */
2058               geometry.x-=(ssize_t) (rotate_image->columns-
2059                 composite_image->columns)/2;
2060               geometry.y-=(ssize_t) (rotate_image->rows-composite_image->rows)/2;
2061               CompositeImageChannel(image,channel,compose,rotate_image,
2062                 geometry.x,geometry.y);
2063               rotate_image=DestroyImage(rotate_image);
2064             }
2065           composite_image=DestroyImage(composite_image);
2066           break;
2067         }
2068       if (LocaleCompare((const char *) tag,"contrast") == 0)
2069         {
2070           MagickBooleanType
2071             sharpen;
2072
2073           /*
2074             Contrast image.
2075           */
2076           if (msl_info->image[n] == (Image *) NULL)
2077             {
2078               ThrowMSLException(OptionError,"NoImagesDefined",
2079                 (const char *) tag);
2080               break;
2081             }
2082           sharpen=MagickFalse;
2083           if (attributes != (const xmlChar **) NULL)
2084             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2085             {
2086               keyword=(const char *) attributes[i++];
2087               attribute=InterpretImageProperties(msl_info->image_info[n],
2088                 msl_info->attributes[n],(const char *) attributes[i]);
2089               CloneString(&value,attribute);
2090               switch (*keyword)
2091               {
2092                 case 'S':
2093                 case 's':
2094                 {
2095                   if (LocaleCompare(keyword,"sharpen") == 0)
2096                     {
2097                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2098                         value);
2099                       if (option < 0)
2100                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2101                           value);
2102                       sharpen=(MagickBooleanType) option;
2103                       break;
2104                     }
2105                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2106                     keyword);
2107                   break;
2108                 }
2109                 default:
2110                 {
2111                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2112                     keyword);
2113                   break;
2114                 }
2115               }
2116             }
2117           (void) ContrastImage(msl_info->image[n],sharpen);
2118           break;
2119         }
2120       if (LocaleCompare((const char *) tag,"crop") == 0)
2121         {
2122           Image
2123             *crop_image;
2124
2125           /*
2126             Crop image.
2127           */
2128           if (msl_info->image[n] == (Image *) NULL)
2129             {
2130               ThrowMSLException(OptionError,"NoImagesDefined",
2131                 (const char *) tag);
2132               break;
2133             }
2134           SetGeometry(msl_info->image[n],&geometry);
2135           if (attributes != (const xmlChar **) NULL)
2136             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2137             {
2138               keyword=(const char *) attributes[i++];
2139               attribute=InterpretImageProperties(msl_info->image_info[n],
2140                 msl_info->attributes[n],(const char *) attributes[i]);
2141               CloneString(&value,attribute);
2142               switch (*keyword)
2143               {
2144                 case 'G':
2145                 case 'g':
2146                 {
2147                   if (LocaleCompare(keyword,"geometry") == 0)
2148                     {
2149                       flags=ParsePageGeometry(msl_info->image[n],value,
2150                         &geometry,&exception);
2151                       if ((flags & HeightValue) == 0)
2152                         geometry.height=geometry.width;
2153                       break;
2154                     }
2155                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2156                     keyword);
2157                   break;
2158                 }
2159                 case 'H':
2160                 case 'h':
2161                 {
2162                   if (LocaleCompare(keyword,"height") == 0)
2163                     {
2164                       geometry.height=StringToLong(value);
2165                       break;
2166                     }
2167                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2168                     keyword);
2169                   break;
2170                 }
2171                 case 'W':
2172                 case 'w':
2173                 {
2174                   if (LocaleCompare(keyword,"width") == 0)
2175                     {
2176                       geometry.width=StringToLong(value);
2177                       break;
2178                     }
2179                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2180                     keyword);
2181                   break;
2182                 }
2183                 case 'X':
2184                 case 'x':
2185                 {
2186                   if (LocaleCompare(keyword,"x") == 0)
2187                     {
2188                       geometry.x=StringToLong(value);
2189                       break;
2190                     }
2191                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2192                     keyword);
2193                   break;
2194                 }
2195                 case 'Y':
2196                 case 'y':
2197                 {
2198                   if (LocaleCompare(keyword,"y") == 0)
2199                     {
2200                       geometry.y=StringToLong(value);
2201                       break;
2202                     }
2203                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2204                     keyword);
2205                   break;
2206                 }
2207                 default:
2208                 {
2209                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2210                     keyword);
2211                   break;
2212                 }
2213               }
2214             }
2215           crop_image=CropImage(msl_info->image[n],&geometry,
2216             &msl_info->image[n]->exception);
2217           if (crop_image == (Image *) NULL)
2218             break;
2219           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2220           msl_info->image[n]=crop_image;
2221           break;
2222         }
2223       if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
2224         {
2225           ssize_t
2226             display;
2227
2228           /*
2229             Cycle-colormap image.
2230           */
2231           if (msl_info->image[n] == (Image *) NULL)
2232             {
2233               ThrowMSLException(OptionError,"NoImagesDefined",
2234                 (const char *) tag);
2235               break;
2236             }
2237           display=0;
2238           if (attributes != (const xmlChar **) NULL)
2239             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2240             {
2241               keyword=(const char *) attributes[i++];
2242               attribute=InterpretImageProperties(msl_info->image_info[n],
2243                 msl_info->attributes[n],(const char *) attributes[i]);
2244               CloneString(&value,attribute);
2245               switch (*keyword)
2246               {
2247                 case 'D':
2248                 case 'd':
2249                 {
2250                   if (LocaleCompare(keyword,"display") == 0)
2251                     {
2252                       display=StringToLong(value);
2253                       break;
2254                     }
2255                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2256                     keyword);
2257                   break;
2258                 }
2259                 default:
2260                 {
2261                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2262                     keyword);
2263                   break;
2264                 }
2265               }
2266             }
2267           (void) CycleColormapImage(msl_info->image[n],display);
2268           break;
2269         }
2270       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2271     }
2272     case 'D':
2273     case 'd':
2274     {
2275       if (LocaleCompare((const char *) tag,"despeckle") == 0)
2276         {
2277           Image
2278             *despeckle_image;
2279
2280           /*
2281             Despeckle image.
2282           */
2283           if (msl_info->image[n] == (Image *) NULL)
2284             {
2285               ThrowMSLException(OptionError,"NoImagesDefined",
2286                 (const char *) tag);
2287               break;
2288             }
2289           if (attributes != (const xmlChar **) NULL)
2290             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2291             {
2292               keyword=(const char *) attributes[i++];
2293               attribute=InterpretImageProperties(msl_info->image_info[n],
2294                 msl_info->attributes[n],(const char *) attributes[i]);
2295               CloneString(&value,attribute);
2296               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2297             }
2298           despeckle_image=DespeckleImage(msl_info->image[n],
2299             &msl_info->image[n]->exception);
2300           if (despeckle_image == (Image *) NULL)
2301             break;
2302           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2303           msl_info->image[n]=despeckle_image;
2304           break;
2305         }
2306       if (LocaleCompare((const char *) tag,"display") == 0)
2307         {
2308           if (msl_info->image[n] == (Image *) NULL)
2309             {
2310               ThrowMSLException(OptionError,"NoImagesDefined",
2311                 (const char *) tag);
2312               break;
2313             }
2314           if (attributes != (const xmlChar **) NULL)
2315             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2316             {
2317               keyword=(const char *) attributes[i++];
2318               attribute=InterpretImageProperties(msl_info->image_info[n],
2319                 msl_info->attributes[n],(const char *) attributes[i]);
2320               CloneString(&value,attribute);
2321               switch (*keyword)
2322               {
2323                 default:
2324                 {
2325                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2326                     keyword);
2327                   break;
2328                 }
2329               }
2330             }
2331           (void) DisplayImages(msl_info->image_info[n],msl_info->image[n]);
2332           break;
2333         }
2334       if (LocaleCompare((const char *) tag,"draw") == 0)
2335         {
2336           char
2337             text[MaxTextExtent];
2338
2339           /*
2340             Annotate image.
2341           */
2342           if (msl_info->image[n] == (Image *) NULL)
2343             {
2344               ThrowMSLException(OptionError,"NoImagesDefined",
2345                 (const char *) tag);
2346               break;
2347             }
2348           draw_info=CloneDrawInfo(msl_info->image_info[n],
2349             msl_info->draw_info[n]);
2350           angle=0.0;
2351           current=draw_info->affine;
2352           GetAffineMatrix(&affine);
2353           if (attributes != (const xmlChar **) NULL)
2354             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2355             {
2356               keyword=(const char *) attributes[i++];
2357               attribute=InterpretImageProperties(msl_info->image_info[n],
2358                 msl_info->attributes[n],(const char *) attributes[i]);
2359               CloneString(&value,attribute);
2360               switch (*keyword)
2361               {
2362                 case 'A':
2363                 case 'a':
2364                 {
2365                   if (LocaleCompare(keyword,"affine") == 0)
2366                     {
2367                       char
2368                         *p;
2369
2370                       p=value;
2371                       draw_info->affine.sx=strtod(p,&p);
2372                       if (*p ==',')
2373                         p++;
2374                       draw_info->affine.rx=strtod(p,&p);
2375                       if (*p ==',')
2376                         p++;
2377                       draw_info->affine.ry=strtod(p,&p);
2378                       if (*p ==',')
2379                         p++;
2380                       draw_info->affine.sy=strtod(p,&p);
2381                       if (*p ==',')
2382                         p++;
2383                       draw_info->affine.tx=strtod(p,&p);
2384                       if (*p ==',')
2385                         p++;
2386                       draw_info->affine.ty=strtod(p,&p);
2387                       break;
2388                     }
2389                   if (LocaleCompare(keyword,"align") == 0)
2390                     {
2391                       option=ParseMagickOption(MagickAlignOptions,MagickFalse,
2392                         value);
2393                       if (option < 0)
2394                         ThrowMSLException(OptionError,"UnrecognizedAlignType",
2395                           value);
2396                       draw_info->align=(AlignType) option;
2397                       break;
2398                     }
2399                   if (LocaleCompare(keyword,"antialias") == 0)
2400                     {
2401                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2402                         value);
2403                       if (option < 0)
2404                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2405                           value);
2406                       draw_info->stroke_antialias=(MagickBooleanType) option;
2407                       draw_info->text_antialias=(MagickBooleanType) option;
2408                       break;
2409                     }
2410                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2411                     keyword);
2412                   break;
2413                 }
2414                 case 'D':
2415                 case 'd':
2416                 {
2417                   if (LocaleCompare(keyword,"density") == 0)
2418                     {
2419                       CloneString(&draw_info->density,value);
2420                       break;
2421                     }
2422                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2423                     keyword);
2424                   break;
2425                 }
2426                 case 'E':
2427                 case 'e':
2428                 {
2429                   if (LocaleCompare(keyword,"encoding") == 0)
2430                     {
2431                       CloneString(&draw_info->encoding,value);
2432                       break;
2433                     }
2434                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2435                     keyword);
2436                   break;
2437                 }
2438                 case 'F':
2439                 case 'f':
2440                 {
2441                   if (LocaleCompare(keyword, "fill") == 0)
2442                     {
2443                       (void) QueryColorDatabase(value,&draw_info->fill,
2444                         &exception);
2445                       break;
2446                     }
2447                   if (LocaleCompare(keyword,"family") == 0)
2448                     {
2449                       CloneString(&draw_info->family,value);
2450                       break;
2451                     }
2452                   if (LocaleCompare(keyword,"font") == 0)
2453                     {
2454                       CloneString(&draw_info->font,value);
2455                       break;
2456                     }
2457                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2458                     keyword);
2459                   break;
2460                 }
2461                 case 'G':
2462                 case 'g':
2463                 {
2464                   if (LocaleCompare(keyword,"geometry") == 0)
2465                     {
2466                       flags=ParsePageGeometry(msl_info->image[n],value,
2467                         &geometry,&exception);
2468                       if ((flags & HeightValue) == 0)
2469                         geometry.height=geometry.width;
2470                       break;
2471                     }
2472                   if (LocaleCompare(keyword,"gravity") == 0)
2473                     {
2474                       option=ParseMagickOption(MagickGravityOptions,MagickFalse,
2475                         value);
2476                       if (option < 0)
2477                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
2478                           value);
2479                       draw_info->gravity=(GravityType) option;
2480                       break;
2481                     }
2482                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2483                     keyword);
2484                   break;
2485                 }
2486                 case 'P':
2487                 case 'p':
2488                 {
2489                   if (LocaleCompare(keyword,"primitive") == 0)
2490                     {
2491                       CloneString(&draw_info->primitive,value);
2492                       break;
2493                     }
2494                   if (LocaleCompare(keyword,"pointsize") == 0)
2495                     {
2496                       draw_info->pointsize=StringToDouble(value);
2497                       break;
2498                     }
2499                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2500                     keyword);
2501                   break;
2502                 }
2503                 case 'R':
2504                 case 'r':
2505                 {
2506                   if (LocaleCompare(keyword,"rotate") == 0)
2507                     {
2508                       angle=StringToDouble(value);
2509                       affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2510                       affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2511                       affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2512                       affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2513                       break;
2514                     }
2515                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2516                     keyword);
2517                   break;
2518                 }
2519                 case 'S':
2520                 case 's':
2521                 {
2522                   if (LocaleCompare(keyword,"scale") == 0)
2523                     {
2524                       flags=ParseGeometry(value,&geometry_info);
2525                       if ((flags & SigmaValue) == 0)
2526                         geometry_info.sigma=1.0;
2527                       affine.sx=geometry_info.rho;
2528                       affine.sy=geometry_info.sigma;
2529                       break;
2530                     }
2531                   if (LocaleCompare(keyword,"skewX") == 0)
2532                     {
2533                       angle=StringToDouble(value);
2534                       affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2535                       break;
2536                     }
2537                   if (LocaleCompare(keyword,"skewY") == 0)
2538                     {
2539                       angle=StringToDouble(value);
2540                       affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2541                       break;
2542                     }
2543                   if (LocaleCompare(keyword,"stretch") == 0)
2544                     {
2545                       option=ParseMagickOption(MagickStretchOptions,MagickFalse,
2546                         value);
2547                       if (option < 0)
2548                         ThrowMSLException(OptionError,"UnrecognizedStretchType",
2549                           value);
2550                       draw_info->stretch=(StretchType) option;
2551                       break;
2552                     }
2553                   if (LocaleCompare(keyword, "stroke") == 0)
2554                     {
2555                       (void) QueryColorDatabase(value,&draw_info->stroke,
2556                         &exception);
2557                       break;
2558                     }
2559                   if (LocaleCompare(keyword,"strokewidth") == 0)
2560                     {
2561                       draw_info->stroke_width=StringToLong(value);
2562                       break;
2563                     }
2564                   if (LocaleCompare(keyword,"style") == 0)
2565                     {
2566                       option=ParseMagickOption(MagickStyleOptions,MagickFalse,
2567                         value);
2568                       if (option < 0)
2569                         ThrowMSLException(OptionError,"UnrecognizedStyleType",
2570                           value);
2571                       draw_info->style=(StyleType) option;
2572                       break;
2573                     }
2574                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2575                     keyword);
2576                   break;
2577                 }
2578                 case 'T':
2579                 case 't':
2580                 {
2581                   if (LocaleCompare(keyword,"text") == 0)
2582                     {
2583                       CloneString(&draw_info->text,value);
2584                       break;
2585                     }
2586                   if (LocaleCompare(keyword,"translate") == 0)
2587                     {
2588                       flags=ParseGeometry(value,&geometry_info);
2589                       if ((flags & SigmaValue) == 0)
2590                         geometry_info.sigma=1.0;
2591                       affine.tx=geometry_info.rho;
2592                       affine.ty=geometry_info.sigma;
2593                       break;
2594                     }
2595                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2596                     keyword);
2597                   break;
2598                 }
2599                 case 'U':
2600                 case 'u':
2601                 {
2602                   if (LocaleCompare(keyword, "undercolor") == 0)
2603                     {
2604                       (void) QueryColorDatabase(value,&draw_info->undercolor,
2605                         &exception);
2606                       break;
2607                     }
2608                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2609                     keyword);
2610                   break;
2611                 }
2612                 case 'W':
2613                 case 'w':
2614                 {
2615                   if (LocaleCompare(keyword,"weight") == 0)
2616                     {
2617                       draw_info->weight=StringToLong(value);
2618                       break;
2619                     }
2620                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2621                     keyword);
2622                   break;
2623                 }
2624                 case 'X':
2625                 case 'x':
2626                 {
2627                   if (LocaleCompare(keyword,"x") == 0)
2628                     {
2629                       geometry.x=StringToLong(value);
2630                       break;
2631                     }
2632                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2633                     keyword);
2634                   break;
2635                 }
2636                 case 'Y':
2637                 case 'y':
2638                 {
2639                   if (LocaleCompare(keyword,"y") == 0)
2640                     {
2641                       geometry.y=StringToLong(value);
2642                       break;
2643                     }
2644                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2645                     keyword);
2646                   break;
2647                 }
2648                 default:
2649                 {
2650                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2651                     keyword);
2652                   break;
2653                 }
2654               }
2655             }
2656           (void) FormatMagickString(text,MaxTextExtent,
2657             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2658             geometry.height,(double) geometry.x,(double) geometry.y);
2659           CloneString(&draw_info->geometry,text);
2660           draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2661           draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2662           draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2663           draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2664           draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2665             affine.tx;
2666           draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2667             affine.ty;
2668           (void) DrawImage(msl_info->image[n],draw_info);
2669           draw_info=DestroyDrawInfo(draw_info);
2670           break;
2671         }
2672       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2673     }
2674     case 'E':
2675     case 'e':
2676     {
2677       if (LocaleCompare((const char *) tag,"edge") == 0)
2678         {
2679           Image
2680             *edge_image;
2681
2682           /*
2683             Edge image.
2684           */
2685           if (msl_info->image[n] == (Image *) NULL)
2686             {
2687               ThrowMSLException(OptionError,"NoImagesDefined",
2688                 (const char *) tag);
2689               break;
2690             }
2691           if (attributes != (const xmlChar **) NULL)
2692             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2693             {
2694               keyword=(const char *) attributes[i++];
2695               attribute=InterpretImageProperties(msl_info->image_info[n],
2696                 msl_info->attributes[n],(const char *) attributes[i]);
2697               CloneString(&value,attribute);
2698               switch (*keyword)
2699               {
2700                 case 'G':
2701                 case 'g':
2702                 {
2703                   if (LocaleCompare(keyword,"geometry") == 0)
2704                     {
2705                       flags=ParseGeometry(value,&geometry_info);
2706                       if ((flags & SigmaValue) == 0)
2707                         geometry_info.sigma=1.0;
2708                       break;
2709                     }
2710                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2711                     keyword);
2712                   break;
2713                 }
2714                 case 'R':
2715                 case 'r':
2716                 {
2717                   if (LocaleCompare(keyword,"radius") == 0)
2718                     {
2719                       geometry_info.rho=StringToDouble(value);
2720                       break;
2721                     }
2722                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2723                     keyword);
2724                   break;
2725                 }
2726                 default:
2727                 {
2728                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2729                     keyword);
2730                   break;
2731                 }
2732               }
2733             }
2734           edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
2735             &msl_info->image[n]->exception);
2736           if (edge_image == (Image *) NULL)
2737             break;
2738           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2739           msl_info->image[n]=edge_image;
2740           break;
2741         }
2742       if (LocaleCompare((const char *) tag,"emboss") == 0)
2743         {
2744           Image
2745             *emboss_image;
2746
2747           /*
2748             Emboss image.
2749           */
2750           if (msl_info->image[n] == (Image *) NULL)
2751             {
2752               ThrowMSLException(OptionError,"NoImagesDefined",
2753                 (const char *) tag);
2754               break;
2755             }
2756           if (attributes != (const xmlChar **) NULL)
2757             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2758             {
2759               keyword=(const char *) attributes[i++];
2760               attribute=InterpretImageProperties(msl_info->image_info[n],
2761                 msl_info->attributes[n],(const char *) attributes[i]);
2762               CloneString(&value,attribute);
2763               switch (*keyword)
2764               {
2765                 case 'G':
2766                 case 'g':
2767                 {
2768                   if (LocaleCompare(keyword,"geometry") == 0)
2769                     {
2770                       flags=ParseGeometry(value,&geometry_info);
2771                       if ((flags & SigmaValue) == 0)
2772                         geometry_info.sigma=1.0;
2773                       break;
2774                     }
2775                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2776                     keyword);
2777                   break;
2778                 }
2779                 case 'R':
2780                 case 'r':
2781                 {
2782                   if (LocaleCompare(keyword,"radius") == 0)
2783                     {
2784                       geometry_info.rho=StringToDouble(value);
2785                       break;
2786                     }
2787                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2788                     keyword);
2789                   break;
2790                 }
2791                 case 'S':
2792                 case 's':
2793                 {
2794                   if (LocaleCompare(keyword,"sigma") == 0)
2795                     {
2796                       geometry_info.sigma=StringToLong(value);
2797                       break;
2798                     }
2799                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2800                     keyword);
2801                   break;
2802                 }
2803                 default:
2804                 {
2805                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2806                     keyword);
2807                   break;
2808                 }
2809               }
2810             }
2811           emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2812             geometry_info.sigma,&msl_info->image[n]->exception);
2813           if (emboss_image == (Image *) NULL)
2814             break;
2815           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2816           msl_info->image[n]=emboss_image;
2817           break;
2818         }
2819       if (LocaleCompare((const char *) tag,"enhance") == 0)
2820         {
2821           Image
2822             *enhance_image;
2823
2824           /*
2825             Enhance image.
2826           */
2827           if (msl_info->image[n] == (Image *) NULL)
2828             {
2829               ThrowMSLException(OptionError,"NoImagesDefined",
2830                 (const char *) tag);
2831               break;
2832             }
2833           if (attributes != (const xmlChar **) NULL)
2834             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2835             {
2836               keyword=(const char *) attributes[i++];
2837               attribute=InterpretImageProperties(msl_info->image_info[n],
2838                 msl_info->attributes[n],(const char *) attributes[i]);
2839               CloneString(&value,attribute);
2840               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2841             }
2842           enhance_image=EnhanceImage(msl_info->image[n],
2843             &msl_info->image[n]->exception);
2844           if (enhance_image == (Image *) NULL)
2845             break;
2846           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2847           msl_info->image[n]=enhance_image;
2848           break;
2849         }
2850       if (LocaleCompare((const char *) tag,"equalize") == 0)
2851         {
2852           /*
2853             Equalize image.
2854           */
2855           if (msl_info->image[n] == (Image *) NULL)
2856             {
2857               ThrowMSLException(OptionError,"NoImagesDefined",
2858                 (const char *) tag);
2859               break;
2860             }
2861           if (attributes != (const xmlChar **) NULL)
2862             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2863             {
2864               keyword=(const char *) attributes[i++];
2865               attribute=InterpretImageProperties(msl_info->image_info[n],
2866                 msl_info->attributes[n],(const char *) attributes[i]);
2867               CloneString(&value,attribute);
2868               switch (*keyword)
2869               {
2870                 default:
2871                 {
2872                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2873                     keyword);
2874                   break;
2875                 }
2876               }
2877             }
2878           (void) EqualizeImage(msl_info->image[n]);
2879           break;
2880         }
2881       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2882     }
2883     case 'F':
2884     case 'f':
2885     {
2886       if (LocaleCompare((const char *) tag, "flatten") == 0)
2887       {
2888         if (msl_info->image[n] == (Image *) NULL)
2889         {
2890           ThrowMSLException(OptionError,"NoImagesDefined",
2891             (const char *) tag);
2892           break;
2893         }
2894
2895         /* no attributes here */
2896
2897         /* process the image */
2898         {
2899           Image
2900             *newImage;
2901
2902           newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2903             &msl_info->image[n]->exception);
2904           if (newImage == (Image *) NULL)
2905             break;
2906           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2907           msl_info->image[n]=newImage;
2908           break;
2909         }
2910       }
2911       if (LocaleCompare((const char *) tag,"flip") == 0)
2912         {
2913           Image
2914             *flip_image;
2915
2916           /*
2917             Flip image.
2918           */
2919           if (msl_info->image[n] == (Image *) NULL)
2920             {
2921               ThrowMSLException(OptionError,"NoImagesDefined",
2922                 (const char *) tag);
2923               break;
2924             }
2925           if (attributes != (const xmlChar **) NULL)
2926             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2927             {
2928               keyword=(const char *) attributes[i++];
2929               attribute=InterpretImageProperties(msl_info->image_info[n],
2930                 msl_info->attributes[n],(const char *) attributes[i]);
2931               CloneString(&value,attribute);
2932               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2933             }
2934           flip_image=FlipImage(msl_info->image[n],
2935             &msl_info->image[n]->exception);
2936           if (flip_image == (Image *) NULL)
2937             break;
2938           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2939           msl_info->image[n]=flip_image;
2940           break;
2941         }
2942       if (LocaleCompare((const char *) tag,"flop") == 0)
2943         {
2944           Image
2945             *flop_image;
2946
2947           /*
2948             Flop image.
2949           */
2950           if (msl_info->image[n] == (Image *) NULL)
2951             {
2952               ThrowMSLException(OptionError,"NoImagesDefined",
2953                 (const char *) tag);
2954               break;
2955             }
2956           if (attributes != (const xmlChar **) NULL)
2957             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2958             {
2959               keyword=(const char *) attributes[i++];
2960               attribute=InterpretImageProperties(msl_info->image_info[n],
2961                 msl_info->attributes[n],(const char *) attributes[i]);
2962               CloneString(&value,attribute);
2963               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2964             }
2965           flop_image=FlopImage(msl_info->image[n],
2966             &msl_info->image[n]->exception);
2967           if (flop_image == (Image *) NULL)
2968             break;
2969           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2970           msl_info->image[n]=flop_image;
2971           break;
2972         }
2973       if (LocaleCompare((const char *) tag,"frame") == 0)
2974         {
2975           FrameInfo
2976             frame_info;
2977
2978           Image
2979             *frame_image;
2980
2981           /*
2982             Frame image.
2983           */
2984           if (msl_info->image[n] == (Image *) NULL)
2985             {
2986               ThrowMSLException(OptionError,"NoImagesDefined",
2987                 (const char *) tag);
2988               break;
2989             }
2990           SetGeometry(msl_info->image[n],&geometry);
2991           if (attributes != (const xmlChar **) NULL)
2992             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2993             {
2994               keyword=(const char *) attributes[i++];
2995               attribute=InterpretImageProperties(msl_info->image_info[n],
2996                 msl_info->attributes[n],(const char *) attributes[i]);
2997               CloneString(&value,attribute);
2998               switch (*keyword)
2999               {
3000                 case 'C':
3001                 case 'c':
3002                 {
3003                   if (LocaleCompare(keyword,"compose") == 0)
3004                     {
3005                       option=ParseMagickOption(MagickComposeOptions,
3006                         MagickFalse,value);
3007                       if (option < 0)
3008                         ThrowMSLException(OptionError,"UnrecognizedComposeType",
3009                           value);
3010                       msl_info->image[n]->compose=(CompositeOperator) option;
3011                       break;
3012                     }
3013                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3014                     keyword);
3015                   break;
3016                 }
3017                 case 'F':
3018                 case 'f':
3019                 {
3020                   if (LocaleCompare(keyword, "fill") == 0)
3021                     {
3022                       (void) QueryColorDatabase(value,
3023                         &msl_info->image[n]->matte_color,&exception);
3024                       break;
3025                     }
3026                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3027                     keyword);
3028                   break;
3029                 }
3030                 case 'G':
3031                 case 'g':
3032                 {
3033                   if (LocaleCompare(keyword,"geometry") == 0)
3034                     {
3035                       flags=ParsePageGeometry(msl_info->image[n],value,
3036                         &geometry,&exception);
3037                       if ((flags & HeightValue) == 0)
3038                         geometry.height=geometry.width;
3039                       frame_info.width=geometry.width;
3040                       frame_info.height=geometry.height;
3041                       frame_info.outer_bevel=geometry.x;
3042                       frame_info.inner_bevel=geometry.y;
3043                       break;
3044                     }
3045                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3046                     keyword);
3047                   break;
3048                 }
3049                 case 'H':
3050                 case 'h':
3051                 {
3052                   if (LocaleCompare(keyword,"height") == 0)
3053                     {
3054                       frame_info.height=StringToLong(value);
3055                       break;
3056                     }
3057                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3058                     keyword);
3059                   break;
3060                 }
3061                 case 'I':
3062                 case 'i':
3063                 {
3064                   if (LocaleCompare(keyword,"inner") == 0)
3065                     {
3066                       frame_info.inner_bevel=StringToLong(value);
3067                       break;
3068                     }
3069                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3070                     keyword);
3071                   break;
3072                 }
3073                 case 'O':
3074                 case 'o':
3075                 {
3076                   if (LocaleCompare(keyword,"outer") == 0)
3077                     {
3078                       frame_info.outer_bevel=StringToLong(value);
3079                       break;
3080                     }
3081                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3082                     keyword);
3083                   break;
3084                 }
3085                 case 'W':
3086                 case 'w':
3087                 {
3088                   if (LocaleCompare(keyword,"width") == 0)
3089                     {
3090                       frame_info.width=StringToLong(value);
3091                       break;
3092                     }
3093                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3094                     keyword);
3095                   break;
3096                 }
3097                 default:
3098                 {
3099                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3100                     keyword);
3101                   break;
3102                 }
3103               }
3104             }
3105           frame_info.x=(ssize_t) frame_info.width;
3106           frame_info.y=(ssize_t) frame_info.height;
3107           frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3108           frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3109           frame_image=FrameImage(msl_info->image[n],&frame_info,
3110             &msl_info->image[n]->exception);
3111           if (frame_image == (Image *) NULL)
3112             break;
3113           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3114           msl_info->image[n]=frame_image;
3115           break;
3116         }
3117       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3118     }
3119     case 'G':
3120     case 'g':
3121     {
3122       if (LocaleCompare((const char *) tag,"gamma") == 0)
3123         {
3124           char
3125             gamma[MaxTextExtent];
3126
3127           MagickPixelPacket
3128             pixel;
3129
3130           /*
3131             Gamma image.
3132           */
3133           if (msl_info->image[n] == (Image *) NULL)
3134             {
3135               ThrowMSLException(OptionError,"NoImagesDefined",
3136                 (const char *) tag);
3137               break;
3138             }
3139           channel=UndefinedChannel;
3140           pixel.red=0.0;
3141           pixel.green=0.0;
3142           pixel.blue=0.0;
3143           *gamma='\0';
3144           if (attributes != (const xmlChar **) NULL)
3145             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3146             {
3147               keyword=(const char *) attributes[i++];
3148               attribute=InterpretImageProperties(msl_info->image_info[n],
3149                 msl_info->attributes[n],(const char *) attributes[i]);
3150               CloneString(&value,attribute);
3151               switch (*keyword)
3152               {
3153                 case 'B':
3154                 case 'b':
3155                 {
3156                   if (LocaleCompare(keyword,"blue") == 0)
3157                     {
3158                       pixel.blue=StringToDouble(value);
3159                       break;
3160                     }
3161                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3162                     keyword);
3163                   break;
3164                 }
3165                 case 'C':
3166                 case 'c':
3167                 {
3168                   if (LocaleCompare(keyword,"channel") == 0)
3169                     {
3170                       option=ParseChannelOption(value);
3171                       if (option < 0)
3172                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
3173                           value);
3174                       channel=(ChannelType) option;
3175                       break;
3176                     }
3177                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3178                     keyword);
3179                   break;
3180                 }
3181                 case 'G':
3182                 case 'g':
3183                 {
3184                   if (LocaleCompare(keyword,"gamma") == 0)
3185                     {
3186                       (void) CopyMagickString(gamma,value,MaxTextExtent);
3187                       break;
3188                     }
3189                   if (LocaleCompare(keyword,"green") == 0)
3190                     {
3191                       pixel.green=StringToDouble(value);
3192                       break;
3193                     }
3194                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3195                     keyword);
3196                   break;
3197                 }
3198                 case 'R':
3199                 case 'r':
3200                 {
3201                   if (LocaleCompare(keyword,"red") == 0)
3202                     {
3203                       pixel.red=StringToDouble(value);
3204                       break;
3205                     }
3206                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3207                     keyword);
3208                   break;
3209                 }
3210                 default:
3211                 {
3212                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3213                     keyword);
3214                   break;
3215                 }
3216               }
3217             }
3218           if (*gamma == '\0')
3219             (void) FormatMagickString(gamma,MaxTextExtent,"%g,%g,%g",
3220               (double) pixel.red,(double) pixel.green,(double) pixel.blue);
3221           switch (channel)
3222           {
3223             default:
3224             {
3225               (void) GammaImage(msl_info->image[n],gamma);
3226               break;
3227             }
3228             case RedChannel:
3229             {
3230               (void) GammaImageChannel(msl_info->image[n],RedChannel,pixel.red);
3231               break;
3232             }
3233             case GreenChannel:
3234             {
3235               (void) GammaImageChannel(msl_info->image[n],GreenChannel,
3236                 pixel.green);
3237               break;
3238             }
3239             case BlueChannel:
3240             {
3241               (void) GammaImageChannel(msl_info->image[n],BlueChannel,
3242                 pixel.blue);
3243               break;
3244             }
3245           }
3246           break;
3247         }
3248       else if (LocaleCompare((const char *) tag,"get") == 0)
3249         {
3250           if (msl_info->image[n] == (Image *) NULL)
3251             {
3252               ThrowMSLException(OptionError,"NoImagesDefined",
3253                 (const char *) tag);
3254               break;
3255             }
3256           if (attributes == (const xmlChar **) NULL)
3257             break;
3258           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3259           {
3260             keyword=(const char *) attributes[i++];
3261             CloneString(&value,(const char *) attributes[i]);
3262             (void) CopyMagickString(key,value,MaxTextExtent);
3263             switch (*keyword)
3264             {
3265               case 'H':
3266               case 'h':
3267               {
3268                 if (LocaleCompare(keyword,"height") == 0)
3269                   {
3270                     (void) FormatMagickString(value,MaxTextExtent,"%.20g",
3271                       (double) msl_info->image[n]->rows);
3272                     (void) SetImageProperty(msl_info->attributes[n],key,value);
3273                     break;
3274                   }
3275                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3276               }
3277               case 'W':
3278               case 'w':
3279               {
3280                 if (LocaleCompare(keyword,"width") == 0)
3281                   {
3282                     (void) FormatMagickString(value,MaxTextExtent,"%.20g",
3283                       (double) msl_info->image[n]->columns);
3284                     (void) SetImageProperty(msl_info->attributes[n],key,value);
3285                     break;
3286                   }
3287                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3288               }
3289               default:
3290               {
3291                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3292                 break;
3293               }
3294             }
3295           }
3296           break;
3297         }
3298     else if (LocaleCompare((const char *) tag, "group") == 0)
3299     {
3300       msl_info->number_groups++;
3301       msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3302         msl_info->group_info,msl_info->number_groups+1UL,
3303         sizeof(*msl_info->group_info));
3304       break;
3305     }
3306       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3307     }
3308     case 'I':
3309     case 'i':
3310     {
3311       if (LocaleCompare((const char *) tag,"image") == 0)
3312         {
3313           MSLPushImage(msl_info,(Image *) NULL);
3314           if (attributes == (const xmlChar **) NULL)
3315             break;
3316           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3317           {
3318             keyword=(const char *) attributes[i++];
3319             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
3320               msl_info->attributes[n],(const char *) attributes[i]));
3321             switch (*keyword)
3322             {
3323               case 'C':
3324               case 'c':
3325               {
3326                 if (LocaleCompare(keyword,"color") == 0)
3327                   {
3328                     Image
3329                       *next_image;
3330
3331                     (void) CopyMagickString(msl_info->image_info[n]->filename,
3332                       "xc:",MaxTextExtent);
3333                     (void) ConcatenateMagickString(msl_info->image_info[n]->
3334                       filename,value,MaxTextExtent);
3335                     next_image=ReadImage(msl_info->image_info[n],&exception);
3336                     CatchException(&exception);
3337                     if (next_image == (Image *) NULL)
3338                       continue;
3339                     if (msl_info->image[n] == (Image *) NULL)
3340                       msl_info->image[n]=next_image;
3341                     else
3342                       {
3343                         register Image
3344                           *p;
3345
3346                         /*
3347                           Link image into image list.
3348                         */
3349                         p=msl_info->image[n];
3350                         while (p->next != (Image *) NULL)
3351                           p=GetNextImageInList(p);
3352                         next_image->previous=p;
3353                         p->next=next_image;
3354                       }
3355                     break;
3356                   }
3357                 (void) SetMSLAttributes(msl_info,keyword,value);
3358                 break;
3359               }
3360               default:
3361               {
3362                 (void) SetMSLAttributes(msl_info,keyword,value);
3363                 break;
3364               }
3365             }
3366           }
3367           break;
3368         }
3369       if (LocaleCompare((const char *) tag,"implode") == 0)
3370         {
3371           Image
3372             *implode_image;
3373
3374           /*
3375             Implode image.
3376           */
3377           if (msl_info->image[n] == (Image *) NULL)
3378             {
3379               ThrowMSLException(OptionError,"NoImagesDefined",
3380                 (const char *) tag);
3381               break;
3382             }
3383           if (attributes != (const xmlChar **) NULL)
3384             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3385             {
3386               keyword=(const char *) attributes[i++];
3387               attribute=InterpretImageProperties(msl_info->image_info[n],
3388                 msl_info->attributes[n],(const char *) attributes[i]);
3389               CloneString(&value,attribute);
3390               switch (*keyword)
3391               {
3392                 case 'A':
3393                 case 'a':
3394                 {
3395                   if (LocaleCompare(keyword,"amount") == 0)
3396                     {
3397                       geometry_info.rho=StringToDouble(value);
3398                       break;
3399                     }
3400                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3401                     keyword);
3402                   break;
3403                 }
3404                 case 'G':
3405                 case 'g':
3406                 {
3407                   if (LocaleCompare(keyword,"geometry") == 0)
3408                     {
3409                       flags=ParseGeometry(value,&geometry_info);
3410                       if ((flags & SigmaValue) == 0)
3411                         geometry_info.sigma=1.0;
3412                       break;
3413                     }
3414                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3415                     keyword);
3416                   break;
3417                 }
3418                 default:
3419                 {
3420                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3421                     keyword);
3422                   break;
3423                 }
3424               }
3425             }
3426           implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3427             &msl_info->image[n]->exception);
3428           if (implode_image == (Image *) NULL)
3429             break;
3430           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3431           msl_info->image[n]=implode_image;
3432           break;
3433         }
3434       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3435     }
3436     case 'L':
3437     case 'l':
3438     {
3439       if (LocaleCompare((const char *) tag,"label") == 0)
3440         break;
3441       if (LocaleCompare((const char *) tag, "level") == 0)
3442       {
3443         double
3444           levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3445
3446         if (msl_info->image[n] == (Image *) NULL)
3447         {
3448           ThrowMSLException(OptionError,"NoImagesDefined",
3449             (const char *) tag);
3450           break;
3451         }
3452         if (attributes == (const xmlChar **) NULL)
3453           break;
3454         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3455         {
3456           keyword=(const char *) attributes[i++];
3457           CloneString(&value,(const char *) attributes[i]);
3458           (void) CopyMagickString(key,value,MaxTextExtent);
3459           switch (*keyword)
3460           {
3461             case 'B':
3462             case 'b':
3463             {
3464               if (LocaleCompare(keyword,"black") == 0)
3465               {
3466                 levelBlack = StringToDouble( value );
3467                 break;
3468               }
3469               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3470               break;
3471             }
3472             case 'G':
3473             case 'g':
3474             {
3475               if (LocaleCompare(keyword,"gamma") == 0)
3476               {
3477                 levelGamma = StringToDouble( value );
3478                 break;
3479               }
3480               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3481               break;
3482             }
3483             case 'W':
3484             case 'w':
3485             {
3486               if (LocaleCompare(keyword,"white") == 0)
3487               {
3488                 levelWhite = StringToDouble( value );
3489                 break;
3490               }
3491               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3492               break;
3493             }
3494             default:
3495             {
3496               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3497               break;
3498             }
3499           }
3500         }
3501
3502         /* process image */
3503         {
3504           char level[MaxTextExtent + 1];
3505           (void) FormatMagickString(level,MaxTextExtent,"%3.6f/%3.6f/%3.6f/",
3506             levelBlack,levelGamma,levelWhite);
3507           LevelImage ( msl_info->image[n], level );
3508           break;
3509         }
3510       }
3511     }
3512     case 'M':
3513     case 'm':
3514     {
3515       if (LocaleCompare((const char *) tag,"magnify") == 0)
3516         {
3517           Image
3518             *magnify_image;
3519
3520           /*
3521             Magnify image.
3522           */
3523           if (msl_info->image[n] == (Image *) NULL)
3524             {
3525               ThrowMSLException(OptionError,"NoImagesDefined",
3526                 (const char *) tag);
3527               break;
3528             }
3529           if (attributes != (const xmlChar **) NULL)
3530             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3531             {
3532               keyword=(const char *) attributes[i++];
3533               attribute=InterpretImageProperties(msl_info->image_info[n],
3534                 msl_info->attributes[n],(const char *) attributes[i]);
3535               CloneString(&value,attribute);
3536               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3537             }
3538           magnify_image=MagnifyImage(msl_info->image[n],
3539             &msl_info->image[n]->exception);
3540           if (magnify_image == (Image *) NULL)
3541             break;
3542           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3543           msl_info->image[n]=magnify_image;
3544           break;
3545         }
3546       if (LocaleCompare((const char *) tag,"map") == 0)
3547         {
3548           Image
3549             *affinity_image;
3550
3551           MagickBooleanType
3552             dither;
3553
3554           QuantizeInfo
3555             *quantize_info;
3556
3557           /*
3558             Map image.
3559           */
3560           if (msl_info->image[n] == (Image *) NULL)
3561             {
3562               ThrowMSLException(OptionError,"NoImagesDefined",
3563                 (const char *) tag);
3564               break;
3565             }
3566           affinity_image=NewImageList();
3567           dither=MagickFalse;
3568           if (attributes != (const xmlChar **) NULL)
3569             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3570             {
3571               keyword=(const char *) attributes[i++];
3572               attribute=InterpretImageProperties(msl_info->image_info[n],
3573                 msl_info->attributes[n],(const char *) attributes[i]);
3574               CloneString(&value,attribute);
3575               switch (*keyword)
3576               {
3577                 case 'D':
3578                 case 'd':
3579                 {
3580                   if (LocaleCompare(keyword,"dither") == 0)
3581                     {
3582                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
3583                         value);
3584                       if (option < 0)
3585                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3586                           value);
3587                       dither=(MagickBooleanType) option;
3588                       break;
3589                     }
3590                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3591                     keyword);
3592                   break;
3593                 }
3594                 case 'I':
3595                 case 'i':
3596                 {
3597                   if (LocaleCompare(keyword,"image") == 0)
3598                     for (j=0; j < msl_info->n; j++)
3599                     {
3600                       const char
3601                         *attribute;
3602
3603                       attribute=GetImageProperty(msl_info->attributes[j],"id");
3604                       if ((attribute != (const char *) NULL)  &&
3605                           (LocaleCompare(attribute,value) == 0))
3606                         {
3607                           affinity_image=CloneImage(msl_info->image[j],0,0,
3608                             MagickFalse,&exception);
3609                           break;
3610                         }
3611                     }
3612                   break;
3613                 }
3614                 default:
3615                 {
3616                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3617                     keyword);
3618                   break;
3619                 }
3620               }
3621             }
3622           quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3623           quantize_info->dither=dither;
3624           (void) RemapImages(quantize_info,msl_info->image[n],
3625             affinity_image);
3626           quantize_info=DestroyQuantizeInfo(quantize_info);
3627           affinity_image=DestroyImage(affinity_image);
3628           break;
3629         }
3630       if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
3631         {
3632           double
3633             opacity;
3634
3635           MagickPixelPacket
3636             target;
3637
3638           PaintMethod
3639             paint_method;
3640
3641           /*
3642             Matte floodfill image.
3643           */
3644           opacity=0.0;
3645           if (msl_info->image[n] == (Image *) NULL)
3646             {
3647               ThrowMSLException(OptionError,"NoImagesDefined",
3648                 (const char *) tag);
3649               break;
3650             }
3651           SetGeometry(msl_info->image[n],&geometry);
3652           paint_method=FloodfillMethod;
3653           if (attributes != (const xmlChar **) NULL)
3654             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3655             {
3656               keyword=(const char *) attributes[i++];
3657               attribute=InterpretImageProperties(msl_info->image_info[n],
3658                 msl_info->attributes[n],(const char *) attributes[i]);
3659               CloneString(&value,attribute);
3660               switch (*keyword)
3661               {
3662                 case 'B':
3663                 case 'b':
3664                 {
3665                   if (LocaleCompare(keyword,"bordercolor") == 0)
3666                     {
3667                       (void) QueryMagickColor(value,&target,&exception);
3668                       paint_method=FillToBorderMethod;
3669                       break;
3670                     }
3671                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3672                     keyword);
3673                   break;
3674                 }
3675                 case 'F':
3676                 case 'f':
3677                 {
3678                   if (LocaleCompare(keyword,"fuzz") == 0)
3679                     {
3680                       msl_info->image[n]->fuzz=StringToDouble(value);
3681                       break;
3682                     }
3683                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3684                     keyword);
3685                   break;
3686                 }
3687                 case 'G':
3688                 case 'g':
3689                 {
3690                   if (LocaleCompare(keyword,"geometry") == 0)
3691                     {
3692                       flags=ParsePageGeometry(msl_info->image[n],value,
3693                         &geometry,&exception);
3694                       if ((flags & HeightValue) == 0)
3695                         geometry.height=geometry.width;
3696                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
3697                         geometry.x,geometry.y,&target,&exception);
3698                       break;
3699                     }
3700                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3701                     keyword);
3702                   break;
3703                 }
3704                 case 'O':
3705                 case 'o':
3706                 {
3707                   if (LocaleCompare(keyword,"opacity") == 0)
3708                     {
3709                       opacity=StringToDouble(value);
3710                       break;
3711                     }
3712                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3713                     keyword);
3714                   break;
3715                 }
3716                 case 'X':
3717                 case 'x':
3718                 {
3719                   if (LocaleCompare(keyword,"x") == 0)
3720                     {
3721                       geometry.x=StringToLong(value);
3722                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
3723                         geometry.x,geometry.y,&target,&exception);
3724                       break;
3725                     }
3726                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3727                     keyword);
3728                   break;
3729                 }
3730                 case 'Y':
3731                 case 'y':
3732                 {
3733                   if (LocaleCompare(keyword,"y") == 0)
3734                     {
3735                       geometry.y=StringToLong(value);
3736                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
3737                         geometry.x,geometry.y,&target,&exception);
3738                       break;
3739                     }
3740                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3741                     keyword);
3742                   break;
3743                 }
3744                 default:
3745                 {
3746                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3747                     keyword);
3748                   break;
3749                 }
3750               }
3751             }
3752           draw_info=CloneDrawInfo(msl_info->image_info[n],
3753             msl_info->draw_info[n]);
3754           draw_info->fill.opacity=ClampToQuantum(opacity);
3755           (void) FloodfillPaintImage(msl_info->image[n],OpacityChannel,
3756             draw_info,&target,geometry.x,geometry.y,
3757             paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
3758           draw_info=DestroyDrawInfo(draw_info);
3759           break;
3760         }
3761       if (LocaleCompare((const char *) tag,"median-filter") == 0)
3762         {
3763           Image
3764             *median_image;
3765
3766           /*
3767             Median-filter image.
3768           */
3769           if (msl_info->image[n] == (Image *) NULL)
3770             {
3771               ThrowMSLException(OptionError,"NoImagesDefined",
3772                 (const char *) tag);
3773               break;
3774             }
3775           if (attributes != (const xmlChar **) NULL)
3776             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3777             {
3778               keyword=(const char *) attributes[i++];
3779               attribute=InterpretImageProperties(msl_info->image_info[n],
3780                 msl_info->attributes[n],(const char *) attributes[i]);
3781               CloneString(&value,attribute);
3782               switch (*keyword)
3783               {
3784                 case 'G':
3785                 case 'g':
3786                 {
3787                   if (LocaleCompare(keyword,"geometry") == 0)
3788                     {
3789                       flags=ParseGeometry(value,&geometry_info);
3790                       if ((flags & SigmaValue) == 0)
3791                         geometry_info.sigma=1.0;
3792                       break;
3793                     }
3794                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3795                     keyword);
3796                   break;
3797                 }
3798                 case 'R':
3799                 case 'r':
3800                 {
3801                   if (LocaleCompare(keyword,"radius") == 0)
3802                     {
3803                       geometry_info.rho=StringToDouble(value);
3804                       break;
3805                     }
3806                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3807                     keyword);
3808                   break;
3809                 }
3810                 default:
3811                 {
3812                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3813                     keyword);
3814                   break;
3815                 }
3816               }
3817             }
3818           median_image=MedianFilterImage(msl_info->image[n],geometry_info.rho,
3819             &msl_info->image[n]->exception);
3820           if (median_image == (Image *) NULL)
3821             break;
3822           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3823           msl_info->image[n]=median_image;
3824           break;
3825         }
3826       if (LocaleCompare((const char *) tag,"minify") == 0)
3827         {
3828           Image
3829             *minify_image;
3830
3831           /*
3832             Minify image.
3833           */
3834           if (msl_info->image[n] == (Image *) NULL)
3835             {
3836               ThrowMSLException(OptionError,"NoImagesDefined",
3837                 (const char *) tag);
3838               break;
3839             }
3840           if (attributes != (const xmlChar **) NULL)
3841             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3842             {
3843               keyword=(const char *) attributes[i++];
3844               attribute=InterpretImageProperties(msl_info->image_info[n],
3845                 msl_info->attributes[n],(const char *) attributes[i]);
3846               CloneString(&value,attribute);
3847               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3848             }
3849           minify_image=MinifyImage(msl_info->image[n],
3850             &msl_info->image[n]->exception);
3851           if (minify_image == (Image *) NULL)
3852             break;
3853           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3854           msl_info->image[n]=minify_image;
3855           break;
3856         }
3857       if (LocaleCompare((const char *) tag,"msl") == 0 )
3858         break;
3859       if (LocaleCompare((const char *) tag,"modulate") == 0)
3860         {
3861           char
3862             modulate[MaxTextExtent];
3863
3864           /*
3865             Modulate image.
3866           */
3867           if (msl_info->image[n] == (Image *) NULL)
3868             {
3869               ThrowMSLException(OptionError,"NoImagesDefined",
3870                 (const char *) tag);
3871               break;
3872             }
3873           geometry_info.rho=100.0;
3874           geometry_info.sigma=100.0;
3875           geometry_info.xi=100.0;
3876           if (attributes != (const xmlChar **) NULL)
3877             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3878             {
3879               keyword=(const char *) attributes[i++];
3880               attribute=InterpretImageProperties(msl_info->image_info[n],
3881                 msl_info->attributes[n],(const char *) attributes[i]);
3882               CloneString(&value,attribute);
3883               switch (*keyword)
3884               {
3885                 case 'B':
3886                 case 'b':
3887                 {
3888                   if (LocaleCompare(keyword,"blackness") == 0)
3889                     {
3890                       geometry_info.rho=StringToDouble(value);
3891                       break;
3892                     }
3893                   if (LocaleCompare(keyword,"brightness") == 0)
3894                     {
3895                       geometry_info.rho=StringToDouble(value);
3896                       break;
3897                     }
3898                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3899                     keyword);
3900                   break;
3901                 }
3902                 case 'F':
3903                 case 'f':
3904                 {
3905                   if (LocaleCompare(keyword,"factor") == 0)
3906                     {
3907                       flags=ParseGeometry(value,&geometry_info);
3908                       break;
3909                     }
3910                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3911                     keyword);
3912                   break;
3913                 }
3914                 case 'H':
3915                 case 'h':
3916                 {
3917                   if (LocaleCompare(keyword,"hue") == 0)
3918                     {
3919                       geometry_info.xi=StringToDouble(value);
3920                       break;
3921                     }
3922                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3923                     keyword);
3924                   break;
3925                 }
3926                 case 'L':
3927                 case 'l':
3928                 {
3929                   if (LocaleCompare(keyword,"lightness") == 0)
3930                     {
3931                       geometry_info.rho=StringToDouble(value);
3932                       break;
3933                     }
3934                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3935                     keyword);
3936                   break;
3937                 }
3938                 case 'S':
3939                 case 's':
3940                 {
3941                   if (LocaleCompare(keyword,"saturation") == 0)
3942                     {
3943                       geometry_info.sigma=StringToDouble(value);
3944                       break;
3945                     }
3946                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3947                     keyword);
3948                   break;
3949                 }
3950                 case 'W':
3951                 case 'w':
3952                 {
3953                   if (LocaleCompare(keyword,"whiteness") == 0)
3954                     {
3955                       geometry_info.sigma=StringToDouble(value);
3956                       break;
3957                     }
3958                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3959                     keyword);
3960                   break;
3961                 }
3962                 default:
3963                 {
3964                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3965                     keyword);
3966                   break;
3967                 }
3968               }
3969             }
3970           (void) FormatMagickString(modulate,MaxTextExtent,"%g,%g,%g",
3971             geometry_info.rho,geometry_info.sigma,geometry_info.xi);
3972           (void) ModulateImage(msl_info->image[n],modulate);
3973           break;
3974         }
3975       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3976     }
3977     case 'N':
3978     case 'n':
3979     {
3980       if (LocaleCompare((const char *) tag,"negate") == 0)
3981         {
3982           MagickBooleanType
3983             gray;
3984
3985           /*
3986             Negate image.
3987           */
3988           if (msl_info->image[n] == (Image *) NULL)
3989             {
3990               ThrowMSLException(OptionError,"NoImagesDefined",
3991                 (const char *) tag);
3992               break;
3993             }
3994           gray=MagickFalse;
3995           if (attributes != (const xmlChar **) NULL)
3996             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3997             {
3998               keyword=(const char *) attributes[i++];
3999               attribute=InterpretImageProperties(msl_info->image_info[n],
4000                 msl_info->attributes[n],(const char *) attributes[i]);
4001               CloneString(&value,attribute);
4002               switch (*keyword)
4003               {
4004                 case 'C':
4005                 case 'c':
4006                 {
4007                   if (LocaleCompare(keyword,"channel") == 0)
4008                     {
4009                       option=ParseChannelOption(value);
4010                       if (option < 0)
4011                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4012                           value);
4013                       channel=(ChannelType) option;
4014                       break;
4015                     }
4016                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4017                     keyword);
4018                   break;
4019                 }
4020                 case 'G':
4021                 case 'g':
4022                 {
4023                   if (LocaleCompare(keyword,"gray") == 0)
4024                     {
4025                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4026                         value);
4027                       if (option < 0)
4028                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4029                           value);
4030                       gray=(MagickBooleanType) option;
4031                       break;
4032                     }
4033                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4034                     keyword);
4035                   break;
4036                 }
4037                 default:
4038                 {
4039                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4040                     keyword);
4041                   break;
4042                 }
4043               }
4044             }
4045           (void) NegateImageChannel(msl_info->image[n],channel,gray);
4046           break;
4047         }
4048       if (LocaleCompare((const char *) tag,"normalize") == 0)
4049         {
4050           /*
4051             Normalize image.
4052           */
4053           if (msl_info->image[n] == (Image *) NULL)
4054             {
4055               ThrowMSLException(OptionError,"NoImagesDefined",
4056                 (const char *) tag);
4057               break;
4058             }
4059           if (attributes != (const xmlChar **) NULL)
4060             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4061             {
4062               keyword=(const char *) attributes[i++];
4063               attribute=InterpretImageProperties(msl_info->image_info[n],
4064                 msl_info->attributes[n],(const char *) attributes[i]);
4065               CloneString(&value,attribute);
4066               switch (*keyword)
4067               {
4068                 case 'C':
4069                 case 'c':
4070                 {
4071                   if (LocaleCompare(keyword,"channel") == 0)
4072                     {
4073                       option=ParseChannelOption(value);
4074                       if (option < 0)
4075                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4076                           value);
4077                       channel=(ChannelType) option;
4078                       break;
4079                     }
4080                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4081                     keyword);
4082                   break;
4083                 }
4084                 default:
4085                 {
4086                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4087                     keyword);
4088                   break;
4089                 }
4090               }
4091             }
4092           (void) NormalizeImageChannel(msl_info->image[n],channel);
4093           break;
4094         }
4095       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4096     }
4097     case 'O':
4098     case 'o':
4099     {
4100       if (LocaleCompare((const char *) tag,"oil-paint") == 0)
4101         {
4102           Image
4103             *paint_image;
4104
4105           /*
4106             Oil-paint image.
4107           */
4108           if (msl_info->image[n] == (Image *) NULL)
4109             {
4110               ThrowMSLException(OptionError,"NoImagesDefined",
4111                 (const char *) tag);
4112               break;
4113             }
4114           if (attributes != (const xmlChar **) NULL)
4115             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4116             {
4117               keyword=(const char *) attributes[i++];
4118               attribute=InterpretImageProperties(msl_info->image_info[n],
4119                 msl_info->attributes[n],(const char *) attributes[i]);
4120               CloneString(&value,attribute);
4121               switch (*keyword)
4122               {
4123                 case 'G':
4124                 case 'g':
4125                 {
4126                   if (LocaleCompare(keyword,"geometry") == 0)
4127                     {
4128                       flags=ParseGeometry(value,&geometry_info);
4129                       if ((flags & SigmaValue) == 0)
4130                         geometry_info.sigma=1.0;
4131                       break;
4132                     }
4133                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4134                     keyword);
4135                   break;
4136                 }
4137                 case 'R':
4138                 case 'r':
4139                 {
4140                   if (LocaleCompare(keyword,"radius") == 0)
4141                     {
4142                       geometry_info.rho=StringToDouble(value);
4143                       break;
4144                     }
4145                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4146                     keyword);
4147                   break;
4148                 }
4149                 default:
4150                 {
4151                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4152                     keyword);
4153                   break;
4154                 }
4155               }
4156             }
4157           paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4158             &msl_info->image[n]->exception);
4159           if (paint_image == (Image *) NULL)
4160             break;
4161           msl_info->image[n]=DestroyImage(msl_info->image[n]);
4162           msl_info->image[n]=paint_image;
4163           break;
4164         }
4165       if (LocaleCompare((const char *) tag,"opaque") == 0)
4166         {
4167           MagickPixelPacket
4168             fill_color,
4169             target;
4170
4171           /*
4172             Opaque image.
4173           */
4174           if (msl_info->image[n] == (Image *) NULL)
4175             {
4176               ThrowMSLException(OptionError,"NoImagesDefined",
4177                 (const char *) tag);
4178               break;
4179             }
4180           (void) QueryMagickColor("none",&target,&exception);
4181           (void) QueryMagickColor("none",&fill_color,&exception);
4182           if (attributes != (const xmlChar **) NULL)
4183             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4184             {
4185               keyword=(const char *) attributes[i++];
4186               attribute=InterpretImageProperties(msl_info->image_info[n],
4187                 msl_info->attributes[n],(const char *) attributes[i]);
4188               CloneString(&value,attribute);
4189               switch (*keyword)
4190               {
4191                 case 'C':
4192                 case 'c':
4193                 {
4194                   if (LocaleCompare(keyword,"channel") == 0)
4195                     {
4196                       option=ParseChannelOption(value);
4197                       if (option < 0)
4198                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4199                           value);
4200                       channel=(ChannelType) option;
4201                       break;
4202                     }
4203                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4204                     keyword);
4205                   break;
4206                 }
4207                 case 'F':
4208                 case 'f':
4209                 {
4210                   if (LocaleCompare(keyword,"fill") == 0)
4211                     {
4212                       (void) QueryMagickColor(value,&fill_color,&exception);
4213                       break;
4214                     }
4215                   if (LocaleCompare(keyword,"fuzz") == 0)
4216                     {
4217                       msl_info->image[n]->fuzz=StringToDouble(value);
4218                       break;
4219                     }
4220                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4221                     keyword);
4222                   break;
4223                 }
4224                 default:
4225                 {
4226                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4227                     keyword);
4228                   break;
4229                 }
4230               }
4231             }
4232           (void) OpaquePaintImageChannel(msl_info->image[n],channel,
4233             &target,&fill_color,MagickFalse);
4234           break;
4235         }
4236       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4237     }
4238     case 'P':
4239     case 'p':
4240     {
4241       if (LocaleCompare((const char *) tag,"print") == 0)
4242         {
4243           if (attributes == (const xmlChar **) NULL)
4244             break;
4245           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4246           {
4247             keyword=(const char *) attributes[i++];
4248             attribute=InterpretImageProperties(msl_info->image_info[n],
4249               msl_info->attributes[n],(const char *) attributes[i]);
4250             CloneString(&value,attribute);
4251             switch (*keyword)
4252             {
4253               case 'O':
4254               case 'o':
4255               {
4256                 if (LocaleCompare(keyword,"output") == 0)
4257                   {
4258                     (void) fprintf(stdout,"%s",value);
4259                     break;
4260                   }
4261                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4262                 break;
4263               }
4264               default:
4265               {
4266                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4267                 break;
4268               }
4269             }
4270           }
4271           break;
4272         }
4273         if (LocaleCompare((const char *) tag, "profile") == 0)
4274           {
4275             if (msl_info->image[n] == (Image *) NULL)
4276               {
4277                 ThrowMSLException(OptionError,"NoImagesDefined",
4278                   (const char *) tag);
4279                 break;
4280               }
4281             if (attributes == (const xmlChar **) NULL)
4282               break;
4283             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4284             {
4285               const char
4286                 *name;
4287
4288               const StringInfo
4289                 *profile;
4290
4291               Image
4292                 *profile_image;
4293
4294               ImageInfo
4295                 *profile_info;
4296
4297               keyword=(const char *) attributes[i++];
4298               attribute=InterpretImageProperties(msl_info->image_info[n],
4299                 msl_info->attributes[n],(const char *) attributes[i]);
4300               CloneString(&value,attribute);
4301               if (*keyword == '+')
4302                 {
4303                   /*
4304                     Remove a profile from the image.
4305                   */
4306                   (void) ProfileImage(msl_info->image[n],keyword,
4307                     (const unsigned char *) NULL,0,MagickTrue);
4308                   continue;
4309                 }
4310               /*
4311                 Associate a profile with the image.
4312               */
4313               profile_info=CloneImageInfo(msl_info->image_info[n]);
4314               profile=GetImageProfile(msl_info->image[n],"iptc");
4315               if (profile != (StringInfo *) NULL)
4316                 profile_info->profile=(void *) CloneStringInfo(profile);
4317               profile_image=GetImageCache(profile_info,keyword,&exception);
4318               profile_info=DestroyImageInfo(profile_info);
4319               if (profile_image == (Image *) NULL)
4320                 {
4321                   char
4322                     name[MaxTextExtent],
4323                     filename[MaxTextExtent];
4324
4325                   register char
4326                     *p;
4327
4328                   StringInfo
4329                     *profile;
4330
4331                   (void) CopyMagickString(filename,keyword,MaxTextExtent);
4332                   (void) CopyMagickString(name,keyword,MaxTextExtent);
4333                   for (p=filename; *p != '\0'; p++)
4334                     if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4335                         (IsPathAccessible(keyword) == MagickFalse))
4336                       {
4337                         register char
4338                           *q;
4339
4340                         /*
4341                           Look for profile name (e.g. name:profile).
4342                         */
4343                         (void) CopyMagickString(name,filename,(size_t)
4344                           (p-filename+1));
4345                         for (q=filename; *q != '\0'; q++)
4346                           *q=(*++p);
4347                         break;
4348                       }
4349                   profile=FileToStringInfo(filename,~0UL,&exception);
4350                   if (profile != (StringInfo *) NULL)
4351                     {
4352                       (void) ProfileImage(msl_info->image[n],name,
4353                         GetStringInfoDatum(profile),(size_t)
4354                         GetStringInfoLength(profile),MagickFalse);
4355                       profile=DestroyStringInfo(profile);
4356                     }
4357                   continue;
4358                 }
4359               ResetImageProfileIterator(profile_image);
4360               name=GetNextImageProfile(profile_image);
4361               while (name != (const char *) NULL)
4362               {
4363                 profile=GetImageProfile(profile_image,name);
4364                 if (profile != (StringInfo *) NULL)
4365                   (void) ProfileImage(msl_info->image[n],name,
4366                     GetStringInfoDatum(profile),(size_t)
4367                     GetStringInfoLength(profile),MagickFalse);
4368                 name=GetNextImageProfile(profile_image);
4369               }
4370               profile_image=DestroyImage(profile_image);
4371             }
4372             break;
4373           }
4374       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4375     }
4376     case 'Q':
4377     case 'q':
4378     {
4379       if (LocaleCompare((const char *) tag,"quantize") == 0)
4380         {
4381           QuantizeInfo
4382             quantize_info;
4383
4384           /*
4385             Quantize image.
4386           */
4387           if (msl_info->image[n] == (Image *) NULL)
4388             {
4389               ThrowMSLException(OptionError,"NoImagesDefined",
4390                 (const char *) tag);
4391               break;
4392             }
4393           GetQuantizeInfo(&quantize_info);
4394           if (attributes != (const xmlChar **) NULL)
4395             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4396             {
4397               keyword=(const char *) attributes[i++];
4398               attribute=InterpretImageProperties(msl_info->image_info[n],
4399                 msl_info->attributes[n],(const char *) attributes[i]);
4400               CloneString(&value,attribute);
4401               switch (*keyword)
4402               {
4403                 case 'C':
4404                 case 'c':
4405                 {
4406                   if (LocaleCompare(keyword,"colors") == 0)
4407                     {
4408                       quantize_info.number_colors=StringToLong(value);
4409                       break;
4410                     }
4411                   if (LocaleCompare(keyword,"colorspace") == 0)
4412                     {
4413                       option=ParseMagickOption(MagickColorspaceOptions,
4414                         MagickFalse,value);
4415                       if (option < 0)
4416                         ThrowMSLException(OptionError,
4417                           "UnrecognizedColorspaceType",value);
4418                       quantize_info.colorspace=(ColorspaceType) option;
4419                       break;
4420                     }
4421                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4422                     keyword);
4423                   break;
4424                 }
4425                 case 'D':
4426                 case 'd':
4427                 {
4428                   if (LocaleCompare(keyword,"dither") == 0)
4429                     {
4430                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4431                         value);
4432                       if (option < 0)
4433                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4434                           value);
4435                       quantize_info.dither=(MagickBooleanType) option;
4436                       break;
4437                     }
4438                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4439                     keyword);
4440                   break;
4441                 }
4442                 case 'M':
4443                 case 'm':
4444                 {
4445                   if (LocaleCompare(keyword,"measure") == 0)
4446                     {
4447                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4448                         value);
4449                       if (option < 0)
4450                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4451                           value);
4452                       quantize_info.measure_error=(MagickBooleanType) option;
4453                       break;
4454                     }
4455                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4456                     keyword);
4457                   break;
4458                 }
4459                 case 'T':
4460                 case 't':
4461                 {
4462                   if (LocaleCompare(keyword,"treedepth") == 0)
4463                     {
4464                       quantize_info.tree_depth=StringToLong(value);
4465                       break;
4466                     }
4467                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4468                     keyword);
4469                   break;
4470                 }
4471                 default:
4472                 {
4473                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4474                     keyword);
4475                   break;
4476                 }
4477               }
4478             }
4479           (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4480           break;
4481         }
4482       if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
4483         {
4484           char
4485             text[MaxTextExtent];
4486
4487           MagickBooleanType
4488             status;
4489
4490           TypeMetric
4491             metrics;
4492
4493           /*
4494             Query font metrics.
4495           */
4496           draw_info=CloneDrawInfo(msl_info->image_info[n],
4497             msl_info->draw_info[n]);
4498           angle=0.0;
4499           current=draw_info->affine;
4500           GetAffineMatrix(&affine);
4501           if (attributes != (const xmlChar **) NULL)
4502             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4503             {
4504               keyword=(const char *) attributes[i++];
4505               attribute=InterpretImageProperties(msl_info->image_info[n],
4506                 msl_info->attributes[n],(const char *) attributes[i]);
4507               CloneString(&value,attribute);
4508               switch (*keyword)
4509               {
4510                 case 'A':
4511                 case 'a':
4512                 {
4513                   if (LocaleCompare(keyword,"affine") == 0)
4514                     {
4515                       char
4516                         *p;
4517
4518                       p=value;
4519                       draw_info->affine.sx=strtod(p,&p);
4520                       if (*p ==',')
4521                         p++;
4522                       draw_info->affine.rx=strtod(p,&p);
4523                       if (*p ==',')
4524                         p++;
4525                       draw_info->affine.ry=strtod(p,&p);
4526                       if (*p ==',')
4527                         p++;
4528                       draw_info->affine.sy=strtod(p,&p);
4529                       if (*p ==',')
4530                         p++;
4531                       draw_info->affine.tx=strtod(p,&p);
4532                       if (*p ==',')
4533                         p++;
4534                       draw_info->affine.ty=strtod(p,&p);
4535                       break;
4536                     }
4537                   if (LocaleCompare(keyword,"align") == 0)
4538                     {
4539                       option=ParseMagickOption(MagickAlignOptions,MagickFalse,
4540                         value);
4541                       if (option < 0)
4542                         ThrowMSLException(OptionError,"UnrecognizedAlignType",
4543                           value);
4544                       draw_info->align=(AlignType) option;
4545                       break;
4546                     }
4547                   if (LocaleCompare(keyword,"antialias") == 0)
4548                     {
4549                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4550                         value);
4551                       if (option < 0)
4552                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4553                           value);
4554                       draw_info->stroke_antialias=(MagickBooleanType) option;
4555                       draw_info->text_antialias=(MagickBooleanType) option;
4556                       break;
4557                     }
4558                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4559                     keyword);
4560                   break;
4561                 }
4562                 case 'D':
4563                 case 'd':
4564                 {
4565                   if (LocaleCompare(keyword,"density") == 0)
4566                     {
4567                       CloneString(&draw_info->density,value);
4568                       break;
4569                     }
4570                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4571                     keyword);
4572                   break;
4573                 }
4574                 case 'E':
4575                 case 'e':
4576                 {
4577                   if (LocaleCompare(keyword,"encoding") == 0)
4578                     {
4579                       CloneString(&draw_info->encoding,value);
4580                       break;
4581                     }
4582                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4583                     keyword);
4584                   break;
4585                 }
4586                 case 'F':
4587                 case 'f':
4588                 {
4589                   if (LocaleCompare(keyword, "fill") == 0)
4590                     {
4591                       (void) QueryColorDatabase(value,&draw_info->fill,
4592                         &exception);
4593                       break;
4594                     }
4595                   if (LocaleCompare(keyword,"family") == 0)
4596                     {
4597                       CloneString(&draw_info->family,value);
4598                       break;
4599                     }
4600                   if (LocaleCompare(keyword,"font") == 0)
4601                     {
4602                       CloneString(&draw_info->font,value);
4603                       break;
4604                     }
4605                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4606                     keyword);
4607                   break;
4608                 }
4609                 case 'G':
4610                 case 'g':
4611                 {
4612                   if (LocaleCompare(keyword,"geometry") == 0)
4613                     {
4614                       flags=ParsePageGeometry(msl_info->image[n],value,
4615                         &geometry,&exception);
4616                       if ((flags & HeightValue) == 0)
4617                         geometry.height=geometry.width;
4618                       break;
4619                     }
4620                   if (LocaleCompare(keyword,"gravity") == 0)
4621                     {
4622                       option=ParseMagickOption(MagickGravityOptions,MagickFalse,
4623                         value);
4624                       if (option < 0)
4625                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
4626                           value);
4627                       draw_info->gravity=(GravityType) option;
4628                       break;
4629                     }
4630                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4631                     keyword);
4632                   break;
4633                 }
4634                 case 'P':
4635                 case 'p':
4636                 {
4637                   if (LocaleCompare(keyword,"pointsize") == 0)
4638                     {
4639                       draw_info->pointsize=StringToDouble(value);
4640                       break;
4641                     }
4642                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4643                     keyword);
4644                   break;
4645                 }
4646                 case 'R':
4647                 case 'r':
4648                 {
4649                   if (LocaleCompare(keyword,"rotate") == 0)
4650                     {
4651                       angle=StringToDouble(value);
4652                       affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4653                       affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4654                       affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4655                       affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4656                       break;
4657                     }
4658                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4659                     keyword);
4660                   break;
4661                 }
4662                 case 'S':
4663                 case 's':
4664                 {
4665                   if (LocaleCompare(keyword,"scale") == 0)
4666                     {
4667                       flags=ParseGeometry(value,&geometry_info);
4668                       if ((flags & SigmaValue) == 0)
4669                         geometry_info.sigma=1.0;
4670                       affine.sx=geometry_info.rho;
4671                       affine.sy=geometry_info.sigma;
4672                       break;
4673                     }
4674                   if (LocaleCompare(keyword,"skewX") == 0)
4675                     {
4676                       angle=StringToDouble(value);
4677                       affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4678                       break;
4679                     }
4680                   if (LocaleCompare(keyword,"skewY") == 0)
4681                     {
4682                       angle=StringToDouble(value);
4683                       affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4684                       break;
4685                     }
4686                   if (LocaleCompare(keyword,"stretch") == 0)
4687                     {
4688                       option=ParseMagickOption(MagickStretchOptions,MagickFalse,
4689                         value);
4690                       if (option < 0)
4691                         ThrowMSLException(OptionError,"UnrecognizedStretchType",
4692                           value);
4693                       draw_info->stretch=(StretchType) option;
4694                       break;
4695                     }
4696                   if (LocaleCompare(keyword, "stroke") == 0)
4697                     {
4698                       (void) QueryColorDatabase(value,&draw_info->stroke,
4699                         &exception);
4700                       break;
4701                     }
4702                   if (LocaleCompare(keyword,"strokewidth") == 0)
4703                     {
4704                       draw_info->stroke_width=StringToLong(value);
4705                       break;
4706                     }
4707                   if (LocaleCompare(keyword,"style") == 0)
4708                     {
4709                       option=ParseMagickOption(MagickStyleOptions,MagickFalse,
4710                         value);
4711                       if (option < 0)
4712                         ThrowMSLException(OptionError,"UnrecognizedStyleType",
4713                           value);
4714                       draw_info->style=(StyleType) option;
4715                       break;
4716                     }
4717                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4718                     keyword);
4719                   break;
4720                 }
4721                 case 'T':
4722                 case 't':
4723                 {
4724                   if (LocaleCompare(keyword,"text") == 0)
4725                     {
4726                       CloneString(&draw_info->text,value);
4727                       break;
4728                     }
4729                   if (LocaleCompare(keyword,"translate") == 0)
4730                     {
4731                       flags=ParseGeometry(value,&geometry_info);
4732                       if ((flags & SigmaValue) == 0)
4733                         geometry_info.sigma=1.0;
4734                       affine.tx=geometry_info.rho;
4735                       affine.ty=geometry_info.sigma;
4736                       break;
4737                     }
4738                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4739                     keyword);
4740                   break;
4741                 }
4742                 case 'U':
4743                 case 'u':
4744                 {
4745                   if (LocaleCompare(keyword, "undercolor") == 0)
4746                     {
4747                       (void) QueryColorDatabase(value,&draw_info->undercolor,
4748                         &exception);
4749                       break;
4750                     }
4751                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4752                     keyword);
4753                   break;
4754                 }
4755                 case 'W':
4756                 case 'w':
4757                 {
4758                   if (LocaleCompare(keyword,"weight") == 0)
4759                     {
4760                       draw_info->weight=StringToLong(value);
4761                       break;
4762                     }
4763                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4764                     keyword);
4765                   break;
4766                 }
4767                 case 'X':
4768                 case 'x':
4769                 {
4770                   if (LocaleCompare(keyword,"x") == 0)
4771                     {
4772                       geometry.x=StringToLong(value);
4773                       break;
4774                     }
4775                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4776                     keyword);
4777                   break;
4778                 }
4779                 case 'Y':
4780                 case 'y':
4781                 {
4782                   if (LocaleCompare(keyword,"y") == 0)
4783                     {
4784                       geometry.y=StringToLong(value);
4785                       break;
4786                     }
4787                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4788                     keyword);
4789                   break;
4790                 }
4791                 default:
4792                 {
4793                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4794                     keyword);
4795                   break;
4796                 }
4797               }
4798             }
4799           (void) FormatMagickString(text,MaxTextExtent,
4800             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4801             geometry.height,(double) geometry.x,(double) geometry.y);
4802           CloneString(&draw_info->geometry,text);
4803           draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4804           draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4805           draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4806           draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4807           draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4808             affine.tx;
4809           draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4810             affine.ty;
4811           status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4812           if (status != MagickFalse)
4813             {
4814               Image
4815                 *image;
4816
4817               image=msl_info->attributes[n];
4818               FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
4819                 "%g",metrics.pixels_per_em.x);
4820               FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
4821                 "%g",metrics.pixels_per_em.y);
4822               FormatImageProperty(image,"msl:font-metrics.ascent","%g",
4823                 metrics.ascent);
4824               FormatImageProperty(image,"msl:font-metrics.descent","%g",
4825                 metrics.descent);
4826               FormatImageProperty(image,"msl:font-metrics.width","%g",
4827                 metrics.width);
4828               FormatImageProperty(image,"msl:font-metrics.height","%g",
4829                 metrics.height);
4830               FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
4831                 metrics.max_advance);
4832               FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
4833                 metrics.bounds.x1);
4834               FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
4835                 metrics.bounds.y1);
4836               FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
4837                 metrics.bounds.x2);
4838               FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
4839                 metrics.bounds.y2);
4840               FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
4841                 metrics.origin.x);
4842               FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
4843                 metrics.origin.y);
4844             }
4845           draw_info=DestroyDrawInfo(draw_info);
4846           break;
4847         }
4848       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4849     }
4850     case 'R':
4851     case 'r':
4852     {
4853       if (LocaleCompare((const char *) tag,"raise") == 0)
4854         {
4855           MagickBooleanType
4856             raise;
4857
4858           /*
4859             Raise image.
4860           */
4861           if (msl_info->image[n] == (Image *) NULL)
4862             {
4863               ThrowMSLException(OptionError,"NoImagesDefined",
4864                 (const char *) tag);
4865               break;
4866             }
4867           raise=MagickFalse;
4868           SetGeometry(msl_info->image[n],&geometry);
4869           if (attributes != (const xmlChar **) NULL)
4870             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4871             {
4872               keyword=(const char *) attributes[i++];
4873               attribute=InterpretImageProperties(msl_info->image_info[n],
4874                 msl_info->attributes[n],(const char *) attributes[i]);
4875               CloneString(&value,attribute);
4876               switch (*keyword)
4877               {
4878                 case 'G':
4879                 case 'g':
4880                 {
4881                   if (LocaleCompare(keyword,"geometry") == 0)
4882                     {
4883                       flags=ParsePageGeometry(msl_info->image[n],value,
4884                         &geometry,&exception);
4885                       if ((flags & HeightValue) == 0)
4886                         geometry.height=geometry.width;
4887                       break;
4888                     }
4889                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4890                     keyword);
4891                   break;
4892                 }
4893                 case 'H':
4894                 case 'h':
4895                 {
4896                   if (LocaleCompare(keyword,"height") == 0)
4897                     {
4898                       geometry.height=StringToLong(value);
4899                       break;
4900                     }
4901                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4902                     keyword);
4903                   break;
4904                 }
4905                 case 'R':
4906                 case 'r':
4907                 {
4908                   if (LocaleCompare(keyword,"raise") == 0)
4909                     {
4910                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4911                         value);
4912                       if (option < 0)
4913                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4914                           value);
4915                       raise=(MagickBooleanType) option;
4916                       break;
4917                     }
4918                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4919                     keyword);
4920                   break;
4921                 }
4922                 case 'W':
4923                 case 'w':
4924                 {
4925                   if (LocaleCompare(keyword,"width") == 0)
4926                     {
4927                       geometry.width=StringToLong(value);
4928                       break;
4929                     }
4930                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4931                     keyword);
4932                   break;
4933                 }
4934                 default:
4935                 {
4936                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4937                     keyword);
4938                   break;
4939                 }
4940               }
4941             }
4942           (void) RaiseImage(msl_info->image[n],&geometry,raise);
4943           break;
4944         }
4945       if (LocaleCompare((const char *) tag,"read") == 0)
4946         {
4947           if (attributes == (const xmlChar **) NULL)
4948             break;
4949           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4950           {
4951             keyword=(const char *) attributes[i++];
4952             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
4953               msl_info->attributes[n],(const char *) attributes[i]));
4954             switch (*keyword)
4955             {
4956               case 'F':
4957               case 'f':
4958               {
4959                 if (LocaleCompare(keyword,"filename") == 0)
4960                   {
4961                     Image
4962                       *image;
4963
4964                     (void) CopyMagickString(msl_info->image_info[n]->filename,
4965                       value,MaxTextExtent);
4966                     image=ReadImage(msl_info->image_info[n],&exception);
4967                     CatchException(&exception);
4968                     if (image == (Image *) NULL)
4969                       continue;
4970                     AppendImageToList(&msl_info->image[n],image);
4971                     break;
4972                   }
4973                 (void) SetMSLAttributes(msl_info,keyword,value);
4974                 break;
4975               }
4976               default:
4977               {
4978                 (void) SetMSLAttributes(msl_info,keyword,value);
4979                 break;
4980               }
4981             }
4982           }
4983           break;
4984         }
4985       if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
4986         {
4987           Image
4988             *paint_image;
4989
4990           /*
4991             Reduce-noise image.
4992           */
4993           if (msl_info->image[n] == (Image *) NULL)
4994             {
4995               ThrowMSLException(OptionError,"NoImagesDefined",
4996                 (const char *) tag);
4997               break;
4998             }
4999           if (attributes != (const xmlChar **) NULL)
5000             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5001             {
5002               keyword=(const char *) attributes[i++];
5003               attribute=InterpretImageProperties(msl_info->image_info[n],
5004                 msl_info->attributes[n],(const char *) attributes[i]);
5005               CloneString(&value,attribute);
5006               switch (*keyword)
5007               {
5008                 case 'G':
5009                 case 'g':
5010                 {
5011                   if (LocaleCompare(keyword,"geometry") == 0)
5012                     {
5013                       flags=ParseGeometry(value,&geometry_info);
5014                       if ((flags & SigmaValue) == 0)
5015                         geometry_info.sigma=1.0;
5016                       break;
5017                     }
5018                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5019                     keyword);
5020                   break;
5021                 }
5022                 case 'R':
5023                 case 'r':
5024                 {
5025                   if (LocaleCompare(keyword,"radius") == 0)
5026                     {
5027                       geometry_info.rho=StringToDouble(value);
5028                       break;
5029                     }
5030                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5031                     keyword);
5032                   break;
5033                 }
5034                 default:
5035                 {
5036                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5037                     keyword);
5038                   break;
5039                 }
5040               }
5041             }
5042           paint_image=ReduceNoiseImage(msl_info->image[n],geometry_info.rho,
5043             &msl_info->image[n]->exception);
5044           if (paint_image == (Image *) NULL)
5045             break;
5046           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5047           msl_info->image[n]=paint_image;
5048           break;
5049         }
5050       else if (LocaleCompare((const char *) tag,"repage") == 0)
5051       {
5052         /* init the values */
5053         width=msl_info->image[n]->page.width;
5054         height=msl_info->image[n]->page.height;
5055         x=msl_info->image[n]->page.x;
5056         y=msl_info->image[n]->page.y;
5057
5058         if (msl_info->image[n] == (Image *) NULL)
5059         {
5060           ThrowMSLException(OptionError,"NoImagesDefined",
5061             (const char *) tag);
5062           break;
5063         }
5064         if (attributes == (const xmlChar **) NULL)
5065         break;
5066         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5067         {
5068         keyword=(const char *) attributes[i++];
5069         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5070           msl_info->attributes[n],(const char *) attributes[i]));
5071         switch (*keyword)
5072         {
5073           case 'G':
5074           case 'g':
5075           {
5076           if (LocaleCompare(keyword,"geometry") == 0)
5077             {
5078               int
5079                 flags;
5080
5081               RectangleInfo
5082                 geometry;
5083
5084             flags=ParseAbsoluteGeometry(value,&geometry);
5085             if ((flags & WidthValue) != 0)
5086               {
5087                 if ((flags & HeightValue) == 0)
5088                   geometry.height=geometry.width;
5089                 width=geometry.width;
5090                 height=geometry.height;
5091               }
5092             if ((flags & AspectValue) != 0)
5093               {
5094                 if ((flags & XValue) != 0)
5095                   x+=geometry.x;
5096                 if ((flags & YValue) != 0)
5097                   y+=geometry.y;
5098               }
5099             else
5100               {
5101                 if ((flags & XValue) != 0)
5102                   {
5103                     x=geometry.x;
5104                     if ((width == 0) && (geometry.x > 0))
5105                       width=msl_info->image[n]->columns+geometry.x;
5106                   }
5107                 if ((flags & YValue) != 0)
5108                   {
5109                     y=geometry.y;
5110                     if ((height == 0) && (geometry.y > 0))
5111                       height=msl_info->image[n]->rows+geometry.y;
5112                   }
5113               }
5114             break;
5115             }
5116           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5117           break;
5118           }
5119           case 'H':
5120           case 'h':
5121           {
5122           if (LocaleCompare(keyword,"height") == 0)
5123             {
5124             height = StringToLong( value );
5125             break;
5126             }
5127           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5128           break;
5129           }
5130           case 'W':
5131           case 'w':
5132           {
5133           if (LocaleCompare(keyword,"width") == 0)
5134             {
5135             width = StringToLong( value );
5136             break;
5137             }
5138           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5139           break;
5140           }
5141           case 'X':
5142           case 'x':
5143           {
5144           if (LocaleCompare(keyword,"x") == 0)
5145             {
5146             x = StringToLong( value );
5147             break;
5148             }
5149           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5150           break;
5151           }
5152           case 'Y':
5153           case 'y':
5154           {
5155           if (LocaleCompare(keyword,"y") == 0)
5156             {
5157             y = StringToLong( value );
5158             break;
5159             }
5160           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5161           break;
5162           }
5163           default:
5164           {
5165           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5166           break;
5167           }
5168         }
5169         }
5170
5171          msl_info->image[n]->page.width=width;
5172          msl_info->image[n]->page.height=height;
5173          msl_info->image[n]->page.x=x;
5174          msl_info->image[n]->page.y=y;
5175         break;
5176       }
5177     else if (LocaleCompare((const char *) tag,"resample") == 0)
5178     {
5179       double
5180         x_resolution,
5181         y_resolution;
5182
5183       if (msl_info->image[n] == (Image *) NULL)
5184         {
5185           ThrowMSLException(OptionError,"NoImagesDefined",
5186             (const char *) tag);
5187           break;
5188         }
5189       if (attributes == (const xmlChar **) NULL)
5190         break;
5191       x_resolution=DefaultResolution;
5192       y_resolution=DefaultResolution;
5193       for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5194       {
5195         keyword=(const char *) attributes[i++];
5196         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5197           msl_info->attributes[n],(const char *) attributes[i]));
5198         switch (*keyword)
5199         {
5200           case 'b':
5201           {
5202             if (LocaleCompare(keyword,"blur") == 0)
5203               {
5204                 msl_info->image[n]->blur=StringToDouble(value);
5205                 break;
5206               }
5207             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5208             break;
5209           }
5210           case 'G':
5211           case 'g':
5212           {
5213             if (LocaleCompare(keyword,"geometry") == 0)
5214               {
5215                 ssize_t
5216                   flags;
5217
5218                 flags=ParseGeometry(value,&geometry_info);
5219                 if ((flags & SigmaValue) == 0)
5220                   geometry_info.sigma*=geometry_info.rho;
5221                 x_resolution=geometry_info.rho;
5222                 y_resolution=geometry_info.sigma;
5223                 break;
5224               }
5225             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5226             break;
5227           }
5228           case 'X':
5229           case 'x':
5230           {
5231             if (LocaleCompare(keyword,"x-resolution") == 0)
5232               {
5233                 x_resolution=StringToDouble(value);
5234                 break;
5235               }
5236             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5237             break;
5238           }
5239           case 'Y':
5240           case 'y':
5241           {
5242             if (LocaleCompare(keyword,"y-resolution") == 0)
5243               {
5244                 y_resolution=StringToDouble(value);
5245                 break;
5246               }
5247             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5248             break;
5249           }
5250           default:
5251           {
5252             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5253             break;
5254           }
5255         }
5256       }
5257       /*
5258         Resample image.
5259       */
5260       {
5261         double
5262           factor;
5263
5264         Image
5265           *resample_image;
5266
5267         factor=1.0;
5268         if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5269           factor=2.54;
5270         width=(size_t) (x_resolution*msl_info->image[n]->columns/
5271           (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5272           msl_info->image[n]->x_resolution))+0.5);
5273         height=(size_t) (y_resolution*msl_info->image[n]->rows/
5274           (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5275           msl_info->image[n]->y_resolution))+0.5);
5276         resample_image=ResizeImage(msl_info->image[n],width,height,
5277           msl_info->image[n]->filter,msl_info->image[n]->blur,
5278           &msl_info->image[n]->exception);
5279         if (resample_image == (Image *) NULL)
5280           break;
5281         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5282         msl_info->image[n]=resample_image;
5283       }
5284       break;
5285     }
5286       if (LocaleCompare((const char *) tag,"resize") == 0)
5287         {
5288           double
5289             blur;
5290
5291           FilterTypes
5292             filter;
5293
5294           Image
5295             *resize_image;
5296
5297           /*
5298             Resize image.
5299           */
5300           if (msl_info->image[n] == (Image *) NULL)
5301             {
5302               ThrowMSLException(OptionError,"NoImagesDefined",
5303                 (const char *) tag);
5304               break;
5305             }
5306           filter=UndefinedFilter;
5307           blur=1.0;
5308           if (attributes != (const xmlChar **) NULL)
5309             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5310             {
5311               keyword=(const char *) attributes[i++];
5312               attribute=InterpretImageProperties(msl_info->image_info[n],
5313                 msl_info->attributes[n],(const char *) attributes[i]);
5314               CloneString(&value,attribute);
5315               switch (*keyword)
5316               {
5317                 case 'F':
5318                 case 'f':
5319                 {
5320                   if (LocaleCompare(keyword,"filter") == 0)
5321                     {
5322                       option=ParseMagickOption(MagickFilterOptions,MagickFalse,
5323                         value);
5324                       if (option < 0)
5325                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5326                           value);
5327                       filter=(FilterTypes) option;
5328                       break;
5329                     }
5330                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5331                     keyword);
5332                   break;
5333                 }
5334                 case 'G':
5335                 case 'g':
5336                 {
5337                   if (LocaleCompare(keyword,"geometry") == 0)
5338                     {
5339                       flags=ParseRegionGeometry(msl_info->image[n],value,
5340                         &geometry,&exception);
5341                       break;
5342                     }
5343                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5344                     keyword);
5345                   break;
5346                 }
5347                 case 'H':
5348                 case 'h':
5349                 {
5350                   if (LocaleCompare(keyword,"height") == 0)
5351                     {
5352                       geometry.height=StringToUnsignedLong(value);
5353                       break;
5354                     }
5355                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5356                     keyword);
5357                   break;
5358                 }
5359                 case 'S':
5360                 case 's':
5361                 {
5362                   if (LocaleCompare(keyword,"support") == 0)
5363                     {
5364                       blur=StringToDouble(value);
5365                       break;
5366                     }
5367                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5368                     keyword);
5369                   break;
5370                 }
5371                 case 'W':
5372                 case 'w':
5373                 {
5374                   if (LocaleCompare(keyword,"width") == 0)
5375                     {
5376                       geometry.width=StringToLong(value);
5377                       break;
5378                     }
5379                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5380                     keyword);
5381                   break;
5382                 }
5383                 default:
5384                 {
5385                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5386                     keyword);
5387                   break;
5388                 }
5389               }
5390             }
5391           resize_image=ResizeImage(msl_info->image[n],geometry.width,
5392             geometry.height,filter,blur,&msl_info->image[n]->exception);
5393           if (resize_image == (Image *) NULL)
5394             break;
5395           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5396           msl_info->image[n]=resize_image;
5397           break;
5398         }
5399       if (LocaleCompare((const char *) tag,"roll") == 0)
5400         {
5401           Image
5402             *roll_image;
5403
5404           /*
5405             Roll image.
5406           */
5407           if (msl_info->image[n] == (Image *) NULL)
5408             {
5409               ThrowMSLException(OptionError,"NoImagesDefined",
5410                 (const char *) tag);
5411               break;
5412             }
5413           SetGeometry(msl_info->image[n],&geometry);
5414           if (attributes != (const xmlChar **) NULL)
5415             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5416             {
5417               keyword=(const char *) attributes[i++];
5418               attribute=InterpretImageProperties(msl_info->image_info[n],
5419                 msl_info->attributes[n],(const char *) attributes[i]);
5420               CloneString(&value,attribute);
5421               switch (*keyword)
5422               {
5423                 case 'G':
5424                 case 'g':
5425                 {
5426                   if (LocaleCompare(keyword,"geometry") == 0)
5427                     {
5428                       flags=ParsePageGeometry(msl_info->image[n],value,
5429                         &geometry,&exception);
5430                       if ((flags & HeightValue) == 0)
5431                         geometry.height=geometry.width;
5432                       break;
5433                     }
5434                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5435                     keyword);
5436                   break;
5437                 }
5438                 case 'X':
5439                 case 'x':
5440                 {
5441                   if (LocaleCompare(keyword,"x") == 0)
5442                     {
5443                       geometry.x=StringToLong(value);
5444                       break;
5445                     }
5446                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5447                     keyword);
5448                   break;
5449                 }
5450                 case 'Y':
5451                 case 'y':
5452                 {
5453                   if (LocaleCompare(keyword,"y") == 0)
5454                     {
5455                       geometry.y=StringToLong(value);
5456                       break;
5457                     }
5458                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5459                     keyword);
5460                   break;
5461                 }
5462                 default:
5463                 {
5464                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5465                     keyword);
5466                   break;
5467                 }
5468               }
5469             }
5470           roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5471             &msl_info->image[n]->exception);
5472           if (roll_image == (Image *) NULL)
5473             break;
5474           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5475           msl_info->image[n]=roll_image;
5476           break;
5477         }
5478       else if (LocaleCompare((const char *) tag,"roll") == 0)
5479       {
5480         /* init the values */
5481         width=msl_info->image[n]->columns;
5482         height=msl_info->image[n]->rows;
5483         x = y = 0;
5484
5485         if (msl_info->image[n] == (Image *) NULL)
5486         {
5487           ThrowMSLException(OptionError,"NoImagesDefined",
5488             (const char *) tag);
5489           break;
5490         }
5491         if (attributes == (const xmlChar **) NULL)
5492         break;
5493         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5494         {
5495         keyword=(const char *) attributes[i++];
5496         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5497           msl_info->attributes[n],(const char *) attributes[i]));
5498         switch (*keyword)
5499         {
5500           case 'G':
5501           case 'g':
5502           {
5503           if (LocaleCompare(keyword,"geometry") == 0)
5504             {
5505             (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5506             break;
5507             }
5508           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5509           break;
5510           }
5511           case 'X':
5512           case 'x':
5513           {
5514           if (LocaleCompare(keyword,"x") == 0)
5515             {
5516             x = StringToLong( value );
5517             break;
5518             }
5519           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5520           break;
5521           }
5522           case 'Y':
5523           case 'y':
5524           {
5525           if (LocaleCompare(keyword,"y") == 0)
5526             {
5527             y = StringToLong( value );
5528             break;
5529             }
5530           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5531           break;
5532           }
5533           default:
5534           {
5535           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5536           break;
5537           }
5538         }
5539         }
5540
5541         /*
5542           process image.
5543         */
5544         {
5545         Image
5546           *newImage;
5547
5548         newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5549         if (newImage == (Image *) NULL)
5550           break;
5551         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5552         msl_info->image[n]=newImage;
5553         }
5554
5555         break;
5556       }
5557       if (LocaleCompare((const char *) tag,"rotate") == 0)
5558         {
5559           Image
5560             *rotate_image;
5561
5562           /*
5563             Rotate image.
5564           */
5565           if (msl_info->image[n] == (Image *) NULL)
5566             {
5567               ThrowMSLException(OptionError,"NoImagesDefined",
5568                 (const char *) tag);
5569               break;
5570             }
5571           if (attributes != (const xmlChar **) NULL)
5572             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5573             {
5574               keyword=(const char *) attributes[i++];
5575               attribute=InterpretImageProperties(msl_info->image_info[n],
5576                 msl_info->attributes[n],(const char *) attributes[i]);
5577               CloneString(&value,attribute);
5578               switch (*keyword)
5579               {
5580                 case 'D':
5581                 case 'd':
5582                 {
5583                   if (LocaleCompare(keyword,"degrees") == 0)
5584                     {
5585                       geometry_info.rho=StringToDouble(value);
5586                       break;
5587                     }
5588                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5589                     keyword);
5590                   break;
5591                 }
5592                 case 'G':
5593                 case 'g':
5594                 {
5595                   if (LocaleCompare(keyword,"geometry") == 0)
5596                     {
5597                       flags=ParseGeometry(value,&geometry_info);
5598                       if ((flags & SigmaValue) == 0)
5599                         geometry_info.sigma=1.0;
5600                       break;
5601                     }
5602                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5603                     keyword);
5604                   break;
5605                 }
5606                 default:
5607                 {
5608                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5609                     keyword);
5610                   break;
5611                 }
5612               }
5613             }
5614           rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5615             &msl_info->image[n]->exception);
5616           if (rotate_image == (Image *) NULL)
5617             break;
5618           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5619           msl_info->image[n]=rotate_image;
5620           break;
5621         }
5622       else if (LocaleCompare((const char *) tag,"rotate") == 0)
5623       {
5624         /* init the values */
5625         double  degrees = 0;
5626
5627         if (msl_info->image[n] == (Image *) NULL)
5628         {
5629           ThrowMSLException(OptionError,"NoImagesDefined",
5630             (const char *) tag);
5631           break;
5632         }
5633         if (attributes == (const xmlChar **) NULL)
5634           break;
5635         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5636         {
5637         keyword=(const char *) attributes[i++];
5638         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5639           msl_info->attributes[n],(const char *) attributes[i]));
5640         switch (*keyword)
5641         {
5642           case 'D':
5643           case 'd':
5644           {
5645           if (LocaleCompare(keyword,"degrees") == 0)
5646             {
5647             degrees = StringToDouble( value );
5648             break;
5649             }
5650           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5651           break;
5652           }
5653           default:
5654           {
5655           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5656           break;
5657           }
5658         }
5659         }
5660
5661         /*
5662           process image.
5663         */
5664         {
5665         Image
5666           *newImage;
5667
5668         newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5669         if (newImage == (Image *) NULL)
5670           break;
5671         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5672         msl_info->image[n]=newImage;
5673         }
5674
5675         break;
5676       }
5677       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5678     }
5679     case 'S':
5680     case 's':
5681     {
5682       if (LocaleCompare((const char *) tag,"sample") == 0)
5683         {
5684           Image
5685             *sample_image;
5686
5687           /*
5688             Sample image.
5689           */
5690           if (msl_info->image[n] == (Image *) NULL)
5691             {
5692               ThrowMSLException(OptionError,"NoImagesDefined",
5693                 (const char *) tag);
5694               break;
5695             }
5696           if (attributes != (const xmlChar **) NULL)
5697             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5698             {
5699               keyword=(const char *) attributes[i++];
5700               attribute=InterpretImageProperties(msl_info->image_info[n],
5701                 msl_info->attributes[n],(const char *) attributes[i]);
5702               CloneString(&value,attribute);
5703               switch (*keyword)
5704               {
5705                 case 'G':
5706                 case 'g':
5707                 {
5708                   if (LocaleCompare(keyword,"geometry") == 0)
5709                     {
5710                       flags=ParseRegionGeometry(msl_info->image[n],value,
5711                         &geometry,&exception);
5712                       break;
5713                     }
5714                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5715                     keyword);
5716                   break;
5717                 }
5718                 case 'H':
5719                 case 'h':
5720                 {
5721                   if (LocaleCompare(keyword,"height") == 0)
5722                     {
5723                       geometry.height=StringToUnsignedLong(value);
5724                       break;
5725                     }
5726                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5727                     keyword);
5728                   break;
5729                 }
5730                 case 'W':
5731                 case 'w':
5732                 {
5733                   if (LocaleCompare(keyword,"width") == 0)
5734                     {
5735                       geometry.width=StringToLong(value);
5736                       break;
5737                     }
5738                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5739                     keyword);
5740                   break;
5741                 }
5742                 default:
5743                 {
5744                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5745                     keyword);
5746                   break;
5747                 }
5748               }
5749             }
5750           sample_image=SampleImage(msl_info->image[n],geometry.width,
5751             geometry.height,&msl_info->image[n]->exception);
5752           if (sample_image == (Image *) NULL)
5753             break;
5754           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5755           msl_info->image[n]=sample_image;
5756           break;
5757         }
5758       if (LocaleCompare((const char *) tag,"scale") == 0)
5759         {
5760           Image
5761             *scale_image;
5762
5763           /*
5764             Scale image.
5765           */
5766           if (msl_info->image[n] == (Image *) NULL)
5767             {
5768               ThrowMSLException(OptionError,"NoImagesDefined",
5769                 (const char *) tag);
5770               break;
5771             }
5772           if (attributes != (const xmlChar **) NULL)
5773             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5774             {
5775               keyword=(const char *) attributes[i++];
5776               attribute=InterpretImageProperties(msl_info->image_info[n],
5777                 msl_info->attributes[n],(const char *) attributes[i]);
5778               CloneString(&value,attribute);
5779               switch (*keyword)
5780               {
5781                 case 'G':
5782                 case 'g':
5783                 {
5784                   if (LocaleCompare(keyword,"geometry") == 0)
5785                     {
5786                       flags=ParseRegionGeometry(msl_info->image[n],value,
5787                         &geometry,&exception);
5788                       break;
5789                     }
5790                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5791                     keyword);
5792                   break;
5793                 }
5794                 case 'H':
5795                 case 'h':
5796                 {
5797                   if (LocaleCompare(keyword,"height") == 0)
5798                     {
5799                       geometry.height=StringToUnsignedLong(value);
5800                       break;
5801                     }
5802                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5803                     keyword);
5804                   break;
5805                 }
5806                 case 'W':
5807                 case 'w':
5808                 {
5809                   if (LocaleCompare(keyword,"width") == 0)
5810                     {
5811                       geometry.width=StringToLong(value);
5812                       break;
5813                     }
5814                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5815                     keyword);
5816                   break;
5817                 }
5818                 default:
5819                 {
5820                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5821                     keyword);
5822                   break;
5823                 }
5824               }
5825             }
5826           scale_image=ScaleImage(msl_info->image[n],geometry.width,
5827             geometry.height,&msl_info->image[n]->exception);
5828           if (scale_image == (Image *) NULL)
5829             break;
5830           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5831           msl_info->image[n]=scale_image;
5832           break;
5833         }
5834       if (LocaleCompare((const char *) tag,"segment") == 0)
5835         {
5836           ColorspaceType
5837             colorspace;
5838
5839           MagickBooleanType
5840             verbose;
5841
5842           /*
5843             Segment image.
5844           */
5845           if (msl_info->image[n] == (Image *) NULL)
5846             {
5847               ThrowMSLException(OptionError,"NoImagesDefined",
5848                 (const char *) tag);
5849               break;
5850             }
5851           geometry_info.rho=1.0;
5852           geometry_info.sigma=1.5;
5853           colorspace=RGBColorspace;
5854           verbose=MagickFalse;
5855           if (attributes != (const xmlChar **) NULL)
5856             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5857             {
5858               keyword=(const char *) attributes[i++];
5859               attribute=InterpretImageProperties(msl_info->image_info[n],
5860                 msl_info->attributes[n],(const char *) attributes[i]);
5861               CloneString(&value,attribute);
5862               switch (*keyword)
5863               {
5864                 case 'C':
5865                 case 'c':
5866                 {
5867                   if (LocaleCompare(keyword,"cluster-threshold") == 0)
5868                     {
5869                       geometry_info.rho=StringToDouble(value);
5870                       break;
5871                     }
5872                   if (LocaleCompare(keyword,"colorspace") == 0)
5873                     {
5874                       option=ParseMagickOption(MagickColorspaceOptions,
5875                         MagickFalse,value);
5876                       if (option < 0)
5877                         ThrowMSLException(OptionError,
5878                           "UnrecognizedColorspaceType",value);
5879                       colorspace=(ColorspaceType) option;
5880                       break;
5881                     }
5882                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5883                     keyword);
5884                   break;
5885                 }
5886                 case 'G':
5887                 case 'g':
5888                 {
5889                   if (LocaleCompare(keyword,"geometry") == 0)
5890                     {
5891                       flags=ParseGeometry(value,&geometry_info);
5892                       if ((flags & SigmaValue) == 0)
5893                         geometry_info.sigma=1.5;
5894                       break;
5895                     }
5896                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5897                     keyword);
5898                   break;
5899                 }
5900                 case 'S':
5901                 case 's':
5902                 {
5903                   if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5904                     {
5905                       geometry_info.sigma=StringToDouble(value);
5906                       break;
5907                     }
5908                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5909                     keyword);
5910                   break;
5911                 }
5912                 default:
5913                 {
5914                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5915                     keyword);
5916                   break;
5917                 }
5918               }
5919             }
5920           (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5921             geometry_info.rho,geometry_info.sigma);
5922           break;
5923         }
5924       else if (LocaleCompare((const char *) tag, "set") == 0)
5925       {
5926         if (msl_info->image[n] == (Image *) NULL)
5927         {
5928           ThrowMSLException(OptionError,"NoImagesDefined",
5929             (const char *) tag);
5930           break;
5931         }
5932
5933         if (attributes == (const xmlChar **) NULL)
5934           break;
5935         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5936         {
5937           keyword=(const char *) attributes[i++];
5938           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5939             msl_info->attributes[n],(const char *) attributes[i]));
5940           switch (*keyword)
5941           {
5942             case 'C':
5943             case 'c':
5944             {
5945               if (LocaleCompare(keyword,"clip-mask") == 0)
5946                 {
5947                   for (j=0; j < msl_info->n; j++)
5948                   {
5949                     const char
5950                       *property;
5951
5952                     property=GetImageProperty(msl_info->attributes[j],"id");
5953                     if (LocaleCompare(property,value) == 0)
5954                       {
5955                         SetImageMask(msl_info->image[n],msl_info->image[j]);
5956                         break;
5957                       }
5958                   }
5959                   break;
5960                 }
5961               if (LocaleCompare(keyword,"clip-path") == 0)
5962                 {
5963                   for (j=0; j < msl_info->n; j++)
5964                   {
5965                     const char
5966                       *property;
5967
5968                     property=GetImageProperty(msl_info->attributes[j],"id");
5969                     if (LocaleCompare(property,value) == 0)
5970                       {
5971                         SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5972                         break;
5973                       }
5974                   }
5975                   break;
5976                 }
5977               if (LocaleCompare(keyword,"colorspace") == 0)
5978                 {
5979                   ssize_t
5980                     colorspace;
5981
5982                   colorspace=(ColorspaceType) ParseMagickOption(
5983                     MagickColorspaceOptions,MagickFalse,value);
5984                   if (colorspace < 0)
5985                     ThrowMSLException(OptionError,"UnrecognizedColorspace",
5986                       value);
5987                   (void) TransformImageColorspace(msl_info->image[n],
5988                     (ColorspaceType) colorspace);
5989                   break;
5990                 }
5991               (void) SetMSLAttributes(msl_info,keyword,value);
5992               break;
5993             }
5994             case 'D':
5995             case 'd':
5996             {
5997               if (LocaleCompare(keyword,"density") == 0)
5998                 {
5999                   flags=ParseGeometry(value,&geometry_info);
6000                   msl_info->image[n]->x_resolution=geometry_info.rho;
6001                   msl_info->image[n]->y_resolution=geometry_info.sigma;
6002                   if ((flags & SigmaValue) == 0)
6003                     msl_info->image[n]->y_resolution=
6004                       msl_info->image[n]->x_resolution;
6005                   break;
6006                 }
6007               (void) SetMSLAttributes(msl_info,keyword,value);
6008               break;
6009             }
6010             case 'O':
6011             case 'o':
6012             {
6013               if (LocaleCompare(keyword, "opacity") == 0)
6014                 {
6015                   ssize_t  opac = OpaqueOpacity,
6016                   len = (ssize_t) strlen( value );
6017
6018                   if (value[len-1] == '%') {
6019                     char  tmp[100];
6020                     (void) CopyMagickString(tmp,value,len);
6021                     opac = StringToLong( tmp );
6022                     opac = (int)(QuantumRange * ((float)opac/100));
6023                   } else
6024                     opac = StringToLong( value );
6025                   (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6026                   break;
6027               }
6028               (void) SetMSLAttributes(msl_info,keyword,value);
6029               break;
6030             }
6031             case 'P':
6032             case 'p':
6033             {
6034               if (LocaleCompare(keyword, "page") == 0)
6035               {
6036                 char
6037                   page[MaxTextExtent];
6038
6039                 const char
6040                   *image_option;
6041
6042                 MagickStatusType
6043                   flags;
6044
6045                 RectangleInfo
6046                   geometry;
6047
6048                 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6049                 image_option=GetImageOption(msl_info->image_info[n],"page");
6050                 if (image_option != (const char *) NULL)
6051                   flags=ParseAbsoluteGeometry(image_option,&geometry);
6052                 flags=ParseAbsoluteGeometry(value,&geometry);
6053                 (void) FormatMagickString(page,MaxTextExtent,"%.20gx%.20g",
6054                   (double) geometry.width,(double) geometry.height);
6055                 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
6056                   (void) FormatMagickString(page,MaxTextExtent,
6057                     "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6058                     (double) geometry.height,(double) geometry.x,(double)
6059                     geometry.y);
6060                 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6061                 msl_info->image_info[n]->page=GetPageGeometry(page);
6062                 break;
6063               }
6064               (void) SetMSLAttributes(msl_info,keyword,value);
6065               break;
6066             }
6067             default:
6068             {
6069               (void) SetMSLAttributes(msl_info,keyword,value);
6070               break;
6071             }
6072           }
6073         }
6074         break;
6075       }
6076       if (LocaleCompare((const char *) tag,"shade") == 0)
6077         {
6078           Image
6079             *shade_image;
6080
6081           MagickBooleanType
6082             gray;
6083
6084           /*
6085             Shade image.
6086           */
6087           if (msl_info->image[n] == (Image *) NULL)
6088             {
6089               ThrowMSLException(OptionError,"NoImagesDefined",
6090                 (const char *) tag);
6091               break;
6092             }
6093           gray=MagickFalse;
6094           if (attributes != (const xmlChar **) NULL)
6095             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6096             {
6097               keyword=(const char *) attributes[i++];
6098               attribute=InterpretImageProperties(msl_info->image_info[n],
6099                 msl_info->attributes[n],(const char *) attributes[i]);
6100               CloneString(&value,attribute);
6101               switch (*keyword)
6102               {
6103                 case 'A':
6104                 case 'a':
6105                 {
6106                   if (LocaleCompare(keyword,"azimuth") == 0)
6107                     {
6108                       geometry_info.rho=StringToDouble(value);
6109                       break;
6110                     }
6111                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6112                     keyword);
6113                   break;
6114                 }
6115                 case 'E':
6116                 case 'e':
6117                 {
6118                   if (LocaleCompare(keyword,"elevation") == 0)
6119                     {
6120                       geometry_info.sigma=StringToDouble(value);
6121                       break;
6122                     }
6123                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6124                     keyword);
6125                   break;
6126                 }
6127                 case 'G':
6128                 case 'g':
6129                 {
6130                   if (LocaleCompare(keyword,"geometry") == 0)
6131                     {
6132                       flags=ParseGeometry(value,&geometry_info);
6133                       if ((flags & SigmaValue) == 0)
6134                         geometry_info.sigma=1.0;
6135                       break;
6136                     }
6137                   if (LocaleCompare(keyword,"gray") == 0)
6138                     {
6139                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
6140                         value);
6141                       if (option < 0)
6142                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6143                           value);
6144                       gray=(MagickBooleanType) option;
6145                       break;
6146                     }
6147                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6148                     keyword);
6149                   break;
6150                 }
6151                 default:
6152                 {
6153                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6154                     keyword);
6155                   break;
6156                 }
6157               }
6158             }
6159           shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6160             geometry_info.sigma,&msl_info->image[n]->exception);
6161           if (shade_image == (Image *) NULL)
6162             break;
6163           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6164           msl_info->image[n]=shade_image;
6165           break;
6166         }
6167       if (LocaleCompare((const char *) tag,"shadow") == 0)
6168         {
6169           Image
6170             *shadow_image;
6171
6172           /*
6173             Shear image.
6174           */
6175           if (msl_info->image[n] == (Image *) NULL)
6176             {
6177               ThrowMSLException(OptionError,"NoImagesDefined",
6178                 (const char *) tag);
6179               break;
6180             }
6181           if (attributes != (const xmlChar **) NULL)
6182             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6183             {
6184               keyword=(const char *) attributes[i++];
6185               attribute=InterpretImageProperties(msl_info->image_info[n],
6186                 msl_info->attributes[n],(const char *) attributes[i]);
6187               CloneString(&value,attribute);
6188               switch (*keyword)
6189               {
6190                 case 'G':
6191                 case 'g':
6192                 {
6193                   if (LocaleCompare(keyword,"geometry") == 0)
6194                     {
6195                       flags=ParseGeometry(value,&geometry_info);
6196                       if ((flags & SigmaValue) == 0)
6197                         geometry_info.sigma=1.0;
6198                       break;
6199                     }
6200                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6201                     keyword);
6202                   break;
6203                 }
6204                 case 'O':
6205                 case 'o':
6206                 {
6207                   if (LocaleCompare(keyword,"opacity") == 0)
6208                     {
6209                       geometry_info.rho=StringToLong(value);
6210                       break;
6211                     }
6212                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6213                     keyword);
6214                   break;
6215                 }
6216                 case 'S':
6217                 case 's':
6218                 {
6219                   if (LocaleCompare(keyword,"sigma") == 0)
6220                     {
6221                       geometry_info.sigma=StringToLong(value);
6222                       break;
6223                     }
6224                   break;
6225                 }
6226                 case 'X':
6227                 case 'x':
6228                 {
6229                   if (LocaleCompare(keyword,"x") == 0)
6230                     {
6231                       geometry_info.xi=StringToDouble(value);
6232                       break;
6233                     }
6234                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6235                     keyword);
6236                   break;
6237                 }
6238                 case 'Y':
6239                 case 'y':
6240                 {
6241                   if (LocaleCompare(keyword,"y") == 0)
6242                     {
6243                       geometry_info.psi=StringToLong(value);
6244                       break;
6245                     }
6246                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6247                     keyword);
6248                   break;
6249                 }
6250                 default:
6251                 {
6252                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6253                     keyword);
6254                   break;
6255                 }
6256               }
6257             }
6258           shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
6259             geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
6260             ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
6261           if (shadow_image == (Image *) NULL)
6262             break;
6263           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6264           msl_info->image[n]=shadow_image;
6265           break;
6266         }
6267       if (LocaleCompare((const char *) tag,"sharpen") == 0)
6268       {
6269         double  radius = 0.0,
6270             sigma = 1.0;
6271
6272         if (msl_info->image[n] == (Image *) NULL)
6273           {
6274             ThrowMSLException(OptionError,"NoImagesDefined",
6275               (const char *) tag);
6276             break;
6277           }
6278         /*
6279         NOTE: sharpen can have no attributes, since we use all the defaults!
6280         */
6281         if (attributes != (const xmlChar **) NULL)
6282         {
6283           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6284           {
6285           keyword=(const char *) attributes[i++];
6286           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6287             msl_info->attributes[n],(const char *) attributes[i]));
6288           switch (*keyword)
6289           {
6290             case 'R':
6291             case 'r':
6292             {
6293               if (LocaleCompare(keyword, "radius") == 0)
6294               {
6295                 radius = StringToDouble( value );
6296                 break;
6297               }
6298               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6299               break;
6300             }
6301             case 'S':
6302             case 's':
6303             {
6304               if (LocaleCompare(keyword,"sigma") == 0)
6305               {
6306                 sigma = StringToLong( value );
6307                 break;
6308               }
6309               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6310               break;
6311             }
6312             default:
6313             {
6314               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6315               break;
6316             }
6317           }
6318           }
6319         }
6320
6321         /*
6322           sharpen image.
6323         */
6324         {
6325         Image
6326           *newImage;
6327
6328         newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6329         if (newImage == (Image *) NULL)
6330           break;
6331         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6332         msl_info->image[n]=newImage;
6333         break;
6334         }
6335       }
6336       else if (LocaleCompare((const char *) tag,"shave") == 0)
6337       {
6338         /* init the values */
6339         width = height = 0;
6340         x = y = 0;
6341
6342         if (msl_info->image[n] == (Image *) NULL)
6343         {
6344           ThrowMSLException(OptionError,"NoImagesDefined",
6345             (const char *) tag);
6346           break;
6347         }
6348         if (attributes == (const xmlChar **) NULL)
6349         break;
6350         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6351         {
6352         keyword=(const char *) attributes[i++];
6353         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6354           msl_info->attributes[n],(const char *) attributes[i]));
6355         switch (*keyword)
6356         {
6357           case 'G':
6358           case 'g':
6359           {
6360           if (LocaleCompare(keyword,"geometry") == 0)
6361             {
6362             (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6363             break;
6364             }
6365           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6366           break;
6367           }
6368           case 'H':
6369           case 'h':
6370           {
6371           if (LocaleCompare(keyword,"height") == 0)
6372             {
6373             height = StringToLong( value );
6374             break;
6375             }
6376           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6377           break;
6378           }
6379           case 'W':
6380           case 'w':
6381           {
6382           if (LocaleCompare(keyword,"width") == 0)
6383             {
6384             width = StringToLong( value );
6385             break;
6386             }
6387           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6388           break;
6389           }
6390           default:
6391           {
6392           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6393           break;
6394           }
6395         }
6396         }
6397
6398         /*
6399           process image.
6400         */
6401         {
6402         Image
6403           *newImage;
6404         RectangleInfo
6405           rectInfo;
6406
6407         rectInfo.height = height;
6408         rectInfo.width = width;
6409         rectInfo.x = x;
6410         rectInfo.y = y;
6411
6412
6413         newImage=ShaveImage(msl_info->image[n], &rectInfo,
6414           &msl_info->image[n]->exception);
6415         if (newImage == (Image *) NULL)
6416           break;
6417         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6418         msl_info->image[n]=newImage;
6419         }
6420
6421         break;
6422       }
6423       if (LocaleCompare((const char *) tag,"shear") == 0)
6424         {
6425           Image
6426             *shear_image;
6427
6428           /*
6429             Shear image.
6430           */
6431           if (msl_info->image[n] == (Image *) NULL)
6432             {
6433               ThrowMSLException(OptionError,"NoImagesDefined",
6434                 (const char *) tag);
6435               break;
6436             }
6437           if (attributes != (const xmlChar **) NULL)
6438             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6439             {
6440               keyword=(const char *) attributes[i++];
6441               attribute=InterpretImageProperties(msl_info->image_info[n],
6442                 msl_info->attributes[n],(const char *) attributes[i]);
6443               CloneString(&value,attribute);
6444               switch (*keyword)
6445               {
6446                 case 'F':
6447                 case 'f':
6448                 {
6449                   if (LocaleCompare(keyword, "fill") == 0)
6450                     {
6451                       (void) QueryColorDatabase(value,
6452                         &msl_info->image[n]->background_color,&exception);
6453                       break;
6454                     }
6455                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6456                     keyword);
6457                   break;
6458                 }
6459                 case 'G':
6460                 case 'g':
6461                 {
6462                   if (LocaleCompare(keyword,"geometry") == 0)
6463                     {
6464                       flags=ParseGeometry(value,&geometry_info);
6465                       if ((flags & SigmaValue) == 0)
6466                         geometry_info.sigma=1.0;
6467                       break;
6468                     }
6469                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6470                     keyword);
6471                   break;
6472                 }
6473                 case 'X':
6474                 case 'x':
6475                 {
6476                   if (LocaleCompare(keyword,"x") == 0)
6477                     {
6478                       geometry_info.rho=StringToDouble(value);
6479                       break;
6480                     }
6481                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6482                     keyword);
6483                   break;
6484                 }
6485                 case 'Y':
6486                 case 'y':
6487                 {
6488                   if (LocaleCompare(keyword,"y") == 0)
6489                     {
6490                       geometry_info.sigma=StringToLong(value);
6491                       break;
6492                     }
6493                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6494                     keyword);
6495                   break;
6496                 }
6497                 default:
6498                 {
6499                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6500                     keyword);
6501                   break;
6502                 }
6503               }
6504             }
6505           shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6506             geometry_info.sigma,&msl_info->image[n]->exception);
6507           if (shear_image == (Image *) NULL)
6508             break;
6509           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6510           msl_info->image[n]=shear_image;
6511           break;
6512         }
6513       if (LocaleCompare((const char *) tag,"signature") == 0)
6514         {
6515           /*
6516             Signature image.
6517           */
6518           if (msl_info->image[n] == (Image *) NULL)
6519             {
6520               ThrowMSLException(OptionError,"NoImagesDefined",
6521                 (const char *) tag);
6522               break;
6523             }
6524           if (attributes != (const xmlChar **) NULL)
6525             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6526             {
6527               keyword=(const char *) attributes[i++];
6528               attribute=InterpretImageProperties(msl_info->image_info[n],
6529                 msl_info->attributes[n],(const char *) attributes[i]);
6530               CloneString(&value,attribute);
6531               switch (*keyword)
6532               {
6533                 default:
6534                 {
6535                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6536                     keyword);
6537                   break;
6538                 }
6539               }
6540             }
6541           (void) SignatureImage(msl_info->image[n]);
6542           break;
6543         }
6544       if (LocaleCompare((const char *) tag,"solarize") == 0)
6545         {
6546           /*
6547             Solarize image.
6548           */
6549           if (msl_info->image[n] == (Image *) NULL)
6550             {
6551               ThrowMSLException(OptionError,"NoImagesDefined",
6552                 (const char *) tag);
6553               break;
6554             }
6555           geometry_info.rho=QuantumRange/2.0;
6556           if (attributes != (const xmlChar **) NULL)
6557             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6558             {
6559               keyword=(const char *) attributes[i++];
6560               attribute=InterpretImageProperties(msl_info->image_info[n],
6561                 msl_info->attributes[n],(const char *) attributes[i]);
6562               CloneString(&value,attribute);
6563               switch (*keyword)
6564               {
6565                 case 'G':
6566                 case 'g':
6567                 {
6568                   if (LocaleCompare(keyword,"geometry") == 0)
6569                     {
6570                       flags=ParseGeometry(value,&geometry_info);
6571                       break;
6572                     }
6573                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6574                     keyword);
6575                   break;
6576                 }
6577                 case 'T':
6578                 case 't':
6579                 {
6580                   if (LocaleCompare(keyword,"threshold") == 0)
6581                     {
6582                       geometry_info.rho=StringToDouble(value);
6583                       break;
6584                     }
6585                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6586                     keyword);
6587                   break;
6588                 }
6589                 default:
6590                 {
6591                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6592                     keyword);
6593                   break;
6594                 }
6595               }
6596             }
6597           (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6598           break;
6599         }
6600       if (LocaleCompare((const char *) tag,"spread") == 0)
6601         {
6602           Image
6603             *spread_image;
6604
6605           /*
6606             Spread image.
6607           */
6608           if (msl_info->image[n] == (Image *) NULL)
6609             {
6610               ThrowMSLException(OptionError,"NoImagesDefined",
6611                 (const char *) tag);
6612               break;
6613             }
6614           if (attributes != (const xmlChar **) NULL)
6615             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6616             {
6617               keyword=(const char *) attributes[i++];
6618               attribute=InterpretImageProperties(msl_info->image_info[n],
6619                 msl_info->attributes[n],(const char *) attributes[i]);
6620               CloneString(&value,attribute);
6621               switch (*keyword)
6622               {
6623                 case 'G':
6624                 case 'g':
6625                 {
6626                   if (LocaleCompare(keyword,"geometry") == 0)
6627                     {
6628                       flags=ParseGeometry(value,&geometry_info);
6629                       if ((flags & SigmaValue) == 0)
6630                         geometry_info.sigma=1.0;
6631                       break;
6632                     }
6633                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6634                     keyword);
6635                   break;
6636                 }
6637                 case 'R':
6638                 case 'r':
6639                 {
6640                   if (LocaleCompare(keyword,"radius") == 0)
6641                     {
6642                       geometry_info.rho=StringToDouble(value);
6643                       break;
6644                     }
6645                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6646                     keyword);
6647                   break;
6648                 }
6649                 default:
6650                 {
6651                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6652                     keyword);
6653                   break;
6654                 }
6655               }
6656             }
6657           spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6658             &msl_info->image[n]->exception);
6659           if (spread_image == (Image *) NULL)
6660             break;
6661           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6662           msl_info->image[n]=spread_image;
6663           break;
6664         }
6665       else if (LocaleCompare((const char *) tag,"stegano") == 0)
6666       {
6667         Image *
6668           watermark = (Image*)NULL;
6669
6670         if (msl_info->image[n] == (Image *) NULL)
6671           {
6672             ThrowMSLException(OptionError,"NoImagesDefined",
6673               (const char *) tag);
6674             break;
6675           }
6676         if (attributes == (const xmlChar **) NULL)
6677         break;
6678         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6679         {
6680         keyword=(const char *) attributes[i++];
6681         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6682           msl_info->attributes[n],(const char *) attributes[i]));
6683         switch (*keyword)
6684         {
6685           case 'I':
6686           case 'i':
6687           {
6688           if (LocaleCompare(keyword,"image") == 0)
6689             {
6690             for (j=0; j<msl_info->n;j++)
6691             {
6692               const char *
6693                 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6694               if (theAttr && LocaleCompare(theAttr, value) == 0)
6695               {
6696                 watermark = msl_info->image[j];
6697                 break;
6698               }
6699             }
6700             break;
6701             }
6702           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6703           break;
6704           }
6705           default:
6706           {
6707           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6708           break;
6709           }
6710         }
6711         }
6712
6713         /*
6714           process image.
6715         */
6716         if ( watermark != (Image*) NULL )
6717         {
6718         Image
6719           *newImage;
6720
6721         newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6722         if (newImage == (Image *) NULL)
6723           break;
6724         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6725         msl_info->image[n]=newImage;
6726         break;
6727         } else
6728           ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6729       }
6730       else if (LocaleCompare((const char *) tag,"stereo") == 0)
6731       {
6732         Image *
6733           stereoImage = (Image*)NULL;
6734
6735         if (msl_info->image[n] == (Image *) NULL)
6736           {
6737             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6738             break;
6739           }
6740         if (attributes == (const xmlChar **) NULL)
6741         break;
6742         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6743         {
6744         keyword=(const char *) attributes[i++];
6745         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6746           msl_info->attributes[n],(const char *) attributes[i]));
6747         switch (*keyword)
6748         {
6749           case 'I':
6750           case 'i':
6751           {
6752           if (LocaleCompare(keyword,"image") == 0)
6753             {
6754             for (j=0; j<msl_info->n;j++)
6755             {
6756               const char *
6757                 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6758               if (theAttr && LocaleCompare(theAttr, value) == 0)
6759               {
6760                 stereoImage = msl_info->image[j];
6761                 break;
6762               }
6763             }
6764             break;
6765             }
6766           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6767           break;
6768           }
6769           default:
6770           {
6771           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6772           break;
6773           }
6774         }
6775         }
6776
6777         /*
6778           process image.
6779         */
6780         if ( stereoImage != (Image*) NULL )
6781         {
6782         Image
6783           *newImage;
6784
6785         newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6786         if (newImage == (Image *) NULL)
6787           break;
6788         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6789         msl_info->image[n]=newImage;
6790         break;
6791         } else
6792           ThrowMSLException(OptionError,"Missing stereo image",keyword);
6793       }
6794       if (LocaleCompare((const char *) tag,"swap") == 0)
6795         {
6796           Image
6797             *p,
6798             *q,
6799             *swap;
6800
6801           ssize_t
6802             index,
6803             swap_index;
6804
6805           if (msl_info->image[n] == (Image *) NULL)
6806             {
6807               ThrowMSLException(OptionError,"NoImagesDefined",
6808                 (const char *) tag);
6809               break;
6810             }
6811           index=(-1);
6812           swap_index=(-2);
6813           if (attributes != (const xmlChar **) NULL)
6814             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6815             {
6816               keyword=(const char *) attributes[i++];
6817               attribute=InterpretImageProperties(msl_info->image_info[n],
6818                 msl_info->attributes[n],(const char *) attributes[i]);
6819               CloneString(&value,attribute);
6820               switch (*keyword)
6821               {
6822                 case 'G':
6823                 case 'g':
6824                 {
6825                   if (LocaleCompare(keyword,"indexes") == 0)
6826                     {
6827                       flags=ParseGeometry(value,&geometry_info);
6828                       index=(ssize_t) geometry_info.rho;
6829                       if ((flags & SigmaValue) == 0)
6830                         swap_index=(ssize_t) geometry_info.sigma;
6831                       break;
6832                     }
6833                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6834                     keyword);
6835                   break;
6836                 }
6837                 default:
6838                 {
6839                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6840                     keyword);
6841                   break;
6842                 }
6843               }
6844             }
6845           /*
6846             Swap images.
6847           */
6848           p=GetImageFromList(msl_info->image[n],index);
6849           q=GetImageFromList(msl_info->image[n],swap_index);
6850           if ((p == (Image *) NULL) || (q == (Image *) NULL))
6851             {
6852               ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
6853               break;
6854             }
6855           swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6856           ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6857           ReplaceImageInList(&q,swap);
6858           msl_info->image[n]=GetFirstImageInList(q);
6859           break;
6860         }
6861       if (LocaleCompare((const char *) tag,"swirl") == 0)
6862         {
6863           Image
6864             *swirl_image;
6865
6866           /*
6867             Swirl image.
6868           */
6869           if (msl_info->image[n] == (Image *) NULL)
6870             {
6871               ThrowMSLException(OptionError,"NoImagesDefined",
6872                 (const char *) tag);
6873               break;
6874             }
6875           if (attributes != (const xmlChar **) NULL)
6876             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6877             {
6878               keyword=(const char *) attributes[i++];
6879               attribute=InterpretImageProperties(msl_info->image_info[n],
6880                 msl_info->attributes[n],(const char *) attributes[i]);
6881               CloneString(&value,attribute);
6882               switch (*keyword)
6883               {
6884                 case 'D':
6885                 case 'd':
6886                 {
6887                   if (LocaleCompare(keyword,"degrees") == 0)
6888                     {
6889                       geometry_info.rho=StringToDouble(value);
6890                       break;
6891                     }
6892                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6893                     keyword);
6894                   break;
6895                 }
6896                 case 'G':
6897                 case 'g':
6898                 {
6899                   if (LocaleCompare(keyword,"geometry") == 0)
6900                     {
6901                       flags=ParseGeometry(value,&geometry_info);
6902                       if ((flags & SigmaValue) == 0)
6903                         geometry_info.sigma=1.0;
6904                       break;
6905                     }
6906                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6907                     keyword);
6908                   break;
6909                 }
6910                 default:
6911                 {
6912                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6913                     keyword);
6914                   break;
6915                 }
6916               }
6917             }
6918           swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6919             &msl_info->image[n]->exception);
6920           if (swirl_image == (Image *) NULL)
6921             break;
6922           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6923           msl_info->image[n]=swirl_image;
6924           break;
6925         }
6926       if (LocaleCompare((const char *) tag,"sync") == 0)
6927         {
6928           /*
6929             Sync image.
6930           */
6931           if (msl_info->image[n] == (Image *) NULL)
6932             {
6933               ThrowMSLException(OptionError,"NoImagesDefined",
6934                 (const char *) tag);
6935               break;
6936             }
6937           if (attributes != (const xmlChar **) NULL)
6938             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6939             {
6940               keyword=(const char *) attributes[i++];
6941               attribute=InterpretImageProperties(msl_info->image_info[n],
6942                 msl_info->attributes[n],(const char *) attributes[i]);
6943               CloneString(&value,attribute);
6944               switch (*keyword)
6945               {
6946                 default:
6947                 {
6948                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6949                     keyword);
6950                   break;
6951                 }
6952               }
6953             }
6954           (void) SyncImage(msl_info->image[n]);
6955           break;
6956         }
6957       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6958     }
6959     case 'T':
6960     case 't':
6961     {
6962       if (LocaleCompare((const char *) tag,"map") == 0)
6963         {
6964           Image
6965             *texture_image;
6966
6967           /*
6968             Texture image.
6969           */
6970           if (msl_info->image[n] == (Image *) NULL)
6971             {
6972               ThrowMSLException(OptionError,"NoImagesDefined",
6973                 (const char *) tag);
6974               break;
6975             }
6976           texture_image=NewImageList();
6977           if (attributes != (const xmlChar **) NULL)
6978             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6979             {
6980               keyword=(const char *) attributes[i++];
6981               attribute=InterpretImageProperties(msl_info->image_info[n],
6982                 msl_info->attributes[n],(const char *) attributes[i]);
6983               CloneString(&value,attribute);
6984               switch (*keyword)
6985               {
6986                 case 'I':
6987                 case 'i':
6988                 {
6989                   if (LocaleCompare(keyword,"image") == 0)
6990                     for (j=0; j < msl_info->n; j++)
6991                     {
6992                       const char
6993                         *attribute;
6994
6995                       attribute=GetImageProperty(msl_info->attributes[j],"id");
6996                       if ((attribute != (const char *) NULL)  &&
6997                           (LocaleCompare(attribute,value) == 0))
6998                         {
6999                           texture_image=CloneImage(msl_info->image[j],0,0,
7000                             MagickFalse,&exception);
7001                           break;
7002                         }
7003                     }
7004                   break;
7005                 }
7006                 default:
7007                 {
7008                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
7009                     keyword);
7010                   break;
7011                 }
7012               }
7013             }
7014           (void) TextureImage(msl_info->image[n],texture_image);
7015           texture_image=DestroyImage(texture_image);
7016           break;
7017         }
7018       else if (LocaleCompare((const char *) tag,"threshold") == 0)
7019       {
7020         /* init the values */
7021         double  threshold = 0;
7022
7023         if (msl_info->image[n] == (Image *) NULL)
7024           {
7025             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7026             break;
7027           }
7028         if (attributes == (const xmlChar **) NULL)
7029         break;
7030         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7031         {
7032         keyword=(const char *) attributes[i++];
7033         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7034           msl_info->attributes[n],(const char *) attributes[i]));
7035         switch (*keyword)
7036         {
7037           case 'T':
7038           case 't':
7039           {
7040           if (LocaleCompare(keyword,"threshold") == 0)
7041             {
7042             threshold = StringToDouble( value );
7043             break;
7044             }
7045           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7046           break;
7047           }
7048           default:
7049           {
7050           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7051           break;
7052           }
7053         }
7054         }
7055
7056         /*
7057           process image.
7058         */
7059         {
7060         BilevelImageChannel(msl_info->image[n],
7061           (ChannelType) ((ssize_t) (AllChannels &~ (ssize_t) OpacityChannel)),
7062           threshold);
7063         break;
7064         }
7065       }
7066       else if (LocaleCompare((const char *) tag, "transparent") == 0)
7067       {
7068         if (msl_info->image[n] == (Image *) NULL)
7069           {
7070             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7071             break;
7072           }
7073         if (attributes == (const xmlChar **) NULL)
7074           break;
7075         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7076         {
7077           keyword=(const char *) attributes[i++];
7078           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7079             msl_info->attributes[n],(const char *) attributes[i]));
7080           switch (*keyword)
7081           {
7082             case 'C':
7083             case 'c':
7084             {
7085               if (LocaleCompare(keyword,"color") == 0)
7086               {
7087                 MagickPixelPacket
7088                   target;
7089
7090                 (void) QueryMagickColor(value,&target,&exception);
7091                 (void) TransparentPaintImage(msl_info->image[n],&target,
7092                   TransparentOpacity,MagickFalse);
7093                 break;
7094               }
7095               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7096               break;
7097             }
7098             default:
7099             {
7100               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7101             break;
7102             }
7103           }
7104         }
7105         break;
7106       }
7107       else if (LocaleCompare((const char *) tag, "trim") == 0)
7108       {
7109         if (msl_info->image[n] == (Image *) NULL)
7110           {
7111             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7112             break;
7113           }
7114
7115         /* no attributes here */
7116
7117         /* process the image */
7118         {
7119           Image
7120             *newImage;
7121           RectangleInfo
7122             rectInfo;
7123
7124           /* all zeros on a crop == trim edges! */
7125           rectInfo.height = rectInfo.width = 0;
7126           rectInfo.x =  rectInfo.y = 0;
7127
7128           newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7129           if (newImage == (Image *) NULL)
7130             break;
7131           msl_info->image[n]=DestroyImage(msl_info->image[n]);
7132           msl_info->image[n]=newImage;
7133           break;
7134         }
7135       }
7136       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7137     }
7138     case 'W':
7139     case 'w':
7140     {
7141       if (LocaleCompare((const char *) tag,"write") == 0)
7142         {
7143           if (msl_info->image[n] == (Image *) NULL)
7144             {
7145               ThrowMSLException(OptionError,"NoImagesDefined",
7146                 (const char *) tag);
7147               break;
7148             }
7149           if (attributes == (const xmlChar **) NULL)
7150             break;
7151           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7152           {
7153             keyword=(const char *) attributes[i++];
7154             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7155               msl_info->attributes[n],(const char *) attributes[i]));
7156             switch (*keyword)
7157             {
7158               case 'F':
7159               case 'f':
7160               {
7161                 if (LocaleCompare(keyword,"filename") == 0)
7162                   {
7163                     (void) CopyMagickString(msl_info->image[n]->filename,value,
7164                       MaxTextExtent);
7165                     break;
7166                   }
7167                 (void) SetMSLAttributes(msl_info,keyword,value);
7168               }
7169               default:
7170               {
7171                 (void) SetMSLAttributes(msl_info,keyword,value);
7172                 break;
7173               }
7174             }
7175           }
7176
7177           /* process */
7178           {
7179             (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7180             break;
7181           }
7182         }
7183       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7184     }
7185     default:
7186     {
7187       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7188       break;
7189     }
7190   }
7191   if ( value != NULL )
7192     value=DestroyString(value);
7193   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  )");
7194 }
7195
7196 static void MSLEndElement(void *context,const xmlChar *tag)
7197 {
7198   ssize_t
7199     n;
7200
7201   MSLInfo
7202     *msl_info;
7203
7204   /*
7205     Called when the end of an element has been detected.
7206   */
7207   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.endElement(%s)",
7208     tag);
7209   msl_info=(MSLInfo *) context;
7210   n=msl_info->n;
7211   switch (*tag)
7212   {
7213     case 'C':
7214     case 'c':
7215     {
7216       if (LocaleCompare((const char *) tag,"comment") == 0 )
7217         {
7218           (void) DeleteImageProperty(msl_info->image[n],"comment");
7219           if (msl_info->content == (char *) NULL)
7220             break;
7221           StripString(msl_info->content);
7222           (void) SetImageProperty(msl_info->image[n],"comment",
7223             msl_info->content);
7224           break;
7225         }
7226       break;
7227     }
7228     case 'G':
7229     case 'g':
7230     {
7231       if (LocaleCompare((const char *) tag, "group") == 0 )
7232       {
7233         if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7234         {
7235           ssize_t  i = (ssize_t)
7236             (msl_info->group_info[msl_info->number_groups-1].numImages);
7237           while ( i-- )
7238           {
7239             if (msl_info->image[msl_info->n] != (Image *) NULL)
7240               msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7241             msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7242             msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7243             msl_info->n--;
7244           }
7245         }
7246         msl_info->number_groups--;
7247       }
7248       break;
7249     }
7250     case 'I':
7251     case 'i':
7252     {
7253       if (LocaleCompare((const char *) tag, "image") == 0)
7254         MSLPopImage(msl_info);
7255        break;
7256     }
7257     case 'L':
7258     case 'l':
7259     {
7260       if (LocaleCompare((const char *) tag,"label") == 0 )
7261         {
7262           (void) DeleteImageProperty(msl_info->image[n],"label");
7263           if (msl_info->content == (char *) NULL)
7264             break;
7265           StripString(msl_info->content);
7266           (void) SetImageProperty(msl_info->image[n],"label",
7267             msl_info->content);
7268           break;
7269         }
7270       break;
7271     }
7272     case 'M':
7273     case 'm':
7274     {
7275       if (LocaleCompare((const char *) tag, "msl") == 0 )
7276       {
7277         /*
7278           This our base element.
7279             at the moment we don't do anything special
7280             but someday we might!
7281         */
7282       }
7283       break;
7284     }
7285     default:
7286       break;
7287   }
7288   if (msl_info->content != (char *) NULL)
7289     msl_info->content=DestroyString(msl_info->content);
7290 }
7291
7292 static void MSLCharacters(void *context,const xmlChar *c,int length)
7293 {
7294   MSLInfo
7295     *msl_info;
7296
7297   register char
7298     *p;
7299
7300   register ssize_t
7301     i;
7302
7303   /*
7304     Receiving some characters from the parser.
7305   */
7306   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7307     "  SAX.characters(%s,%d)",c,length);
7308   msl_info=(MSLInfo *) context;
7309   if (msl_info->content != (char *) NULL)
7310     msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7311       strlen(msl_info->content)+length+MaxTextExtent,
7312       sizeof(*msl_info->content));
7313   else
7314     {
7315       msl_info->content=(char *) NULL;
7316       if (~length >= MaxTextExtent)
7317         msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7318           sizeof(*msl_info->content));
7319       if (msl_info->content != (char *) NULL)
7320         *msl_info->content='\0';
7321     }
7322   if (msl_info->content == (char *) NULL)
7323     return;
7324   p=msl_info->content+strlen(msl_info->content);
7325   for (i=0; i < length; i++)
7326     *p++=c[i];
7327   *p='\0';
7328 }
7329
7330 static void MSLReference(void *context,const xmlChar *name)
7331 {
7332   MSLInfo
7333     *msl_info;
7334
7335   xmlParserCtxtPtr
7336     parser;
7337
7338   /*
7339     Called when an entity reference is detected.
7340   */
7341   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7342     "  SAX.reference(%s)",name);
7343   msl_info=(MSLInfo *) context;
7344   parser=msl_info->parser;
7345   if (*name == '#')
7346     (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7347   else
7348     (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7349 }
7350
7351 static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7352 {
7353   MSLInfo
7354     *msl_info;
7355
7356   /*
7357     Receiving some ignorable whitespaces from the parser.
7358   */
7359   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7360     "  SAX.ignorableWhitespace(%.30s, %d)",c,length);
7361   msl_info=(MSLInfo *) context;
7362   (void) msl_info;
7363 }
7364
7365 static void MSLProcessingInstructions(void *context,const xmlChar *target,
7366   const xmlChar *data)
7367 {
7368   MSLInfo
7369     *msl_info;
7370
7371   /*
7372     A processing instruction has been parsed.
7373   */
7374   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7375     "  SAX.processingInstruction(%s, %s)",
7376     target,data);
7377   msl_info=(MSLInfo *) context;
7378   (void) msl_info;
7379 }
7380
7381 static void MSLComment(void *context,const xmlChar *value)
7382 {
7383   MSLInfo
7384     *msl_info;
7385
7386   /*
7387     A comment has been parsed.
7388   */
7389   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7390     "  SAX.comment(%s)",value);
7391   msl_info=(MSLInfo *) context;
7392   (void) msl_info;
7393 }
7394
7395 static void MSLWarning(void *context,const char *format,...)
7396 {
7397   char
7398     *message,
7399     reason[MaxTextExtent];
7400
7401   MSLInfo
7402     *msl_info;
7403
7404   va_list
7405     operands;
7406
7407   /**
7408     Display and format a warning messages, gives file, line, position and
7409     extra parameters.
7410   */
7411   va_start(operands,format);
7412   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.warning: ");
7413   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7414   msl_info=(MSLInfo *) context;
7415   (void) msl_info;
7416 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7417   (void) vsprintf(reason,format,operands);
7418 #else
7419   (void) vsnprintf(reason,MaxTextExtent,format,operands);
7420 #endif
7421   message=GetExceptionMessage(errno);
7422   ThrowMSLException(CoderError,reason,message);
7423   message=DestroyString(message);
7424   va_end(operands);
7425 }
7426
7427 static void MSLError(void *context,const char *format,...)
7428 {
7429   char
7430     reason[MaxTextExtent];
7431
7432   MSLInfo
7433     *msl_info;
7434
7435   va_list
7436     operands;
7437
7438   /*
7439     Display and format a error formats, gives file, line, position and
7440     extra parameters.
7441   */
7442   va_start(operands,format);
7443   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.error: ");
7444   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7445   msl_info=(MSLInfo *) context;
7446   (void) msl_info;
7447 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7448   (void) vsprintf(reason,format,operands);
7449 #else
7450   (void) vsnprintf(reason,MaxTextExtent,format,operands);
7451 #endif
7452   ThrowMSLException(DelegateFatalError,reason,"SAX error");
7453   va_end(operands);
7454 }
7455
7456 static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7457 {
7458   MSLInfo
7459     *msl_info;
7460
7461    xmlNodePtr
7462      child;
7463
7464   xmlParserCtxtPtr
7465     parser;
7466
7467   /*
7468     Called when a pcdata block has been parsed.
7469   */
7470   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7471     "  SAX.pcdata(%s, %d)",value,length);
7472   msl_info=(MSLInfo *) context;
7473   (void) msl_info;
7474   parser=msl_info->parser;
7475   child=xmlGetLastChild(parser->node);
7476   if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7477     {
7478       xmlTextConcat(child,value,length);
7479       return;
7480     }
7481   (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7482 }
7483
7484 static void MSLExternalSubset(void *context,const xmlChar *name,
7485   const xmlChar *external_id,const xmlChar *system_id)
7486 {
7487   MSLInfo
7488     *msl_info;
7489
7490   xmlParserCtxt
7491     parser_context;
7492
7493   xmlParserCtxtPtr
7494     parser;
7495
7496   xmlParserInputPtr
7497     input;
7498
7499   /*
7500     Does this document has an external subset?
7501   */
7502   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7503     "  SAX.externalSubset(%s %s %s)",name,
7504     (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7505     (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
7506   msl_info=(MSLInfo *) context;
7507   (void) msl_info;
7508   parser=msl_info->parser;
7509   if (((external_id == NULL) && (system_id == NULL)) ||
7510       ((parser->validate == 0) || (parser->wellFormed == 0) ||
7511       (msl_info->document == 0)))
7512     return;
7513   input=MSLResolveEntity(context,external_id,system_id);
7514   if (input == NULL)
7515     return;
7516   (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7517   parser_context=(*parser);
7518   parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7519   if (parser->inputTab == (xmlParserInputPtr *) NULL)
7520     {
7521       parser->errNo=XML_ERR_NO_MEMORY;
7522       parser->input=parser_context.input;
7523       parser->inputNr=parser_context.inputNr;
7524       parser->inputMax=parser_context.inputMax;
7525       parser->inputTab=parser_context.inputTab;
7526       return;
7527   }
7528   parser->inputNr=0;
7529   parser->inputMax=5;
7530   parser->input=NULL;
7531   xmlPushInput(parser,input);
7532   (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7533   if (input->filename == (char *) NULL)
7534     input->filename=(char *) xmlStrdup(system_id);
7535   input->line=1;
7536   input->col=1;
7537   input->base=parser->input->cur;
7538   input->cur=parser->input->cur;
7539   input->free=NULL;
7540   xmlParseExternalSubset(parser,external_id,system_id);
7541   while (parser->inputNr > 1)
7542     (void) xmlPopInput(parser);
7543   xmlFreeInputStream(parser->input);
7544   xmlFree(parser->inputTab);
7545   parser->input=parser_context.input;
7546   parser->inputNr=parser_context.inputNr;
7547   parser->inputMax=parser_context.inputMax;
7548   parser->inputTab=parser_context.inputTab;
7549 }
7550
7551 #if defined(__cplusplus) || defined(c_plusplus)
7552 }
7553 #endif
7554
7555 static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7556   ExceptionInfo *exception)
7557 {
7558   char
7559     message[MaxTextExtent];
7560
7561   Image
7562     *msl_image;
7563
7564   int
7565     status;
7566
7567   ssize_t
7568     n;
7569
7570   MSLInfo
7571     msl_info;
7572
7573   xmlSAXHandler
7574     sax_modules;
7575
7576   xmlSAXHandlerPtr
7577     sax_handler;
7578
7579   /*
7580     Open image file.
7581   */
7582   assert(image_info != (const ImageInfo *) NULL);
7583   assert(image_info->signature == MagickSignature);
7584   if (image_info->debug != MagickFalse)
7585     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7586       image_info->filename);
7587   assert(image != (Image **) NULL);
7588   msl_image=AcquireImage(image_info);
7589   status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7590   if (status == MagickFalse)
7591     {
7592       ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7593         msl_image->filename);
7594       msl_image=DestroyImageList(msl_image);
7595       return(MagickFalse);
7596     }
7597   msl_image->columns=1;
7598   msl_image->rows=1;
7599   /*
7600     Parse MSL file.
7601   */
7602   (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7603   msl_info.exception=exception;
7604   msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7605     sizeof(*msl_info.image_info));
7606   msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7607     sizeof(*msl_info.draw_info));
7608   /* top of the stack is the MSL file itself */
7609   msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
7610   msl_info.attributes=(Image **) AcquireMagickMemory(
7611     sizeof(*msl_info.attributes));
7612   msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7613     sizeof(*msl_info.group_info));
7614   if ((msl_info.image_info == (ImageInfo **) NULL) ||
7615       (msl_info.image == (Image **) NULL) ||
7616       (msl_info.attributes == (Image **) NULL) ||
7617       (msl_info.group_info == (MSLGroupInfo *) NULL))
7618     ThrowFatalException(ResourceLimitFatalError,
7619       "UnableToInterpretMSLImage");
7620   *msl_info.image_info=CloneImageInfo(image_info);
7621   *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7622   *msl_info.attributes=AcquireImage(image_info);
7623   msl_info.group_info[0].numImages=0;
7624   /* the first slot is used to point to the MSL file image */
7625   *msl_info.image=msl_image;
7626   if (*image != (Image *) NULL)
7627     MSLPushImage(&msl_info,*image);
7628   (void) xmlSubstituteEntitiesDefault(1);
7629   (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7630   sax_modules.internalSubset=MSLInternalSubset;
7631   sax_modules.isStandalone=MSLIsStandalone;
7632   sax_modules.hasInternalSubset=MSLHasInternalSubset;
7633   sax_modules.hasExternalSubset=MSLHasExternalSubset;
7634   sax_modules.resolveEntity=MSLResolveEntity;
7635   sax_modules.getEntity=MSLGetEntity;
7636   sax_modules.entityDecl=MSLEntityDeclaration;
7637   sax_modules.notationDecl=MSLNotationDeclaration;
7638   sax_modules.attributeDecl=MSLAttributeDeclaration;
7639   sax_modules.elementDecl=MSLElementDeclaration;
7640   sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7641   sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7642   sax_modules.startDocument=MSLStartDocument;
7643   sax_modules.endDocument=MSLEndDocument;
7644   sax_modules.startElement=MSLStartElement;
7645   sax_modules.endElement=MSLEndElement;
7646   sax_modules.reference=MSLReference;
7647   sax_modules.characters=MSLCharacters;
7648   sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7649   sax_modules.processingInstruction=MSLProcessingInstructions;
7650   sax_modules.comment=MSLComment;
7651   sax_modules.warning=MSLWarning;
7652   sax_modules.error=MSLError;
7653   sax_modules.fatalError=MSLError;
7654   sax_modules.getParameterEntity=MSLGetParameterEntity;
7655   sax_modules.cdataBlock=MSLCDataBlock;
7656   sax_modules.externalSubset=MSLExternalSubset;
7657   sax_handler=(&sax_modules);
7658   msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
7659     msl_image->filename);
7660   while (ReadBlobString(msl_image,message) != (char *) NULL)
7661   {
7662     n=(ssize_t) strlen(message);
7663     if (n == 0)
7664       continue;
7665     status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7666     if (status != 0)
7667       break;
7668     (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7669     if (msl_info.exception->severity >= ErrorException)
7670       break;
7671   }
7672   if (msl_info.exception->severity == UndefinedException)
7673     (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7674   xmlFreeParserCtxt(msl_info.parser);
7675   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7676   xmlCleanupParser();
7677   msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7678     msl_info.group_info);
7679   if (*image == (Image *) NULL)
7680     *image=(*msl_info.image);
7681   if ((*msl_info.image)->exception.severity != UndefinedException)
7682     return(MagickFalse);
7683   return(MagickTrue);
7684 }
7685
7686 static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7687 {
7688   Image
7689     *image;
7690
7691   /*
7692     Open image file.
7693   */
7694   assert(image_info != (const ImageInfo *) NULL);
7695   assert(image_info->signature == MagickSignature);
7696   if (image_info->debug != MagickFalse)
7697     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7698       image_info->filename);
7699   assert(exception != (ExceptionInfo *) NULL);
7700   assert(exception->signature == MagickSignature);
7701   image=(Image *) NULL;
7702   (void) ProcessMSLScript(image_info,&image,exception);
7703   return(GetFirstImageInList(image));
7704 }
7705 #endif
7706 \f
7707 /*
7708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7709 %                                                                             %
7710 %                                                                             %
7711 %                                                                             %
7712 %   R e g i s t e r M S L I m a g e                                           %
7713 %                                                                             %
7714 %                                                                             %
7715 %                                                                             %
7716 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7717 %
7718 %  RegisterMSLImage() adds attributes for the MSL image format to
7719 %  the list of supported formats.  The attributes include the image format
7720 %  tag, a method to read and/or write the format, whether the format
7721 %  supports the saving of more than one frame to the same file or blob,
7722 %  whether the format supports native in-memory I/O, and a brief
7723 %  description of the format.
7724 %
7725 %  The format of the RegisterMSLImage method is:
7726 %
7727 %      size_t RegisterMSLImage(void)
7728 %
7729 */
7730 ModuleExport size_t RegisterMSLImage(void)
7731 {
7732   MagickInfo
7733     *entry;
7734
7735   entry=SetMagickInfo("MSL");
7736 #if defined(MAGICKCORE_XML_DELEGATE)
7737   entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7738   entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7739 #endif
7740   entry->description=ConstantString("Magick Scripting Language");
7741   entry->module=ConstantString("MSL");
7742   (void) RegisterMagickInfo(entry);
7743   return(MagickImageCoderSignature);
7744 }
7745 \f
7746 #if defined(MAGICKCORE_XML_DELEGATE)
7747 /*
7748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7749 %                                                                             %
7750 %                                                                             %
7751 %                                                                             %
7752 %   S e t M S L A t t r i b u t e s                                           %
7753 %                                                                             %
7754 %                                                                             %
7755 %                                                                             %
7756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7757 %
7758 %  SetMSLAttributes() ...
7759 %
7760 %  The format of the SetMSLAttributes method is:
7761 %
7762 %      MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
7763 %        const char *keyword,const char *value)
7764 %
7765 %  A description of each parameter follows:
7766 %
7767 %    o msl_info: the MSL info.
7768 %
7769 %    o keyword: the keyword.
7770 %
7771 %    o value: the value.
7772 %
7773 */
7774 static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7775   const char *value)
7776 {
7777   Image
7778     *attributes;
7779
7780   DrawInfo
7781     *draw_info;
7782
7783   ExceptionInfo
7784     *exception;
7785
7786   GeometryInfo
7787     geometry_info;
7788
7789   Image
7790     *image;
7791
7792   ImageInfo
7793     *image_info;
7794
7795   int
7796     flags;
7797
7798   ssize_t
7799     n;
7800
7801   assert(msl_info != (MSLInfo *) NULL);
7802   if (keyword == (const char *) NULL)
7803     return(MagickTrue);
7804   if (value == (const char *) NULL)
7805     return(MagickTrue);
7806   exception=msl_info->exception;
7807   n=msl_info->n;
7808   attributes=msl_info->attributes[n];
7809   image_info=msl_info->image_info[n];
7810   draw_info=msl_info->draw_info[n];
7811   image=msl_info->image[n];
7812   switch (*keyword)
7813   {
7814     case 'A':
7815     case 'a':
7816     {
7817       if (LocaleCompare(keyword,"adjoin") == 0)
7818         {
7819           ssize_t
7820             adjoin;
7821
7822           adjoin=ParseMagickOption(MagickBooleanOptions,MagickFalse,value);
7823           if (adjoin < 0)
7824             ThrowMSLException(OptionError,"UnrecognizedType",value);
7825           image_info->adjoin=(MagickBooleanType) adjoin;
7826           break;
7827         }
7828       if (LocaleCompare(keyword,"alpha") == 0)
7829         {
7830           ssize_t
7831             alpha;
7832
7833           alpha=ParseMagickOption(MagickAlphaOptions,MagickFalse,value);
7834           if (alpha < 0)
7835             ThrowMSLException(OptionError,"UnrecognizedType",value);
7836           if (image != (Image *) NULL)
7837             (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha);
7838           break;
7839         }
7840       if (LocaleCompare(keyword,"antialias") == 0)
7841         {
7842           ssize_t
7843             antialias;
7844
7845           antialias=ParseMagickOption(MagickBooleanOptions,MagickFalse,value);
7846           if (antialias < 0)
7847             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7848           image_info->antialias=(MagickBooleanType) antialias;
7849           break;
7850         }
7851       if (LocaleCompare(keyword,"area-limit") == 0)
7852         {
7853           MagickSizeType
7854             limit;
7855
7856           limit=MagickResourceInfinity;
7857           if (LocaleCompare(value,"unlimited") != 0)
7858             limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
7859           (void) SetMagickResourceLimit(AreaResource,limit);
7860           break;
7861         }
7862       if (LocaleCompare(keyword,"attenuate") == 0)
7863         {
7864           (void) SetImageOption(image_info,keyword,value);
7865           break;
7866         }
7867       if (LocaleCompare(keyword,"authenticate") == 0)
7868         {
7869           (void) CloneString(&image_info->density,value);
7870           break;
7871         }
7872       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7873       break;
7874     }
7875     case 'B':
7876     case 'b':
7877     {
7878       if (LocaleCompare(keyword,"background") == 0)
7879         {
7880           (void) QueryColorDatabase(value,&image_info->background_color,
7881             exception);
7882           break;
7883         }
7884       if (LocaleCompare(keyword,"bias") == 0)
7885         {
7886           if (image == (Image *) NULL)
7887             break;
7888           image->bias=SiPrefixToDouble(value,QuantumRange);
7889           break;
7890         }
7891       if (LocaleCompare(keyword,"blue-primary") == 0)
7892         {
7893           if (image == (Image *) NULL)
7894             break;
7895           flags=ParseGeometry(value,&geometry_info);
7896           image->chromaticity.blue_primary.x=geometry_info.rho;
7897           image->chromaticity.blue_primary.y=geometry_info.sigma;
7898           if ((flags & SigmaValue) == 0)
7899             image->chromaticity.blue_primary.y=
7900               image->chromaticity.blue_primary.x;
7901           break;
7902         }
7903       if (LocaleCompare(keyword,"bordercolor") == 0)
7904         {
7905           (void) QueryColorDatabase(value,&image_info->border_color,
7906             exception);
7907           break;
7908         }
7909       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7910       break;
7911     }
7912     case 'D':
7913     case 'd':
7914     {
7915       if (LocaleCompare(keyword,"density") == 0)
7916         {
7917           (void) CloneString(&image_info->density,value);
7918           (void) CloneString(&draw_info->density,value);
7919           break;
7920         }
7921       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7922       break;
7923     }
7924     case 'F':
7925     case 'f':
7926     {
7927       if (LocaleCompare(keyword,"fill") == 0)
7928         {
7929           (void) QueryColorDatabase(value,&draw_info->fill,exception);
7930           (void) SetImageOption(image_info,keyword,value);
7931           break;
7932         }
7933       if (LocaleCompare(keyword,"filename") == 0)
7934         {
7935           (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7936           break;
7937         }
7938       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7939       break;
7940     }
7941     case 'G':
7942     case 'g':
7943     {
7944       if (LocaleCompare(keyword,"gravity") == 0)
7945         {
7946           ssize_t
7947             gravity;
7948
7949           gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,value);
7950           if (gravity < 0)
7951             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7952           (void) SetImageOption(image_info,keyword,value);
7953           break;
7954         }
7955       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7956       break;
7957     }
7958     case 'I':
7959     case 'i':
7960     {
7961       if (LocaleCompare(keyword,"id") == 0)
7962         {
7963           (void) SetImageProperty(attributes,keyword,value);
7964           break;
7965         }
7966       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7967       break;
7968     }
7969     case 'M':
7970     case 'm':
7971     {
7972       if (LocaleCompare(keyword,"magick") == 0)
7973         {
7974           (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
7975           break;
7976         }
7977       if (LocaleCompare(keyword,"mattecolor") == 0)
7978         {
7979           (void) QueryColorDatabase(value,&image_info->matte_color,
7980             exception);
7981           break;
7982         }
7983       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7984       break;
7985     }
7986     case 'P':
7987     case 'p':
7988     {
7989       if (LocaleCompare(keyword,"pointsize") == 0)
7990         {
7991           image_info->pointsize=StringToDouble(value);
7992           draw_info->pointsize=StringToDouble(value);
7993           break;
7994         }
7995       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7996       break;
7997     }
7998     case 'Q':
7999     case 'q':
8000     {
8001       if (LocaleCompare(keyword,"quality") == 0)
8002         {
8003           image_info->quality=StringToLong(value);
8004           if (image == (Image *) NULL)
8005             break;
8006           image->quality=StringToLong(value);
8007           break;
8008         }
8009       break;
8010     }
8011     case 'S':
8012     case 's':
8013     {
8014       if (LocaleCompare(keyword,"size") == 0)
8015         {
8016           (void) CloneString(&image_info->size,value);
8017           break;
8018         }
8019       if (LocaleCompare(keyword,"stroke") == 0)
8020         {
8021           (void) QueryColorDatabase(value,&draw_info->stroke,exception);
8022           (void) SetImageOption(image_info,keyword,value);
8023           break;
8024         }
8025       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8026       break;
8027     }
8028     default:
8029     {
8030       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8031       break;
8032     }
8033   }
8034   return(MagickTrue);
8035 }
8036 #endif
8037 \f
8038 /*
8039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8040 %                                                                             %
8041 %                                                                             %
8042 %                                                                             %
8043 %   U n r e g i s t e r M S L I m a g e                                       %
8044 %                                                                             %
8045 %                                                                             %
8046 %                                                                             %
8047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8048 %
8049 %  UnregisterMSLImage() removes format registrations made by the
8050 %  MSL module from the list of supported formats.
8051 %
8052 %  The format of the UnregisterMSLImage method is:
8053 %
8054 %      UnregisterMSLImage(void)
8055 %
8056 */
8057 ModuleExport void UnregisterMSLImage(void)
8058 {
8059   (void) UnregisterMagickInfo("MSL");
8060 }
8061 \f
8062 #if defined(MAGICKCORE_XML_DELEGATE)
8063 /*
8064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8065 %                                                                             %
8066 %                                                                             %
8067 %                                                                             %
8068 %   W r i t e M S L I m a g e                                                 %
8069 %                                                                             %
8070 %                                                                             %
8071 %                                                                             %
8072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8073 %
8074 %  WriteMSLImage() writes an image to a file in MVG image format.
8075 %
8076 %  The format of the WriteMSLImage method is:
8077 %
8078 %      MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8079 %
8080 %  A description of each parameter follows.
8081 %
8082 %    o image_info: the image info.
8083 %
8084 %    o image:  The image.
8085 %
8086 */
8087 static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8088 {
8089   assert(image_info != (const ImageInfo *) NULL);
8090   assert(image_info->signature == MagickSignature);
8091   assert(image != (Image *) NULL);
8092   assert(image->signature == MagickSignature);
8093   if (image->debug != MagickFalse)
8094     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8095   (void) ReferenceImage(image);
8096   (void) ProcessMSLScript(image_info,&image,&image->exception);
8097   return(MagickTrue);
8098 }
8099 #endif