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