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