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