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