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