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