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