]> granicus.if.org Git - imagemagick/blob - coders/msl.c
9804a5a020e57b01d0f4f3ccd6500aba16a919f0
[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           noise_image=AddNoiseImageChannel(msl_info->image[n],channel,noise,
740             &msl_info->image[n]->exception);
741           if (noise_image == (Image *) NULL)
742             break;
743           msl_info->image[n]=DestroyImage(msl_info->image[n]);
744           msl_info->image[n]=noise_image;
745           break;
746         }
747       if (LocaleCompare((const char *) tag,"annotate") == 0)
748         {
749           char
750             text[MaxTextExtent];
751
752           /*
753             Annotate image.
754           */
755           if (msl_info->image[n] == (Image *) NULL)
756             {
757               ThrowMSLException(OptionError,"NoImagesDefined",
758                 (const char *) tag);
759               break;
760             }
761           draw_info=CloneDrawInfo(msl_info->image_info[n],
762             msl_info->draw_info[n]);
763           angle=0.0;
764           current=draw_info->affine;
765           GetAffineMatrix(&affine);
766           if (attributes != (const xmlChar **) NULL)
767             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
768             {
769               keyword=(const char *) attributes[i++];
770               attribute=InterpretImageProperties(msl_info->image_info[n],
771                 msl_info->attributes[n],(const char *) attributes[i]);
772               CloneString(&value,attribute);
773               switch (*keyword)
774               {
775                 case 'A':
776                 case 'a':
777                 {
778                   if (LocaleCompare(keyword,"affine") == 0)
779                     {
780                       char
781                         *p;
782
783                       p=value;
784                       draw_info->affine.sx=InterpretLocaleValue(p,&p);
785                       if (*p ==',')
786                         p++;
787                       draw_info->affine.rx=InterpretLocaleValue(p,&p);
788                       if (*p ==',')
789                         p++;
790                       draw_info->affine.ry=InterpretLocaleValue(p,&p);
791                       if (*p ==',')
792                         p++;
793                       draw_info->affine.sy=InterpretLocaleValue(p,&p);
794                       if (*p ==',')
795                         p++;
796                       draw_info->affine.tx=InterpretLocaleValue(p,&p);
797                       if (*p ==',')
798                         p++;
799                       draw_info->affine.ty=InterpretLocaleValue(p,&p);
800                       break;
801                     }
802                   if (LocaleCompare(keyword,"align") == 0)
803                     {
804                       option=ParseCommandOption(MagickAlignOptions,MagickFalse,
805                         value);
806                       if (option < 0)
807                         ThrowMSLException(OptionError,"UnrecognizedAlignType",
808                           value);
809                       draw_info->align=(AlignType) option;
810                       break;
811                     }
812                   if (LocaleCompare(keyword,"antialias") == 0)
813                     {
814                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
815                         value);
816                       if (option < 0)
817                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
818                           value);
819                       draw_info->stroke_antialias=(MagickBooleanType) option;
820                       draw_info->text_antialias=(MagickBooleanType) option;
821                       break;
822                     }
823                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
824                     keyword);
825                   break;
826                 }
827                 case 'D':
828                 case 'd':
829                 {
830                   if (LocaleCompare(keyword,"density") == 0)
831                     {
832                       CloneString(&draw_info->density,value);
833                       break;
834                     }
835                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
836                     keyword);
837                   break;
838                 }
839                 case 'E':
840                 case 'e':
841                 {
842                   if (LocaleCompare(keyword,"encoding") == 0)
843                     {
844                       CloneString(&draw_info->encoding,value);
845                       break;
846                     }
847                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
848                     keyword);
849                   break;
850                 }
851                 case 'F':
852                 case 'f':
853                 {
854                   if (LocaleCompare(keyword, "fill") == 0)
855                     {
856                       (void) QueryColorDatabase(value,&draw_info->fill,
857                         &exception);
858                       break;
859                     }
860                   if (LocaleCompare(keyword,"family") == 0)
861                     {
862                       CloneString(&draw_info->family,value);
863                       break;
864                     }
865                   if (LocaleCompare(keyword,"font") == 0)
866                     {
867                       CloneString(&draw_info->font,value);
868                       break;
869                     }
870                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
871                     keyword);
872                   break;
873                 }
874                 case 'G':
875                 case 'g':
876                 {
877                   if (LocaleCompare(keyword,"geometry") == 0)
878                     {
879                       flags=ParsePageGeometry(msl_info->image[n],value,
880                         &geometry,&exception);
881                       if ((flags & HeightValue) == 0)
882                         geometry.height=geometry.width;
883                       break;
884                     }
885                   if (LocaleCompare(keyword,"gravity") == 0)
886                     {
887                       option=ParseCommandOption(MagickGravityOptions,MagickFalse,
888                         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           blur_image=BlurImageChannel(msl_info->image[n],channel,
1233             geometry_info.rho,geometry_info.sigma,
1234             &msl_info->image[n]->exception);
1235           if (blur_image == (Image *) NULL)
1236             break;
1237           msl_info->image[n]=DestroyImage(msl_info->image[n]);
1238           msl_info->image[n]=blur_image;
1239           break;
1240         }
1241       if (LocaleCompare((const char *) tag,"border") == 0)
1242         {
1243           Image
1244             *border_image;
1245
1246           /*
1247             Border image.
1248           */
1249           if (msl_info->image[n] == (Image *) NULL)
1250             {
1251               ThrowMSLException(OptionError,"NoImagesDefined",
1252                 (const char *) tag);
1253               break;
1254             }
1255           SetGeometry(msl_info->image[n],&geometry);
1256           if (attributes != (const xmlChar **) NULL)
1257             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1258             {
1259               keyword=(const char *) attributes[i++];
1260               attribute=InterpretImageProperties(msl_info->image_info[n],
1261                 msl_info->attributes[n],(const char *) attributes[i]);
1262               CloneString(&value,attribute);
1263               switch (*keyword)
1264               {
1265                 case 'C':
1266                 case 'c':
1267                 {
1268                   if (LocaleCompare(keyword,"compose") == 0)
1269                     {
1270                       option=ParseCommandOption(MagickComposeOptions,MagickFalse,
1271                         value);
1272                       if (option < 0)
1273                         ThrowMSLException(OptionError,"UnrecognizedComposeType",
1274                           value);
1275                       msl_info->image[n]->compose=(CompositeOperator) option;
1276                       break;
1277                     }
1278                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1279                     keyword);
1280                   break;
1281                 }
1282                 case 'F':
1283                 case 'f':
1284                 {
1285                   if (LocaleCompare(keyword, "fill") == 0)
1286                     {
1287                       (void) QueryColorDatabase(value,
1288                         &msl_info->image[n]->border_color,&exception);
1289                       break;
1290                     }
1291                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1292                     keyword);
1293                   break;
1294                 }
1295                 case 'G':
1296                 case 'g':
1297                 {
1298                   if (LocaleCompare(keyword,"geometry") == 0)
1299                     {
1300                       flags=ParsePageGeometry(msl_info->image[n],value,
1301                         &geometry,&exception);
1302                       if ((flags & HeightValue) == 0)
1303                         geometry.height=geometry.width;
1304                       break;
1305                     }
1306                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1307                     keyword);
1308                   break;
1309                 }
1310                 case 'H':
1311                 case 'h':
1312                 {
1313                   if (LocaleCompare(keyword,"height") == 0)
1314                     {
1315                       geometry.height=StringToLong(value);
1316                       break;
1317                     }
1318                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1319                     keyword);
1320                   break;
1321                 }
1322                 case 'W':
1323                 case 'w':
1324                 {
1325                   if (LocaleCompare(keyword,"width") == 0)
1326                     {
1327                       geometry.width=StringToLong(value);
1328                       break;
1329                     }
1330                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1331                     keyword);
1332                   break;
1333                 }
1334                 default:
1335                 {
1336                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1337                     keyword);
1338                   break;
1339                 }
1340               }
1341             }
1342           border_image=BorderImage(msl_info->image[n],&geometry,
1343             &msl_info->image[n]->exception);
1344           if (border_image == (Image *) NULL)
1345             break;
1346           msl_info->image[n]=DestroyImage(msl_info->image[n]);
1347           msl_info->image[n]=border_image;
1348           break;
1349         }
1350       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1351     }
1352     case 'C':
1353     case 'c':
1354     {
1355       if (LocaleCompare((const char *) tag,"colorize") == 0)
1356         {
1357           char
1358             opacity[MaxTextExtent];
1359
1360           Image
1361             *colorize_image;
1362
1363           PixelPacket
1364             target;
1365
1366           /*
1367             Add noise image.
1368           */
1369           if (msl_info->image[n] == (Image *) NULL)
1370             {
1371               ThrowMSLException(OptionError,"NoImagesDefined",
1372                 (const char *) tag);
1373               break;
1374             }
1375           target=msl_info->image[n]->background_color;
1376           (void) CopyMagickString(opacity,"100",MaxTextExtent);
1377           if (attributes != (const xmlChar **) NULL)
1378             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1379             {
1380               keyword=(const char *) attributes[i++];
1381               attribute=InterpretImageProperties(msl_info->image_info[n],
1382                 msl_info->attributes[n],(const char *) attributes[i]);
1383               CloneString(&value,attribute);
1384               switch (*keyword)
1385               {
1386                 case 'F':
1387                 case 'f':
1388                 {
1389                   if (LocaleCompare(keyword,"fill") == 0)
1390                     {
1391                       (void) QueryColorDatabase(value,&target,
1392                         &msl_info->image[n]->exception);
1393                       break;
1394                     }
1395                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1396                     keyword);
1397                   break;
1398                 }
1399                 case 'O':
1400                 case 'o':
1401                 {
1402                   if (LocaleCompare(keyword,"opacity") == 0)
1403                     {
1404                       (void) CopyMagickString(opacity,value,MaxTextExtent);
1405                       break;
1406                     }
1407                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1408                     keyword);
1409                   break;
1410                 }
1411                 default:
1412                 {
1413                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1414                     keyword);
1415                   break;
1416                 }
1417               }
1418             }
1419           colorize_image=ColorizeImage(msl_info->image[n],opacity,target,
1420             &msl_info->image[n]->exception);
1421           if (colorize_image == (Image *) NULL)
1422             break;
1423           msl_info->image[n]=DestroyImage(msl_info->image[n]);
1424           msl_info->image[n]=colorize_image;
1425           break;
1426         }
1427       if (LocaleCompare((const char *) tag, "charcoal") == 0)
1428       {
1429         double  radius = 0.0,
1430             sigma = 1.0;
1431
1432         if (msl_info->image[n] == (Image *) NULL)
1433         {
1434           ThrowMSLException(OptionError,"NoImagesDefined",
1435             (const char *) tag);
1436           break;
1437         }
1438         /*
1439         NOTE: charcoal can have no attributes, since we use all the defaults!
1440         */
1441         if (attributes != (const xmlChar **) NULL)
1442         {
1443           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1444           {
1445           keyword=(const char *) attributes[i++];
1446           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
1447             msl_info->attributes[n],(const char *) attributes[i]));
1448           switch (*keyword)
1449           {
1450             case 'R':
1451             case 'r':
1452             {
1453               if (LocaleCompare(keyword, "radius") == 0)
1454               {
1455                 radius = InterpretLocaleValue(value,(char **) NULL);
1456                 break;
1457               }
1458               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1459               break;
1460             }
1461             case 'S':
1462             case 's':
1463             {
1464               if (LocaleCompare(keyword,"sigma") == 0)
1465               {
1466                 sigma = StringToLong( value );
1467                 break;
1468               }
1469               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1470               break;
1471             }
1472             default:
1473             {
1474               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1475               break;
1476             }
1477           }
1478           }
1479         }
1480
1481         /*
1482           charcoal image.
1483         */
1484         {
1485         Image
1486           *newImage;
1487
1488         newImage=CharcoalImage(msl_info->image[n],radius,sigma,
1489           &msl_info->image[n]->exception);
1490         if (newImage == (Image *) NULL)
1491           break;
1492         msl_info->image[n]=DestroyImage(msl_info->image[n]);
1493         msl_info->image[n]=newImage;
1494         break;
1495         }
1496       }
1497       if (LocaleCompare((const char *) tag,"chop") == 0)
1498         {
1499           Image
1500             *chop_image;
1501
1502           /*
1503             Chop image.
1504           */
1505           if (msl_info->image[n] == (Image *) NULL)
1506             {
1507               ThrowMSLException(OptionError,"NoImagesDefined",
1508                 (const char *) tag);
1509               break;
1510             }
1511           SetGeometry(msl_info->image[n],&geometry);
1512           if (attributes != (const xmlChar **) NULL)
1513             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1514             {
1515               keyword=(const char *) attributes[i++];
1516               attribute=InterpretImageProperties(msl_info->image_info[n],
1517                 msl_info->attributes[n],(const char *) attributes[i]);
1518               CloneString(&value,attribute);
1519               switch (*keyword)
1520               {
1521                 case 'G':
1522                 case 'g':
1523                 {
1524                   if (LocaleCompare(keyword,"geometry") == 0)
1525                     {
1526                       flags=ParsePageGeometry(msl_info->image[n],value,
1527                         &geometry,&exception);
1528                       if ((flags & HeightValue) == 0)
1529                         geometry.height=geometry.width;
1530                       break;
1531                     }
1532                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1533                     keyword);
1534                   break;
1535                 }
1536                 case 'H':
1537                 case 'h':
1538                 {
1539                   if (LocaleCompare(keyword,"height") == 0)
1540                     {
1541                       geometry.height=StringToLong(value);
1542                       break;
1543                     }
1544                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1545                     keyword);
1546                   break;
1547                 }
1548                 case 'W':
1549                 case 'w':
1550                 {
1551                   if (LocaleCompare(keyword,"width") == 0)
1552                     {
1553                       geometry.width=StringToLong(value);
1554                       break;
1555                     }
1556                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1557                     keyword);
1558                   break;
1559                 }
1560                 case 'X':
1561                 case 'x':
1562                 {
1563                   if (LocaleCompare(keyword,"x") == 0)
1564                     {
1565                       geometry.x=StringToLong(value);
1566                       break;
1567                     }
1568                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1569                     keyword);
1570                   break;
1571                 }
1572                 case 'Y':
1573                 case 'y':
1574                 {
1575                   if (LocaleCompare(keyword,"y") == 0)
1576                     {
1577                       geometry.y=StringToLong(value);
1578                       break;
1579                     }
1580                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1581                     keyword);
1582                   break;
1583                 }
1584                 default:
1585                 {
1586                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1587                     keyword);
1588                   break;
1589                 }
1590               }
1591             }
1592           chop_image=ChopImage(msl_info->image[n],&geometry,
1593             &msl_info->image[n]->exception);
1594           if (chop_image == (Image *) NULL)
1595             break;
1596           msl_info->image[n]=DestroyImage(msl_info->image[n]);
1597           msl_info->image[n]=chop_image;
1598           break;
1599         }
1600       if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
1601         {
1602           PaintMethod
1603             paint_method;
1604
1605           PixelInfo
1606             target;
1607
1608           /*
1609             Color floodfill image.
1610           */
1611           if (msl_info->image[n] == (Image *) NULL)
1612             {
1613               ThrowMSLException(OptionError,"NoImagesDefined",
1614                 (const char *) tag);
1615               break;
1616             }
1617           draw_info=CloneDrawInfo(msl_info->image_info[n],
1618             msl_info->draw_info[n]);
1619           SetGeometry(msl_info->image[n],&geometry);
1620           paint_method=FloodfillMethod;
1621           if (attributes != (const xmlChar **) NULL)
1622             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1623             {
1624               keyword=(const char *) attributes[i++];
1625               attribute=InterpretImageProperties(msl_info->image_info[n],
1626                 msl_info->attributes[n],(const char *) attributes[i]);
1627               CloneString(&value,attribute);
1628               switch (*keyword)
1629               {
1630                 case 'B':
1631                 case 'b':
1632                 {
1633                   if (LocaleCompare(keyword,"bordercolor") == 0)
1634                     {
1635                       (void) QueryMagickColor(value,&target,&exception);
1636                       paint_method=FillToBorderMethod;
1637                       break;
1638                     }
1639                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1640                     keyword);
1641                   break;
1642                 }
1643                 case 'F':
1644                 case 'f':
1645                 {
1646                   if (LocaleCompare(keyword,"fill") == 0)
1647                     {
1648                       (void) QueryColorDatabase(value,&draw_info->fill,
1649                         &exception);
1650                       break;
1651                     }
1652                   if (LocaleCompare(keyword,"fuzz") == 0)
1653                     {
1654                       msl_info->image[n]->fuzz=InterpretLocaleValue(value,
1655                         (char **) NULL);
1656                       break;
1657                     }
1658                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1659                     keyword);
1660                   break;
1661                 }
1662                 case 'G':
1663                 case 'g':
1664                 {
1665                   if (LocaleCompare(keyword,"geometry") == 0)
1666                     {
1667                       flags=ParsePageGeometry(msl_info->image[n],value,
1668                         &geometry,&exception);
1669                       if ((flags & HeightValue) == 0)
1670                         geometry.height=geometry.width;
1671                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
1672                         geometry.x,geometry.y,&target,&exception);
1673                       break;
1674                     }
1675                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1676                     keyword);
1677                   break;
1678                 }
1679                 case 'X':
1680                 case 'x':
1681                 {
1682                   if (LocaleCompare(keyword,"x") == 0)
1683                     {
1684                       geometry.x=StringToLong(value);
1685                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
1686                         geometry.x,geometry.y,&target,&exception);
1687                       break;
1688                     }
1689                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1690                     keyword);
1691                   break;
1692                 }
1693                 case 'Y':
1694                 case 'y':
1695                 {
1696                   if (LocaleCompare(keyword,"y") == 0)
1697                     {
1698                       geometry.y=StringToLong(value);
1699                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
1700                         geometry.x,geometry.y,&target,&exception);
1701                       break;
1702                     }
1703                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1704                     keyword);
1705                   break;
1706                 }
1707                 default:
1708                 {
1709                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1710                     keyword);
1711                   break;
1712                 }
1713               }
1714             }
1715           (void) FloodfillPaintImage(msl_info->image[n],DefaultChannels,
1716             draw_info,&target,geometry.x,geometry.y,
1717             paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
1718           draw_info=DestroyDrawInfo(draw_info);
1719           break;
1720         }
1721       if (LocaleCompare((const char *) tag,"comment") == 0)
1722         break;
1723       if (LocaleCompare((const char *) tag,"composite") == 0)
1724         {
1725           char
1726             composite_geometry[MaxTextExtent];
1727
1728           CompositeOperator
1729             compose;
1730
1731           Image
1732             *composite_image,
1733             *rotate_image;
1734
1735           PixelPacket
1736             target;
1737
1738           /*
1739             Composite image.
1740           */
1741           if (msl_info->image[n] == (Image *) NULL)
1742             {
1743               ThrowMSLException(OptionError,"NoImagesDefined",
1744                 (const char *) tag);
1745               break;
1746             }
1747           composite_image=NewImageList();
1748           compose=OverCompositeOp;
1749           if (attributes != (const xmlChar **) NULL)
1750             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1751             {
1752               keyword=(const char *) attributes[i++];
1753               attribute=InterpretImageProperties(msl_info->image_info[n],
1754                 msl_info->attributes[n],(const char *) attributes[i]);
1755               CloneString(&value,attribute);
1756               switch (*keyword)
1757               {
1758                 case 'C':
1759                 case 'c':
1760                 {
1761                   if (LocaleCompare(keyword,"compose") == 0)
1762                     {
1763                       option=ParseCommandOption(MagickComposeOptions,MagickFalse,
1764                         value);
1765                       if (option < 0)
1766                         ThrowMSLException(OptionError,"UnrecognizedComposeType",
1767                           value);
1768                       compose=(CompositeOperator) option;
1769                       break;
1770                     }
1771                   break;
1772                 }
1773                 case 'I':
1774                 case 'i':
1775                 {
1776                   if (LocaleCompare(keyword,"image") == 0)
1777                     for (j=0; j < msl_info->n; j++)
1778                     {
1779                       const char
1780                         *attribute;
1781
1782                       attribute=GetImageProperty(msl_info->attributes[j],"id");
1783                       if ((attribute != (const char *) NULL)  &&
1784                           (LocaleCompare(attribute,value) == 0))
1785                         {
1786                           composite_image=CloneImage(msl_info->image[j],0,0,
1787                             MagickFalse,&exception);
1788                           break;
1789                         }
1790                     }
1791                   break;
1792                 }
1793                 default:
1794                   break;
1795               }
1796             }
1797           if (composite_image == (Image *) NULL)
1798             break;
1799           rotate_image=NewImageList();
1800           SetGeometry(msl_info->image[n],&geometry);
1801           if (attributes != (const xmlChar **) NULL)
1802             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1803             {
1804               keyword=(const char *) attributes[i++];
1805               attribute=InterpretImageProperties(msl_info->image_info[n],
1806                 msl_info->attributes[n],(const char *) attributes[i]);
1807               CloneString(&value,attribute);
1808               switch (*keyword)
1809               {
1810                 case 'B':
1811                 case 'b':
1812                 {
1813                   if (LocaleCompare(keyword,"blend") == 0)
1814                     {
1815                       (void) SetImageArtifact(composite_image,
1816                                             "compose:args",value);
1817                       break;
1818                     }
1819                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1820                     keyword);
1821                   break;
1822                 }
1823                 case 'C':
1824                 case 'c':
1825                 {
1826                   if (LocaleCompare(keyword,"channel") == 0)
1827                     {
1828                       option=ParseChannelOption(value);
1829                       if (option < 0)
1830                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
1831                           value);
1832                       channel=(ChannelType) option;
1833                       break;
1834                     }
1835                   if (LocaleCompare(keyword, "color") == 0)
1836                     {
1837                       (void) QueryColorDatabase(value,
1838                         &composite_image->background_color,&exception);
1839                       break;
1840                     }
1841                   if (LocaleCompare(keyword,"compose") == 0)
1842                     break;
1843                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1844                     keyword);
1845                   break;
1846                 }
1847                 case 'G':
1848                 case 'g':
1849                 {
1850                   if (LocaleCompare(keyword,"geometry") == 0)
1851                     {
1852                       flags=ParsePageGeometry(msl_info->image[n],value,
1853                         &geometry,&exception);
1854                       if ((flags & HeightValue) == 0)
1855                         geometry.height=geometry.width;
1856                       (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
1857                         geometry.y,&target,&exception);
1858                       break;
1859                     }
1860                   if (LocaleCompare(keyword,"gravity") == 0)
1861                     {
1862                       option=ParseCommandOption(MagickGravityOptions,MagickFalse,
1863                         value);
1864                       if (option < 0)
1865                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
1866                           value);
1867                       msl_info->image[n]->gravity=(GravityType) option;
1868                       break;
1869                     }
1870                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1871                     keyword);
1872                   break;
1873                 }
1874                 case 'I':
1875                 case 'i':
1876                 {
1877                   if (LocaleCompare(keyword,"image") == 0)
1878                     break;
1879                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1880                     keyword);
1881                   break;
1882                 }
1883                 case 'M':
1884                 case 'm':
1885                 {
1886                   if (LocaleCompare(keyword,"mask") == 0)
1887                     for (j=0; j < msl_info->n; j++)
1888                     {
1889                       const char
1890                         *attribute;
1891
1892                       attribute=GetImageProperty(msl_info->attributes[j],"id");
1893                       if ((attribute != (const char *) NULL)  &&
1894                           (LocaleCompare(value,value) == 0))
1895                         {
1896                           SetImageType(composite_image,TrueColorMatteType);
1897                           (void) CompositeImage(composite_image,
1898                             CopyOpacityCompositeOp,msl_info->image[j],0,0);
1899                           break;
1900                         }
1901                     }
1902                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1903                     keyword);
1904                   break;
1905                 }
1906                 case 'O':
1907                 case 'o':
1908                 {
1909                   if (LocaleCompare(keyword,"opacity") == 0)
1910                     {
1911                       ssize_t
1912                         opacity,
1913                         y;
1914
1915                       register ssize_t
1916                         x;
1917
1918                       register Quantum
1919                         *q;
1920
1921                       CacheView
1922                         *composite_view;
1923
1924                       opacity=StringToLong(value);
1925                       if (compose != DissolveCompositeOp)
1926                         {
1927                           (void) SetImageOpacity(composite_image,(Quantum)
1928                             opacity);
1929                           break;
1930                         }
1931                       (void) SetImageArtifact(msl_info->image[n],
1932                                             "compose:args",value);
1933                       if (composite_image->matte != MagickTrue)
1934                         (void) SetImageOpacity(composite_image,OpaqueAlpha);
1935                       composite_view=AcquireCacheView(composite_image);
1936                       for (y=0; y < (ssize_t) composite_image->rows ; y++)
1937                       {
1938                         q=GetCacheViewAuthenticPixels(composite_view,0,y,
1939                           (ssize_t) composite_image->columns,1,&exception);
1940                         for (x=0; x < (ssize_t) composite_image->columns; x++)
1941                         {
1942                           if (GetPixelAlpha(composite_image,q) == OpaqueAlpha)
1943                             SetPixelAlpha(composite_image,
1944                               ClampToQuantum(opacity),q);
1945                           q+=GetPixelChannels(composite_image);
1946                         }
1947                         if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1948                           break;
1949                       }
1950                       composite_view=DestroyCacheView(composite_view);
1951                       break;
1952                     }
1953                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1954                     keyword);
1955                   break;
1956                 }
1957                 case 'R':
1958                 case 'r':
1959                 {
1960                   if (LocaleCompare(keyword,"rotate") == 0)
1961                     {
1962                       rotate_image=RotateImage(composite_image,
1963                         InterpretLocaleValue(value,(char **) NULL),&exception);
1964                       break;
1965                     }
1966                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
1967                     keyword);
1968                   break;
1969                 }
1970                 case 'T':
1971                 case 't':
1972                 {
1973                   if (LocaleCompare(keyword,"tile") == 0)
1974                     {
1975                       MagickBooleanType
1976                         tile;
1977
1978                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
1979                         value);
1980                       if (option < 0)
1981                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1982                           value);
1983                       tile=(MagickBooleanType) option;
1984                       (void) tile;
1985                       if (rotate_image != (Image *) NULL)
1986                         (void) SetImageArtifact(rotate_image,
1987                           "compose:outside-overlay","false");
1988                       else
1989                         (void) SetImageArtifact(composite_image,
1990                           "compose:outside-overlay","false");
1991                        image=msl_info->image[n];
1992                        height=composite_image->rows;
1993                        width=composite_image->columns;
1994                        for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
1995                          for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
1996                          {
1997                            if (rotate_image != (Image *) NULL)
1998                              (void) CompositeImage(image,compose,rotate_image,
1999                                x,y);
2000                            else
2001                              (void) CompositeImage(image,compose,
2002                                composite_image,x,y);
2003                          }
2004                       if (rotate_image != (Image *) NULL)
2005                         rotate_image=DestroyImage(rotate_image);
2006                       break;
2007                     }
2008                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2009                     keyword);
2010                   break;
2011                 }
2012                 case 'X':
2013                 case 'x':
2014                 {
2015                   if (LocaleCompare(keyword,"x") == 0)
2016                     {
2017                       geometry.x=StringToLong(value);
2018                       (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2019                         geometry.y,&target,&exception);
2020                       break;
2021                     }
2022                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2023                     keyword);
2024                   break;
2025                 }
2026                 case 'Y':
2027                 case 'y':
2028                 {
2029                   if (LocaleCompare(keyword,"y") == 0)
2030                     {
2031                       geometry.y=StringToLong(value);
2032                       (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2033                         geometry.y,&target,&exception);
2034                       break;
2035                     }
2036                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2037                     keyword);
2038                   break;
2039                 }
2040                 default:
2041                 {
2042                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2043                     keyword);
2044                   break;
2045                 }
2046               }
2047             }
2048           image=msl_info->image[n];
2049           (void) FormatLocaleString(composite_geometry,MaxTextExtent,
2050             "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2051             (double) composite_image->rows,(double) geometry.x,(double)
2052             geometry.y);
2053           flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2054             &exception);
2055           if (rotate_image == (Image *) NULL)
2056             CompositeImageChannel(image,channel,compose,composite_image,
2057               geometry.x,geometry.y);
2058           else
2059             {
2060               /*
2061                 Rotate image.
2062               */
2063               geometry.x-=(ssize_t) (rotate_image->columns-
2064                 composite_image->columns)/2;
2065               geometry.y-=(ssize_t) (rotate_image->rows-composite_image->rows)/2;
2066               CompositeImageChannel(image,channel,compose,rotate_image,
2067                 geometry.x,geometry.y);
2068               rotate_image=DestroyImage(rotate_image);
2069             }
2070           composite_image=DestroyImage(composite_image);
2071           break;
2072         }
2073       if (LocaleCompare((const char *) tag,"contrast") == 0)
2074         {
2075           MagickBooleanType
2076             sharpen;
2077
2078           /*
2079             Contrast image.
2080           */
2081           if (msl_info->image[n] == (Image *) NULL)
2082             {
2083               ThrowMSLException(OptionError,"NoImagesDefined",
2084                 (const char *) tag);
2085               break;
2086             }
2087           sharpen=MagickFalse;
2088           if (attributes != (const xmlChar **) NULL)
2089             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2090             {
2091               keyword=(const char *) attributes[i++];
2092               attribute=InterpretImageProperties(msl_info->image_info[n],
2093                 msl_info->attributes[n],(const char *) attributes[i]);
2094               CloneString(&value,attribute);
2095               switch (*keyword)
2096               {
2097                 case 'S':
2098                 case 's':
2099                 {
2100                   if (LocaleCompare(keyword,"sharpen") == 0)
2101                     {
2102                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2103                         value);
2104                       if (option < 0)
2105                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2106                           value);
2107                       sharpen=(MagickBooleanType) option;
2108                       break;
2109                     }
2110                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2111                     keyword);
2112                   break;
2113                 }
2114                 default:
2115                 {
2116                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2117                     keyword);
2118                   break;
2119                 }
2120               }
2121             }
2122           (void) ContrastImage(msl_info->image[n],sharpen);
2123           break;
2124         }
2125       if (LocaleCompare((const char *) tag,"crop") == 0)
2126         {
2127           Image
2128             *crop_image;
2129
2130           /*
2131             Crop image.
2132           */
2133           if (msl_info->image[n] == (Image *) NULL)
2134             {
2135               ThrowMSLException(OptionError,"NoImagesDefined",
2136                 (const char *) tag);
2137               break;
2138             }
2139           SetGeometry(msl_info->image[n],&geometry);
2140           if (attributes != (const xmlChar **) NULL)
2141             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2142             {
2143               keyword=(const char *) attributes[i++];
2144               attribute=InterpretImageProperties(msl_info->image_info[n],
2145                 msl_info->attributes[n],(const char *) attributes[i]);
2146               CloneString(&value,attribute);
2147               switch (*keyword)
2148               {
2149                 case 'G':
2150                 case 'g':
2151                 {
2152                   if (LocaleCompare(keyword,"geometry") == 0)
2153                     {
2154                       flags=ParsePageGeometry(msl_info->image[n],value,
2155                         &geometry,&exception);
2156                       if ((flags & HeightValue) == 0)
2157                         geometry.height=geometry.width;
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           switch (channel)
3230           {
3231             default:
3232             {
3233               (void) GammaImage(msl_info->image[n],gamma);
3234               break;
3235             }
3236             case RedChannel:
3237             {
3238               (void) GammaImageChannel(msl_info->image[n],RedChannel,pixel.red);
3239               break;
3240             }
3241             case GreenChannel:
3242             {
3243               (void) GammaImageChannel(msl_info->image[n],GreenChannel,
3244                 pixel.green);
3245               break;
3246             }
3247             case BlueChannel:
3248             {
3249               (void) GammaImageChannel(msl_info->image[n],BlueChannel,
3250                 pixel.blue);
3251               break;
3252             }
3253           }
3254           break;
3255         }
3256       else if (LocaleCompare((const char *) tag,"get") == 0)
3257         {
3258           if (msl_info->image[n] == (Image *) NULL)
3259             {
3260               ThrowMSLException(OptionError,"NoImagesDefined",
3261                 (const char *) tag);
3262               break;
3263             }
3264           if (attributes == (const xmlChar **) NULL)
3265             break;
3266           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3267           {
3268             keyword=(const char *) attributes[i++];
3269             CloneString(&value,(const char *) attributes[i]);
3270             (void) CopyMagickString(key,value,MaxTextExtent);
3271             switch (*keyword)
3272             {
3273               case 'H':
3274               case 'h':
3275               {
3276                 if (LocaleCompare(keyword,"height") == 0)
3277                   {
3278                     (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
3279                       (double) msl_info->image[n]->rows);
3280                     (void) SetImageProperty(msl_info->attributes[n],key,value);
3281                     break;
3282                   }
3283                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3284               }
3285               case 'W':
3286               case 'w':
3287               {
3288                 if (LocaleCompare(keyword,"width") == 0)
3289                   {
3290                     (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
3291                       (double) msl_info->image[n]->columns);
3292                     (void) SetImageProperty(msl_info->attributes[n],key,value);
3293                     break;
3294                   }
3295                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3296               }
3297               default:
3298               {
3299                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3300                 break;
3301               }
3302             }
3303           }
3304           break;
3305         }
3306     else if (LocaleCompare((const char *) tag, "group") == 0)
3307     {
3308       msl_info->number_groups++;
3309       msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3310         msl_info->group_info,msl_info->number_groups+1UL,
3311         sizeof(*msl_info->group_info));
3312       break;
3313     }
3314       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3315     }
3316     case 'I':
3317     case 'i':
3318     {
3319       if (LocaleCompare((const char *) tag,"image") == 0)
3320         {
3321           MSLPushImage(msl_info,(Image *) NULL);
3322           if (attributes == (const xmlChar **) NULL)
3323             break;
3324           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3325           {
3326             keyword=(const char *) attributes[i++];
3327             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
3328               msl_info->attributes[n],(const char *) attributes[i]));
3329             switch (*keyword)
3330             {
3331               case 'C':
3332               case 'c':
3333               {
3334                 if (LocaleCompare(keyword,"color") == 0)
3335                   {
3336                     Image
3337                       *next_image;
3338
3339                     (void) CopyMagickString(msl_info->image_info[n]->filename,
3340                       "xc:",MaxTextExtent);
3341                     (void) ConcatenateMagickString(msl_info->image_info[n]->
3342                       filename,value,MaxTextExtent);
3343                     next_image=ReadImage(msl_info->image_info[n],&exception);
3344                     CatchException(&exception);
3345                     if (next_image == (Image *) NULL)
3346                       continue;
3347                     if (msl_info->image[n] == (Image *) NULL)
3348                       msl_info->image[n]=next_image;
3349                     else
3350                       {
3351                         register Image
3352                           *p;
3353
3354                         /*
3355                           Link image into image list.
3356                         */
3357                         p=msl_info->image[n];
3358                         while (p->next != (Image *) NULL)
3359                           p=GetNextImageInList(p);
3360                         next_image->previous=p;
3361                         p->next=next_image;
3362                       }
3363                     break;
3364                   }
3365                 (void) SetMSLAttributes(msl_info,keyword,value);
3366                 break;
3367               }
3368               default:
3369               {
3370                 (void) SetMSLAttributes(msl_info,keyword,value);
3371                 break;
3372               }
3373             }
3374           }
3375           break;
3376         }
3377       if (LocaleCompare((const char *) tag,"implode") == 0)
3378         {
3379           Image
3380             *implode_image;
3381
3382           /*
3383             Implode image.
3384           */
3385           if (msl_info->image[n] == (Image *) NULL)
3386             {
3387               ThrowMSLException(OptionError,"NoImagesDefined",
3388                 (const char *) tag);
3389               break;
3390             }
3391           if (attributes != (const xmlChar **) NULL)
3392             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3393             {
3394               keyword=(const char *) attributes[i++];
3395               attribute=InterpretImageProperties(msl_info->image_info[n],
3396                 msl_info->attributes[n],(const char *) attributes[i]);
3397               CloneString(&value,attribute);
3398               switch (*keyword)
3399               {
3400                 case 'A':
3401                 case 'a':
3402                 {
3403                   if (LocaleCompare(keyword,"amount") == 0)
3404                     {
3405                       geometry_info.rho=InterpretLocaleValue(value,
3406                         (char **) NULL);
3407                       break;
3408                     }
3409                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3410                     keyword);
3411                   break;
3412                 }
3413                 case 'G':
3414                 case 'g':
3415                 {
3416                   if (LocaleCompare(keyword,"geometry") == 0)
3417                     {
3418                       flags=ParseGeometry(value,&geometry_info);
3419                       if ((flags & SigmaValue) == 0)
3420                         geometry_info.sigma=1.0;
3421                       break;
3422                     }
3423                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3424                     keyword);
3425                   break;
3426                 }
3427                 default:
3428                 {
3429                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3430                     keyword);
3431                   break;
3432                 }
3433               }
3434             }
3435           implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3436             &msl_info->image[n]->exception);
3437           if (implode_image == (Image *) NULL)
3438             break;
3439           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3440           msl_info->image[n]=implode_image;
3441           break;
3442         }
3443       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3444     }
3445     case 'L':
3446     case 'l':
3447     {
3448       if (LocaleCompare((const char *) tag,"label") == 0)
3449         break;
3450       if (LocaleCompare((const char *) tag, "level") == 0)
3451       {
3452         double
3453           levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3454
3455         if (msl_info->image[n] == (Image *) NULL)
3456         {
3457           ThrowMSLException(OptionError,"NoImagesDefined",
3458             (const char *) tag);
3459           break;
3460         }
3461         if (attributes == (const xmlChar **) NULL)
3462           break;
3463         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3464         {
3465           keyword=(const char *) attributes[i++];
3466           CloneString(&value,(const char *) attributes[i]);
3467           (void) CopyMagickString(key,value,MaxTextExtent);
3468           switch (*keyword)
3469           {
3470             case 'B':
3471             case 'b':
3472             {
3473               if (LocaleCompare(keyword,"black") == 0)
3474               {
3475                 levelBlack = InterpretLocaleValue(value,(char **) NULL);
3476                 break;
3477               }
3478               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3479               break;
3480             }
3481             case 'G':
3482             case 'g':
3483             {
3484               if (LocaleCompare(keyword,"gamma") == 0)
3485               {
3486                 levelGamma = InterpretLocaleValue(value,(char **) NULL);
3487                 break;
3488               }
3489               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3490               break;
3491             }
3492             case 'W':
3493             case 'w':
3494             {
3495               if (LocaleCompare(keyword,"white") == 0)
3496               {
3497                 levelWhite = InterpretLocaleValue(value,(char **) NULL);
3498                 break;
3499               }
3500               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3501               break;
3502             }
3503             default:
3504             {
3505               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3506               break;
3507             }
3508           }
3509         }
3510
3511         /* process image */
3512         LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma);
3513         break;
3514       }
3515     }
3516     case 'M':
3517     case 'm':
3518     {
3519       if (LocaleCompare((const char *) tag,"magnify") == 0)
3520         {
3521           Image
3522             *magnify_image;
3523
3524           /*
3525             Magnify image.
3526           */
3527           if (msl_info->image[n] == (Image *) NULL)
3528             {
3529               ThrowMSLException(OptionError,"NoImagesDefined",
3530                 (const char *) tag);
3531               break;
3532             }
3533           if (attributes != (const xmlChar **) NULL)
3534             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3535             {
3536               keyword=(const char *) attributes[i++];
3537               attribute=InterpretImageProperties(msl_info->image_info[n],
3538                 msl_info->attributes[n],(const char *) attributes[i]);
3539               CloneString(&value,attribute);
3540               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3541             }
3542           magnify_image=MagnifyImage(msl_info->image[n],
3543             &msl_info->image[n]->exception);
3544           if (magnify_image == (Image *) NULL)
3545             break;
3546           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3547           msl_info->image[n]=magnify_image;
3548           break;
3549         }
3550       if (LocaleCompare((const char *) tag,"map") == 0)
3551         {
3552           Image
3553             *affinity_image;
3554
3555           MagickBooleanType
3556             dither;
3557
3558           QuantizeInfo
3559             *quantize_info;
3560
3561           /*
3562             Map image.
3563           */
3564           if (msl_info->image[n] == (Image *) NULL)
3565             {
3566               ThrowMSLException(OptionError,"NoImagesDefined",
3567                 (const char *) tag);
3568               break;
3569             }
3570           affinity_image=NewImageList();
3571           dither=MagickFalse;
3572           if (attributes != (const xmlChar **) NULL)
3573             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3574             {
3575               keyword=(const char *) attributes[i++];
3576               attribute=InterpretImageProperties(msl_info->image_info[n],
3577                 msl_info->attributes[n],(const char *) attributes[i]);
3578               CloneString(&value,attribute);
3579               switch (*keyword)
3580               {
3581                 case 'D':
3582                 case 'd':
3583                 {
3584                   if (LocaleCompare(keyword,"dither") == 0)
3585                     {
3586                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
3587                         value);
3588                       if (option < 0)
3589                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3590                           value);
3591                       dither=(MagickBooleanType) option;
3592                       break;
3593                     }
3594                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3595                     keyword);
3596                   break;
3597                 }
3598                 case 'I':
3599                 case 'i':
3600                 {
3601                   if (LocaleCompare(keyword,"image") == 0)
3602                     for (j=0; j < msl_info->n; j++)
3603                     {
3604                       const char
3605                         *attribute;
3606
3607                       attribute=GetImageProperty(msl_info->attributes[j],"id");
3608                       if ((attribute != (const char *) NULL)  &&
3609                           (LocaleCompare(attribute,value) == 0))
3610                         {
3611                           affinity_image=CloneImage(msl_info->image[j],0,0,
3612                             MagickFalse,&exception);
3613                           break;
3614                         }
3615                     }
3616                   break;
3617                 }
3618                 default:
3619                 {
3620                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3621                     keyword);
3622                   break;
3623                 }
3624               }
3625             }
3626           quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3627           quantize_info->dither=dither;
3628           (void) RemapImages(quantize_info,msl_info->image[n],
3629             affinity_image);
3630           quantize_info=DestroyQuantizeInfo(quantize_info);
3631           affinity_image=DestroyImage(affinity_image);
3632           break;
3633         }
3634       if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
3635         {
3636           double
3637             opacity;
3638
3639           PixelInfo
3640             target;
3641
3642           PaintMethod
3643             paint_method;
3644
3645           /*
3646             Matte floodfill image.
3647           */
3648           opacity=0.0;
3649           if (msl_info->image[n] == (Image *) NULL)
3650             {
3651               ThrowMSLException(OptionError,"NoImagesDefined",
3652                 (const char *) tag);
3653               break;
3654             }
3655           SetGeometry(msl_info->image[n],&geometry);
3656           paint_method=FloodfillMethod;
3657           if (attributes != (const xmlChar **) NULL)
3658             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3659             {
3660               keyword=(const char *) attributes[i++];
3661               attribute=InterpretImageProperties(msl_info->image_info[n],
3662                 msl_info->attributes[n],(const char *) attributes[i]);
3663               CloneString(&value,attribute);
3664               switch (*keyword)
3665               {
3666                 case 'B':
3667                 case 'b':
3668                 {
3669                   if (LocaleCompare(keyword,"bordercolor") == 0)
3670                     {
3671                       (void) QueryMagickColor(value,&target,&exception);
3672                       paint_method=FillToBorderMethod;
3673                       break;
3674                     }
3675                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3676                     keyword);
3677                   break;
3678                 }
3679                 case 'F':
3680                 case 'f':
3681                 {
3682                   if (LocaleCompare(keyword,"fuzz") == 0)
3683                     {
3684                       msl_info->image[n]->fuzz=InterpretLocaleValue(value,
3685                         (char **) NULL);
3686                       break;
3687                     }
3688                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3689                     keyword);
3690                   break;
3691                 }
3692                 case 'G':
3693                 case 'g':
3694                 {
3695                   if (LocaleCompare(keyword,"geometry") == 0)
3696                     {
3697                       flags=ParsePageGeometry(msl_info->image[n],value,
3698                         &geometry,&exception);
3699                       if ((flags & HeightValue) == 0)
3700                         geometry.height=geometry.width;
3701                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
3702                         geometry.x,geometry.y,&target,&exception);
3703                       break;
3704                     }
3705                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3706                     keyword);
3707                   break;
3708                 }
3709                 case 'O':
3710                 case 'o':
3711                 {
3712                   if (LocaleCompare(keyword,"opacity") == 0)
3713                     {
3714                       opacity=InterpretLocaleValue(value,(char **) NULL);
3715                       break;
3716                     }
3717                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3718                     keyword);
3719                   break;
3720                 }
3721                 case 'X':
3722                 case 'x':
3723                 {
3724                   if (LocaleCompare(keyword,"x") == 0)
3725                     {
3726                       geometry.x=StringToLong(value);
3727                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
3728                         geometry.x,geometry.y,&target,&exception);
3729                       break;
3730                     }
3731                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3732                     keyword);
3733                   break;
3734                 }
3735                 case 'Y':
3736                 case 'y':
3737                 {
3738                   if (LocaleCompare(keyword,"y") == 0)
3739                     {
3740                       geometry.y=StringToLong(value);
3741                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
3742                         geometry.x,geometry.y,&target,&exception);
3743                       break;
3744                     }
3745                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3746                     keyword);
3747                   break;
3748                 }
3749                 default:
3750                 {
3751                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3752                     keyword);
3753                   break;
3754                 }
3755               }
3756             }
3757           draw_info=CloneDrawInfo(msl_info->image_info[n],
3758             msl_info->draw_info[n]);
3759           draw_info->fill.alpha=ClampToQuantum(opacity);
3760           (void) FloodfillPaintImage(msl_info->image[n],OpacityChannel,
3761             draw_info,&target,geometry.x,geometry.y,
3762             paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
3763           draw_info=DestroyDrawInfo(draw_info);
3764           break;
3765         }
3766       if (LocaleCompare((const char *) tag,"median-filter") == 0)
3767         {
3768           Image
3769             *median_image;
3770
3771           /*
3772             Median-filter image.
3773           */
3774           if (msl_info->image[n] == (Image *) NULL)
3775             {
3776               ThrowMSLException(OptionError,"NoImagesDefined",
3777                 (const char *) tag);
3778               break;
3779             }
3780           if (attributes != (const xmlChar **) NULL)
3781             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3782             {
3783               keyword=(const char *) attributes[i++];
3784               attribute=InterpretImageProperties(msl_info->image_info[n],
3785                 msl_info->attributes[n],(const char *) attributes[i]);
3786               CloneString(&value,attribute);
3787               switch (*keyword)
3788               {
3789                 case 'G':
3790                 case 'g':
3791                 {
3792                   if (LocaleCompare(keyword,"geometry") == 0)
3793                     {
3794                       flags=ParseGeometry(value,&geometry_info);
3795                       if ((flags & SigmaValue) == 0)
3796                         geometry_info.sigma=1.0;
3797                       break;
3798                     }
3799                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3800                     keyword);
3801                   break;
3802                 }
3803                 case 'R':
3804                 case 'r':
3805                 {
3806                   if (LocaleCompare(keyword,"radius") == 0)
3807                     {
3808                       geometry_info.rho=InterpretLocaleValue(value,
3809                         (char **) NULL);
3810                       break;
3811                     }
3812                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3813                     keyword);
3814                   break;
3815                 }
3816                 default:
3817                 {
3818                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3819                     keyword);
3820                   break;
3821                 }
3822               }
3823             }
3824           median_image=StatisticImage(msl_info->image[n],MedianStatistic,
3825             (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3826             &msl_info->image[n]->exception);
3827           if (median_image == (Image *) NULL)
3828             break;
3829           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3830           msl_info->image[n]=median_image;
3831           break;
3832         }
3833       if (LocaleCompare((const char *) tag,"minify") == 0)
3834         {
3835           Image
3836             *minify_image;
3837
3838           /*
3839             Minify image.
3840           */
3841           if (msl_info->image[n] == (Image *) NULL)
3842             {
3843               ThrowMSLException(OptionError,"NoImagesDefined",
3844                 (const char *) tag);
3845               break;
3846             }
3847           if (attributes != (const xmlChar **) NULL)
3848             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3849             {
3850               keyword=(const char *) attributes[i++];
3851               attribute=InterpretImageProperties(msl_info->image_info[n],
3852                 msl_info->attributes[n],(const char *) attributes[i]);
3853               CloneString(&value,attribute);
3854               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3855             }
3856           minify_image=MinifyImage(msl_info->image[n],
3857             &msl_info->image[n]->exception);
3858           if (minify_image == (Image *) NULL)
3859             break;
3860           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3861           msl_info->image[n]=minify_image;
3862           break;
3863         }
3864       if (LocaleCompare((const char *) tag,"msl") == 0 )
3865         break;
3866       if (LocaleCompare((const char *) tag,"modulate") == 0)
3867         {
3868           char
3869             modulate[MaxTextExtent];
3870
3871           /*
3872             Modulate image.
3873           */
3874           if (msl_info->image[n] == (Image *) NULL)
3875             {
3876               ThrowMSLException(OptionError,"NoImagesDefined",
3877                 (const char *) tag);
3878               break;
3879             }
3880           geometry_info.rho=100.0;
3881           geometry_info.sigma=100.0;
3882           geometry_info.xi=100.0;
3883           if (attributes != (const xmlChar **) NULL)
3884             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3885             {
3886               keyword=(const char *) attributes[i++];
3887               attribute=InterpretImageProperties(msl_info->image_info[n],
3888                 msl_info->attributes[n],(const char *) attributes[i]);
3889               CloneString(&value,attribute);
3890               switch (*keyword)
3891               {
3892                 case 'B':
3893                 case 'b':
3894                 {
3895                   if (LocaleCompare(keyword,"blackness") == 0)
3896                     {
3897                       geometry_info.rho=InterpretLocaleValue(value,
3898                         (char **) NULL);
3899                       break;
3900                     }
3901                   if (LocaleCompare(keyword,"brightness") == 0)
3902                     {
3903                       geometry_info.rho=InterpretLocaleValue(value,
3904                         (char **) NULL);
3905                       break;
3906                     }
3907                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3908                     keyword);
3909                   break;
3910                 }
3911                 case 'F':
3912                 case 'f':
3913                 {
3914                   if (LocaleCompare(keyword,"factor") == 0)
3915                     {
3916                       flags=ParseGeometry(value,&geometry_info);
3917                       break;
3918                     }
3919                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3920                     keyword);
3921                   break;
3922                 }
3923                 case 'H':
3924                 case 'h':
3925                 {
3926                   if (LocaleCompare(keyword,"hue") == 0)
3927                     {
3928                       geometry_info.xi=InterpretLocaleValue(value,
3929                         (char **) NULL);
3930                       break;
3931                     }
3932                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3933                     keyword);
3934                   break;
3935                 }
3936                 case 'L':
3937                 case 'l':
3938                 {
3939                   if (LocaleCompare(keyword,"lightness") == 0)
3940                     {
3941                       geometry_info.rho=InterpretLocaleValue(value,
3942                         (char **) NULL);
3943                       break;
3944                     }
3945                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3946                     keyword);
3947                   break;
3948                 }
3949                 case 'S':
3950                 case 's':
3951                 {
3952                   if (LocaleCompare(keyword,"saturation") == 0)
3953                     {
3954                       geometry_info.sigma=InterpretLocaleValue(value,
3955                         (char **) NULL);
3956                       break;
3957                     }
3958                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3959                     keyword);
3960                   break;
3961                 }
3962                 case 'W':
3963                 case 'w':
3964                 {
3965                   if (LocaleCompare(keyword,"whiteness") == 0)
3966                     {
3967                       geometry_info.sigma=InterpretLocaleValue(value,
3968                         (char **) NULL);
3969                       break;
3970                     }
3971                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3972                     keyword);
3973                   break;
3974                 }
3975                 default:
3976                 {
3977                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3978                     keyword);
3979                   break;
3980                 }
3981               }
3982             }
3983           (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
3984             geometry_info.rho,geometry_info.sigma,geometry_info.xi);
3985           (void) ModulateImage(msl_info->image[n],modulate);
3986           break;
3987         }
3988       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3989     }
3990     case 'N':
3991     case 'n':
3992     {
3993       if (LocaleCompare((const char *) tag,"negate") == 0)
3994         {
3995           MagickBooleanType
3996             gray;
3997
3998           /*
3999             Negate image.
4000           */
4001           if (msl_info->image[n] == (Image *) NULL)
4002             {
4003               ThrowMSLException(OptionError,"NoImagesDefined",
4004                 (const char *) tag);
4005               break;
4006             }
4007           gray=MagickFalse;
4008           if (attributes != (const xmlChar **) NULL)
4009             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4010             {
4011               keyword=(const char *) attributes[i++];
4012               attribute=InterpretImageProperties(msl_info->image_info[n],
4013                 msl_info->attributes[n],(const char *) attributes[i]);
4014               CloneString(&value,attribute);
4015               switch (*keyword)
4016               {
4017                 case 'C':
4018                 case 'c':
4019                 {
4020                   if (LocaleCompare(keyword,"channel") == 0)
4021                     {
4022                       option=ParseChannelOption(value);
4023                       if (option < 0)
4024                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4025                           value);
4026                       channel=(ChannelType) option;
4027                       break;
4028                     }
4029                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4030                     keyword);
4031                   break;
4032                 }
4033                 case 'G':
4034                 case 'g':
4035                 {
4036                   if (LocaleCompare(keyword,"gray") == 0)
4037                     {
4038                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4039                         value);
4040                       if (option < 0)
4041                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4042                           value);
4043                       gray=(MagickBooleanType) option;
4044                       break;
4045                     }
4046                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4047                     keyword);
4048                   break;
4049                 }
4050                 default:
4051                 {
4052                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4053                     keyword);
4054                   break;
4055                 }
4056               }
4057             }
4058           (void) NegateImageChannel(msl_info->image[n],channel,gray);
4059           break;
4060         }
4061       if (LocaleCompare((const char *) tag,"normalize") == 0)
4062         {
4063           /*
4064             Normalize image.
4065           */
4066           if (msl_info->image[n] == (Image *) NULL)
4067             {
4068               ThrowMSLException(OptionError,"NoImagesDefined",
4069                 (const char *) tag);
4070               break;
4071             }
4072           if (attributes != (const xmlChar **) NULL)
4073             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4074             {
4075               keyword=(const char *) attributes[i++];
4076               attribute=InterpretImageProperties(msl_info->image_info[n],
4077                 msl_info->attributes[n],(const char *) attributes[i]);
4078               CloneString(&value,attribute);
4079               switch (*keyword)
4080               {
4081                 case 'C':
4082                 case 'c':
4083                 {
4084                   if (LocaleCompare(keyword,"channel") == 0)
4085                     {
4086                       option=ParseChannelOption(value);
4087                       if (option < 0)
4088                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4089                           value);
4090                       channel=(ChannelType) option;
4091                       break;
4092                     }
4093                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4094                     keyword);
4095                   break;
4096                 }
4097                 default:
4098                 {
4099                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4100                     keyword);
4101                   break;
4102                 }
4103               }
4104             }
4105           (void) NormalizeImageChannel(msl_info->image[n],channel);
4106           break;
4107         }
4108       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4109     }
4110     case 'O':
4111     case 'o':
4112     {
4113       if (LocaleCompare((const char *) tag,"oil-paint") == 0)
4114         {
4115           Image
4116             *paint_image;
4117
4118           /*
4119             Oil-paint image.
4120           */
4121           if (msl_info->image[n] == (Image *) NULL)
4122             {
4123               ThrowMSLException(OptionError,"NoImagesDefined",
4124                 (const char *) tag);
4125               break;
4126             }
4127           if (attributes != (const xmlChar **) NULL)
4128             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4129             {
4130               keyword=(const char *) attributes[i++];
4131               attribute=InterpretImageProperties(msl_info->image_info[n],
4132                 msl_info->attributes[n],(const char *) attributes[i]);
4133               CloneString(&value,attribute);
4134               switch (*keyword)
4135               {
4136                 case 'G':
4137                 case 'g':
4138                 {
4139                   if (LocaleCompare(keyword,"geometry") == 0)
4140                     {
4141                       flags=ParseGeometry(value,&geometry_info);
4142                       if ((flags & SigmaValue) == 0)
4143                         geometry_info.sigma=1.0;
4144                       break;
4145                     }
4146                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4147                     keyword);
4148                   break;
4149                 }
4150                 case 'R':
4151                 case 'r':
4152                 {
4153                   if (LocaleCompare(keyword,"radius") == 0)
4154                     {
4155                       geometry_info.rho=InterpretLocaleValue(value,
4156                         (char **) NULL);
4157                       break;
4158                     }
4159                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4160                     keyword);
4161                   break;
4162                 }
4163                 default:
4164                 {
4165                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4166                     keyword);
4167                   break;
4168                 }
4169               }
4170             }
4171           paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4172             &msl_info->image[n]->exception);
4173           if (paint_image == (Image *) NULL)
4174             break;
4175           msl_info->image[n]=DestroyImage(msl_info->image[n]);
4176           msl_info->image[n]=paint_image;
4177           break;
4178         }
4179       if (LocaleCompare((const char *) tag,"opaque") == 0)
4180         {
4181           PixelInfo
4182             fill_color,
4183             target;
4184
4185           /*
4186             Opaque image.
4187           */
4188           if (msl_info->image[n] == (Image *) NULL)
4189             {
4190               ThrowMSLException(OptionError,"NoImagesDefined",
4191                 (const char *) tag);
4192               break;
4193             }
4194           (void) QueryMagickColor("none",&target,&exception);
4195           (void) QueryMagickColor("none",&fill_color,&exception);
4196           if (attributes != (const xmlChar **) NULL)
4197             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4198             {
4199               keyword=(const char *) attributes[i++];
4200               attribute=InterpretImageProperties(msl_info->image_info[n],
4201                 msl_info->attributes[n],(const char *) attributes[i]);
4202               CloneString(&value,attribute);
4203               switch (*keyword)
4204               {
4205                 case 'C':
4206                 case 'c':
4207                 {
4208                   if (LocaleCompare(keyword,"channel") == 0)
4209                     {
4210                       option=ParseChannelOption(value);
4211                       if (option < 0)
4212                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4213                           value);
4214                       channel=(ChannelType) option;
4215                       break;
4216                     }
4217                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4218                     keyword);
4219                   break;
4220                 }
4221                 case 'F':
4222                 case 'f':
4223                 {
4224                   if (LocaleCompare(keyword,"fill") == 0)
4225                     {
4226                       (void) QueryMagickColor(value,&fill_color,&exception);
4227                       break;
4228                     }
4229                   if (LocaleCompare(keyword,"fuzz") == 0)
4230                     {
4231                       msl_info->image[n]->fuzz=InterpretLocaleValue(value,
4232                         (char **) NULL);
4233                       break;
4234                     }
4235                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4236                     keyword);
4237                   break;
4238                 }
4239                 default:
4240                 {
4241                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4242                     keyword);
4243                   break;
4244                 }
4245               }
4246             }
4247           (void) OpaquePaintImageChannel(msl_info->image[n],channel,
4248             &target,&fill_color,MagickFalse);
4249           break;
4250         }
4251       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4252     }
4253     case 'P':
4254     case 'p':
4255     {
4256       if (LocaleCompare((const char *) tag,"print") == 0)
4257         {
4258           if (attributes == (const xmlChar **) NULL)
4259             break;
4260           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4261           {
4262             keyword=(const char *) attributes[i++];
4263             attribute=InterpretImageProperties(msl_info->image_info[n],
4264               msl_info->attributes[n],(const char *) attributes[i]);
4265             CloneString(&value,attribute);
4266             switch (*keyword)
4267             {
4268               case 'O':
4269               case 'o':
4270               {
4271                 if (LocaleCompare(keyword,"output") == 0)
4272                   {
4273                     (void) FormatLocaleFile(stdout,"%s",value);
4274                     break;
4275                   }
4276                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4277                 break;
4278               }
4279               default:
4280               {
4281                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4282                 break;
4283               }
4284             }
4285           }
4286           break;
4287         }
4288         if (LocaleCompare((const char *) tag, "profile") == 0)
4289           {
4290             if (msl_info->image[n] == (Image *) NULL)
4291               {
4292                 ThrowMSLException(OptionError,"NoImagesDefined",
4293                   (const char *) tag);
4294                 break;
4295               }
4296             if (attributes == (const xmlChar **) NULL)
4297               break;
4298             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4299             {
4300               const char
4301                 *name;
4302
4303               const StringInfo
4304                 *profile;
4305
4306               Image
4307                 *profile_image;
4308
4309               ImageInfo
4310                 *profile_info;
4311
4312               keyword=(const char *) attributes[i++];
4313               attribute=InterpretImageProperties(msl_info->image_info[n],
4314                 msl_info->attributes[n],(const char *) attributes[i]);
4315               CloneString(&value,attribute);
4316               if (*keyword == '+')
4317                 {
4318                   /*
4319                     Remove a profile from the image.
4320                   */
4321                   (void) ProfileImage(msl_info->image[n],keyword,
4322                     (const unsigned char *) NULL,0,MagickTrue);
4323                   continue;
4324                 }
4325               /*
4326                 Associate a profile with the image.
4327               */
4328               profile_info=CloneImageInfo(msl_info->image_info[n]);
4329               profile=GetImageProfile(msl_info->image[n],"iptc");
4330               if (profile != (StringInfo *) NULL)
4331                 profile_info->profile=(void *) CloneStringInfo(profile);
4332               profile_image=GetImageCache(profile_info,keyword,&exception);
4333               profile_info=DestroyImageInfo(profile_info);
4334               if (profile_image == (Image *) NULL)
4335                 {
4336                   char
4337                     name[MaxTextExtent],
4338                     filename[MaxTextExtent];
4339
4340                   register char
4341                     *p;
4342
4343                   StringInfo
4344                     *profile;
4345
4346                   (void) CopyMagickString(filename,keyword,MaxTextExtent);
4347                   (void) CopyMagickString(name,keyword,MaxTextExtent);
4348                   for (p=filename; *p != '\0'; p++)
4349                     if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4350                         (IsPathAccessible(keyword) == MagickFalse))
4351                       {
4352                         register char
4353                           *q;
4354
4355                         /*
4356                           Look for profile name (e.g. name:profile).
4357                         */
4358                         (void) CopyMagickString(name,filename,(size_t)
4359                           (p-filename+1));
4360                         for (q=filename; *q != '\0'; q++)
4361                           *q=(*++p);
4362                         break;
4363                       }
4364                   profile=FileToStringInfo(filename,~0UL,&exception);
4365                   if (profile != (StringInfo *) NULL)
4366                     {
4367                       (void) ProfileImage(msl_info->image[n],name,
4368                         GetStringInfoDatum(profile),(size_t)
4369                         GetStringInfoLength(profile),MagickFalse);
4370                       profile=DestroyStringInfo(profile);
4371                     }
4372                   continue;
4373                 }
4374               ResetImageProfileIterator(profile_image);
4375               name=GetNextImageProfile(profile_image);
4376               while (name != (const char *) NULL)
4377               {
4378                 profile=GetImageProfile(profile_image,name);
4379                 if (profile != (StringInfo *) NULL)
4380                   (void) ProfileImage(msl_info->image[n],name,
4381                     GetStringInfoDatum(profile),(size_t)
4382                     GetStringInfoLength(profile),MagickFalse);
4383                 name=GetNextImageProfile(profile_image);
4384               }
4385               profile_image=DestroyImage(profile_image);
4386             }
4387             break;
4388           }
4389       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4390     }
4391     case 'Q':
4392     case 'q':
4393     {
4394       if (LocaleCompare((const char *) tag,"quantize") == 0)
4395         {
4396           QuantizeInfo
4397             quantize_info;
4398
4399           /*
4400             Quantize image.
4401           */
4402           if (msl_info->image[n] == (Image *) NULL)
4403             {
4404               ThrowMSLException(OptionError,"NoImagesDefined",
4405                 (const char *) tag);
4406               break;
4407             }
4408           GetQuantizeInfo(&quantize_info);
4409           if (attributes != (const xmlChar **) NULL)
4410             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4411             {
4412               keyword=(const char *) attributes[i++];
4413               attribute=InterpretImageProperties(msl_info->image_info[n],
4414                 msl_info->attributes[n],(const char *) attributes[i]);
4415               CloneString(&value,attribute);
4416               switch (*keyword)
4417               {
4418                 case 'C':
4419                 case 'c':
4420                 {
4421                   if (LocaleCompare(keyword,"colors") == 0)
4422                     {
4423                       quantize_info.number_colors=StringToLong(value);
4424                       break;
4425                     }
4426                   if (LocaleCompare(keyword,"colorspace") == 0)
4427                     {
4428                       option=ParseCommandOption(MagickColorspaceOptions,
4429                         MagickFalse,value);
4430                       if (option < 0)
4431                         ThrowMSLException(OptionError,
4432                           "UnrecognizedColorspaceType",value);
4433                       quantize_info.colorspace=(ColorspaceType) option;
4434                       break;
4435                     }
4436                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4437                     keyword);
4438                   break;
4439                 }
4440                 case 'D':
4441                 case 'd':
4442                 {
4443                   if (LocaleCompare(keyword,"dither") == 0)
4444                     {
4445                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4446                         value);
4447                       if (option < 0)
4448                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4449                           value);
4450                       quantize_info.dither=(MagickBooleanType) option;
4451                       break;
4452                     }
4453                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4454                     keyword);
4455                   break;
4456                 }
4457                 case 'M':
4458                 case 'm':
4459                 {
4460                   if (LocaleCompare(keyword,"measure") == 0)
4461                     {
4462                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4463                         value);
4464                       if (option < 0)
4465                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4466                           value);
4467                       quantize_info.measure_error=(MagickBooleanType) option;
4468                       break;
4469                     }
4470                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4471                     keyword);
4472                   break;
4473                 }
4474                 case 'T':
4475                 case 't':
4476                 {
4477                   if (LocaleCompare(keyword,"treedepth") == 0)
4478                     {
4479                       quantize_info.tree_depth=StringToLong(value);
4480                       break;
4481                     }
4482                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4483                     keyword);
4484                   break;
4485                 }
4486                 default:
4487                 {
4488                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4489                     keyword);
4490                   break;
4491                 }
4492               }
4493             }
4494           (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4495           break;
4496         }
4497       if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
4498         {
4499           char
4500             text[MaxTextExtent];
4501
4502           MagickBooleanType
4503             status;
4504
4505           TypeMetric
4506             metrics;
4507
4508           /*
4509             Query font metrics.
4510           */
4511           draw_info=CloneDrawInfo(msl_info->image_info[n],
4512             msl_info->draw_info[n]);
4513           angle=0.0;
4514           current=draw_info->affine;
4515           GetAffineMatrix(&affine);
4516           if (attributes != (const xmlChar **) NULL)
4517             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4518             {
4519               keyword=(const char *) attributes[i++];
4520               attribute=InterpretImageProperties(msl_info->image_info[n],
4521                 msl_info->attributes[n],(const char *) attributes[i]);
4522               CloneString(&value,attribute);
4523               switch (*keyword)
4524               {
4525                 case 'A':
4526                 case 'a':
4527                 {
4528                   if (LocaleCompare(keyword,"affine") == 0)
4529                     {
4530                       char
4531                         *p;
4532
4533                       p=value;
4534                       draw_info->affine.sx=InterpretLocaleValue(p,&p);
4535                       if (*p ==',')
4536                         p++;
4537                       draw_info->affine.rx=InterpretLocaleValue(p,&p);
4538                       if (*p ==',')
4539                         p++;
4540                       draw_info->affine.ry=InterpretLocaleValue(p,&p);
4541                       if (*p ==',')
4542                         p++;
4543                       draw_info->affine.sy=InterpretLocaleValue(p,&p);
4544                       if (*p ==',')
4545                         p++;
4546                       draw_info->affine.tx=InterpretLocaleValue(p,&p);
4547                       if (*p ==',')
4548                         p++;
4549                       draw_info->affine.ty=InterpretLocaleValue(p,&p);
4550                       break;
4551                     }
4552                   if (LocaleCompare(keyword,"align") == 0)
4553                     {
4554                       option=ParseCommandOption(MagickAlignOptions,MagickFalse,
4555                         value);
4556                       if (option < 0)
4557                         ThrowMSLException(OptionError,"UnrecognizedAlignType",
4558                           value);
4559                       draw_info->align=(AlignType) option;
4560                       break;
4561                     }
4562                   if (LocaleCompare(keyword,"antialias") == 0)
4563                     {
4564                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4565                         value);
4566                       if (option < 0)
4567                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4568                           value);
4569                       draw_info->stroke_antialias=(MagickBooleanType) option;
4570                       draw_info->text_antialias=(MagickBooleanType) option;
4571                       break;
4572                     }
4573                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4574                     keyword);
4575                   break;
4576                 }
4577                 case 'D':
4578                 case 'd':
4579                 {
4580                   if (LocaleCompare(keyword,"density") == 0)
4581                     {
4582                       CloneString(&draw_info->density,value);
4583                       break;
4584                     }
4585                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4586                     keyword);
4587                   break;
4588                 }
4589                 case 'E':
4590                 case 'e':
4591                 {
4592                   if (LocaleCompare(keyword,"encoding") == 0)
4593                     {
4594                       CloneString(&draw_info->encoding,value);
4595                       break;
4596                     }
4597                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4598                     keyword);
4599                   break;
4600                 }
4601                 case 'F':
4602                 case 'f':
4603                 {
4604                   if (LocaleCompare(keyword, "fill") == 0)
4605                     {
4606                       (void) QueryColorDatabase(value,&draw_info->fill,
4607                         &exception);
4608                       break;
4609                     }
4610                   if (LocaleCompare(keyword,"family") == 0)
4611                     {
4612                       CloneString(&draw_info->family,value);
4613                       break;
4614                     }
4615                   if (LocaleCompare(keyword,"font") == 0)
4616                     {
4617                       CloneString(&draw_info->font,value);
4618                       break;
4619                     }
4620                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4621                     keyword);
4622                   break;
4623                 }
4624                 case 'G':
4625                 case 'g':
4626                 {
4627                   if (LocaleCompare(keyword,"geometry") == 0)
4628                     {
4629                       flags=ParsePageGeometry(msl_info->image[n],value,
4630                         &geometry,&exception);
4631                       if ((flags & HeightValue) == 0)
4632                         geometry.height=geometry.width;
4633                       break;
4634                     }
4635                   if (LocaleCompare(keyword,"gravity") == 0)
4636                     {
4637                       option=ParseCommandOption(MagickGravityOptions,MagickFalse,
4638                         value);
4639                       if (option < 0)
4640                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
4641                           value);
4642                       draw_info->gravity=(GravityType) option;
4643                       break;
4644                     }
4645                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4646                     keyword);
4647                   break;
4648                 }
4649                 case 'P':
4650                 case 'p':
4651                 {
4652                   if (LocaleCompare(keyword,"pointsize") == 0)
4653                     {
4654                       draw_info->pointsize=InterpretLocaleValue(value,
4655                         (char **) NULL);
4656                       break;
4657                     }
4658                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4659                     keyword);
4660                   break;
4661                 }
4662                 case 'R':
4663                 case 'r':
4664                 {
4665                   if (LocaleCompare(keyword,"rotate") == 0)
4666                     {
4667                       angle=InterpretLocaleValue(value,(char **) NULL);
4668                       affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4669                       affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4670                       affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4671                       affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4672                       break;
4673                     }
4674                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4675                     keyword);
4676                   break;
4677                 }
4678                 case 'S':
4679                 case 's':
4680                 {
4681                   if (LocaleCompare(keyword,"scale") == 0)
4682                     {
4683                       flags=ParseGeometry(value,&geometry_info);
4684                       if ((flags & SigmaValue) == 0)
4685                         geometry_info.sigma=1.0;
4686                       affine.sx=geometry_info.rho;
4687                       affine.sy=geometry_info.sigma;
4688                       break;
4689                     }
4690                   if (LocaleCompare(keyword,"skewX") == 0)
4691                     {
4692                       angle=InterpretLocaleValue(value,(char **) NULL);
4693                       affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4694                       break;
4695                     }
4696                   if (LocaleCompare(keyword,"skewY") == 0)
4697                     {
4698                       angle=InterpretLocaleValue(value,(char **) NULL);
4699                       affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4700                       break;
4701                     }
4702                   if (LocaleCompare(keyword,"stretch") == 0)
4703                     {
4704                       option=ParseCommandOption(MagickStretchOptions,MagickFalse,
4705                         value);
4706                       if (option < 0)
4707                         ThrowMSLException(OptionError,"UnrecognizedStretchType",
4708                           value);
4709                       draw_info->stretch=(StretchType) option;
4710                       break;
4711                     }
4712                   if (LocaleCompare(keyword, "stroke") == 0)
4713                     {
4714                       (void) QueryColorDatabase(value,&draw_info->stroke,
4715                         &exception);
4716                       break;
4717                     }
4718                   if (LocaleCompare(keyword,"strokewidth") == 0)
4719                     {
4720                       draw_info->stroke_width=StringToLong(value);
4721                       break;
4722                     }
4723                   if (LocaleCompare(keyword,"style") == 0)
4724                     {
4725                       option=ParseCommandOption(MagickStyleOptions,MagickFalse,
4726                         value);
4727                       if (option < 0)
4728                         ThrowMSLException(OptionError,"UnrecognizedStyleType",
4729                           value);
4730                       draw_info->style=(StyleType) option;
4731                       break;
4732                     }
4733                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4734                     keyword);
4735                   break;
4736                 }
4737                 case 'T':
4738                 case 't':
4739                 {
4740                   if (LocaleCompare(keyword,"text") == 0)
4741                     {
4742                       CloneString(&draw_info->text,value);
4743                       break;
4744                     }
4745                   if (LocaleCompare(keyword,"translate") == 0)
4746                     {
4747                       flags=ParseGeometry(value,&geometry_info);
4748                       if ((flags & SigmaValue) == 0)
4749                         geometry_info.sigma=1.0;
4750                       affine.tx=geometry_info.rho;
4751                       affine.ty=geometry_info.sigma;
4752                       break;
4753                     }
4754                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4755                     keyword);
4756                   break;
4757                 }
4758                 case 'U':
4759                 case 'u':
4760                 {
4761                   if (LocaleCompare(keyword, "undercolor") == 0)
4762                     {
4763                       (void) QueryColorDatabase(value,&draw_info->undercolor,
4764                         &exception);
4765                       break;
4766                     }
4767                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4768                     keyword);
4769                   break;
4770                 }
4771                 case 'W':
4772                 case 'w':
4773                 {
4774                   if (LocaleCompare(keyword,"weight") == 0)
4775                     {
4776                       draw_info->weight=StringToLong(value);
4777                       break;
4778                     }
4779                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4780                     keyword);
4781                   break;
4782                 }
4783                 case 'X':
4784                 case 'x':
4785                 {
4786                   if (LocaleCompare(keyword,"x") == 0)
4787                     {
4788                       geometry.x=StringToLong(value);
4789                       break;
4790                     }
4791                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4792                     keyword);
4793                   break;
4794                 }
4795                 case 'Y':
4796                 case 'y':
4797                 {
4798                   if (LocaleCompare(keyword,"y") == 0)
4799                     {
4800                       geometry.y=StringToLong(value);
4801                       break;
4802                     }
4803                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4804                     keyword);
4805                   break;
4806                 }
4807                 default:
4808                 {
4809                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4810                     keyword);
4811                   break;
4812                 }
4813               }
4814             }
4815           (void) FormatLocaleString(text,MaxTextExtent,
4816             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4817             geometry.height,(double) geometry.x,(double) geometry.y);
4818           CloneString(&draw_info->geometry,text);
4819           draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4820           draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4821           draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4822           draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4823           draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4824             affine.tx;
4825           draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4826             affine.ty;
4827           status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4828           if (status != MagickFalse)
4829             {
4830               Image
4831                 *image;
4832
4833               image=msl_info->attributes[n];
4834               FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
4835                 "%g",metrics.pixels_per_em.x);
4836               FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
4837                 "%g",metrics.pixels_per_em.y);
4838               FormatImageProperty(image,"msl:font-metrics.ascent","%g",
4839                 metrics.ascent);
4840               FormatImageProperty(image,"msl:font-metrics.descent","%g",
4841                 metrics.descent);
4842               FormatImageProperty(image,"msl:font-metrics.width","%g",
4843                 metrics.width);
4844               FormatImageProperty(image,"msl:font-metrics.height","%g",
4845                 metrics.height);
4846               FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
4847                 metrics.max_advance);
4848               FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
4849                 metrics.bounds.x1);
4850               FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
4851                 metrics.bounds.y1);
4852               FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
4853                 metrics.bounds.x2);
4854               FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
4855                 metrics.bounds.y2);
4856               FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
4857                 metrics.origin.x);
4858               FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
4859                 metrics.origin.y);
4860             }
4861           draw_info=DestroyDrawInfo(draw_info);
4862           break;
4863         }
4864       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4865     }
4866     case 'R':
4867     case 'r':
4868     {
4869       if (LocaleCompare((const char *) tag,"raise") == 0)
4870         {
4871           MagickBooleanType
4872             raise;
4873
4874           /*
4875             Raise image.
4876           */
4877           if (msl_info->image[n] == (Image *) NULL)
4878             {
4879               ThrowMSLException(OptionError,"NoImagesDefined",
4880                 (const char *) tag);
4881               break;
4882             }
4883           raise=MagickFalse;
4884           SetGeometry(msl_info->image[n],&geometry);
4885           if (attributes != (const xmlChar **) NULL)
4886             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4887             {
4888               keyword=(const char *) attributes[i++];
4889               attribute=InterpretImageProperties(msl_info->image_info[n],
4890                 msl_info->attributes[n],(const char *) attributes[i]);
4891               CloneString(&value,attribute);
4892               switch (*keyword)
4893               {
4894                 case 'G':
4895                 case 'g':
4896                 {
4897                   if (LocaleCompare(keyword,"geometry") == 0)
4898                     {
4899                       flags=ParsePageGeometry(msl_info->image[n],value,
4900                         &geometry,&exception);
4901                       if ((flags & HeightValue) == 0)
4902                         geometry.height=geometry.width;
4903                       break;
4904                     }
4905                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4906                     keyword);
4907                   break;
4908                 }
4909                 case 'H':
4910                 case 'h':
4911                 {
4912                   if (LocaleCompare(keyword,"height") == 0)
4913                     {
4914                       geometry.height=StringToLong(value);
4915                       break;
4916                     }
4917                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4918                     keyword);
4919                   break;
4920                 }
4921                 case 'R':
4922                 case 'r':
4923                 {
4924                   if (LocaleCompare(keyword,"raise") == 0)
4925                     {
4926                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4927                         value);
4928                       if (option < 0)
4929                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4930                           value);
4931                       raise=(MagickBooleanType) option;
4932                       break;
4933                     }
4934                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4935                     keyword);
4936                   break;
4937                 }
4938                 case 'W':
4939                 case 'w':
4940                 {
4941                   if (LocaleCompare(keyword,"width") == 0)
4942                     {
4943                       geometry.width=StringToLong(value);
4944                       break;
4945                     }
4946                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4947                     keyword);
4948                   break;
4949                 }
4950                 default:
4951                 {
4952                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4953                     keyword);
4954                   break;
4955                 }
4956               }
4957             }
4958           (void) RaiseImage(msl_info->image[n],&geometry,raise);
4959           break;
4960         }
4961       if (LocaleCompare((const char *) tag,"read") == 0)
4962         {
4963           if (attributes == (const xmlChar **) NULL)
4964             break;
4965           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4966           {
4967             keyword=(const char *) attributes[i++];
4968             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
4969               msl_info->attributes[n],(const char *) attributes[i]));
4970             switch (*keyword)
4971             {
4972               case 'F':
4973               case 'f':
4974               {
4975                 if (LocaleCompare(keyword,"filename") == 0)
4976                   {
4977                     Image
4978                       *image;
4979
4980                     (void) CopyMagickString(msl_info->image_info[n]->filename,
4981                       value,MaxTextExtent);
4982                     image=ReadImage(msl_info->image_info[n],&exception);
4983                     CatchException(&exception);
4984                     if (image == (Image *) NULL)
4985                       continue;
4986                     AppendImageToList(&msl_info->image[n],image);
4987                     break;
4988                   }
4989                 (void) SetMSLAttributes(msl_info,keyword,value);
4990                 break;
4991               }
4992               default:
4993               {
4994                 (void) SetMSLAttributes(msl_info,keyword,value);
4995                 break;
4996               }
4997             }
4998           }
4999           break;
5000         }
5001       if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
5002         {
5003           Image
5004             *paint_image;
5005
5006           /*
5007             Reduce-noise image.
5008           */
5009           if (msl_info->image[n] == (Image *) NULL)
5010             {
5011               ThrowMSLException(OptionError,"NoImagesDefined",
5012                 (const char *) tag);
5013               break;
5014             }
5015           if (attributes != (const xmlChar **) NULL)
5016             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5017             {
5018               keyword=(const char *) attributes[i++];
5019               attribute=InterpretImageProperties(msl_info->image_info[n],
5020                 msl_info->attributes[n],(const char *) attributes[i]);
5021               CloneString(&value,attribute);
5022               switch (*keyword)
5023               {
5024                 case 'G':
5025                 case 'g':
5026                 {
5027                   if (LocaleCompare(keyword,"geometry") == 0)
5028                     {
5029                       flags=ParseGeometry(value,&geometry_info);
5030                       if ((flags & SigmaValue) == 0)
5031                         geometry_info.sigma=1.0;
5032                       break;
5033                     }
5034                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5035                     keyword);
5036                   break;
5037                 }
5038                 case 'R':
5039                 case 'r':
5040                 {
5041                   if (LocaleCompare(keyword,"radius") == 0)
5042                     {
5043                       geometry_info.rho=InterpretLocaleValue(value,
5044                         (char **) NULL);
5045                       break;
5046                     }
5047                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5048                     keyword);
5049                   break;
5050                 }
5051                 default:
5052                 {
5053                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5054                     keyword);
5055                   break;
5056                 }
5057               }
5058             }
5059           paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
5060             (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5061             &msl_info->image[n]->exception);
5062           if (paint_image == (Image *) NULL)
5063             break;
5064           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5065           msl_info->image[n]=paint_image;
5066           break;
5067         }
5068       else if (LocaleCompare((const char *) tag,"repage") == 0)
5069       {
5070         /* init the values */
5071         width=msl_info->image[n]->page.width;
5072         height=msl_info->image[n]->page.height;
5073         x=msl_info->image[n]->page.x;
5074         y=msl_info->image[n]->page.y;
5075
5076         if (msl_info->image[n] == (Image *) NULL)
5077         {
5078           ThrowMSLException(OptionError,"NoImagesDefined",
5079             (const char *) tag);
5080           break;
5081         }
5082         if (attributes == (const xmlChar **) NULL)
5083         break;
5084         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5085         {
5086         keyword=(const char *) attributes[i++];
5087         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5088           msl_info->attributes[n],(const char *) attributes[i]));
5089         switch (*keyword)
5090         {
5091           case 'G':
5092           case 'g':
5093           {
5094           if (LocaleCompare(keyword,"geometry") == 0)
5095             {
5096               int
5097                 flags;
5098
5099               RectangleInfo
5100                 geometry;
5101
5102             flags=ParseAbsoluteGeometry(value,&geometry);
5103             if ((flags & WidthValue) != 0)
5104               {
5105                 if ((flags & HeightValue) == 0)
5106                   geometry.height=geometry.width;
5107                 width=geometry.width;
5108                 height=geometry.height;
5109               }
5110             if ((flags & AspectValue) != 0)
5111               {
5112                 if ((flags & XValue) != 0)
5113                   x+=geometry.x;
5114                 if ((flags & YValue) != 0)
5115                   y+=geometry.y;
5116               }
5117             else
5118               {
5119                 if ((flags & XValue) != 0)
5120                   {
5121                     x=geometry.x;
5122                     if ((width == 0) && (geometry.x > 0))
5123                       width=msl_info->image[n]->columns+geometry.x;
5124                   }
5125                 if ((flags & YValue) != 0)
5126                   {
5127                     y=geometry.y;
5128                     if ((height == 0) && (geometry.y > 0))
5129                       height=msl_info->image[n]->rows+geometry.y;
5130                   }
5131               }
5132             break;
5133             }
5134           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5135           break;
5136           }
5137           case 'H':
5138           case 'h':
5139           {
5140           if (LocaleCompare(keyword,"height") == 0)
5141             {
5142             height = StringToLong( value );
5143             break;
5144             }
5145           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5146           break;
5147           }
5148           case 'W':
5149           case 'w':
5150           {
5151           if (LocaleCompare(keyword,"width") == 0)
5152             {
5153             width = StringToLong( value );
5154             break;
5155             }
5156           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5157           break;
5158           }
5159           case 'X':
5160           case 'x':
5161           {
5162           if (LocaleCompare(keyword,"x") == 0)
5163             {
5164             x = StringToLong( value );
5165             break;
5166             }
5167           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5168           break;
5169           }
5170           case 'Y':
5171           case 'y':
5172           {
5173           if (LocaleCompare(keyword,"y") == 0)
5174             {
5175             y = StringToLong( value );
5176             break;
5177             }
5178           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5179           break;
5180           }
5181           default:
5182           {
5183           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5184           break;
5185           }
5186         }
5187         }
5188
5189          msl_info->image[n]->page.width=width;
5190          msl_info->image[n]->page.height=height;
5191          msl_info->image[n]->page.x=x;
5192          msl_info->image[n]->page.y=y;
5193         break;
5194       }
5195     else if (LocaleCompare((const char *) tag,"resample") == 0)
5196     {
5197       double
5198         x_resolution,
5199         y_resolution;
5200
5201       if (msl_info->image[n] == (Image *) NULL)
5202         {
5203           ThrowMSLException(OptionError,"NoImagesDefined",
5204             (const char *) tag);
5205           break;
5206         }
5207       if (attributes == (const xmlChar **) NULL)
5208         break;
5209       x_resolution=DefaultResolution;
5210       y_resolution=DefaultResolution;
5211       for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5212       {
5213         keyword=(const char *) attributes[i++];
5214         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5215           msl_info->attributes[n],(const char *) attributes[i]));
5216         switch (*keyword)
5217         {
5218           case 'b':
5219           {
5220             if (LocaleCompare(keyword,"blur") == 0)
5221               {
5222                 msl_info->image[n]->blur=InterpretLocaleValue(value,
5223                         (char **) NULL);
5224                 break;
5225               }
5226             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5227             break;
5228           }
5229           case 'G':
5230           case 'g':
5231           {
5232             if (LocaleCompare(keyword,"geometry") == 0)
5233               {
5234                 ssize_t
5235                   flags;
5236
5237                 flags=ParseGeometry(value,&geometry_info);
5238                 if ((flags & SigmaValue) == 0)
5239                   geometry_info.sigma*=geometry_info.rho;
5240                 x_resolution=geometry_info.rho;
5241                 y_resolution=geometry_info.sigma;
5242                 break;
5243               }
5244             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5245             break;
5246           }
5247           case 'X':
5248           case 'x':
5249           {
5250             if (LocaleCompare(keyword,"x-resolution") == 0)
5251               {
5252                 x_resolution=InterpretLocaleValue(value,(char **) NULL);
5253                 break;
5254               }
5255             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5256             break;
5257           }
5258           case 'Y':
5259           case 'y':
5260           {
5261             if (LocaleCompare(keyword,"y-resolution") == 0)
5262               {
5263                 y_resolution=InterpretLocaleValue(value,(char **) NULL);
5264                 break;
5265               }
5266             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5267             break;
5268           }
5269           default:
5270           {
5271             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5272             break;
5273           }
5274         }
5275       }
5276       /*
5277         Resample image.
5278       */
5279       {
5280         double
5281           factor;
5282
5283         Image
5284           *resample_image;
5285
5286         factor=1.0;
5287         if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5288           factor=2.54;
5289         width=(size_t) (x_resolution*msl_info->image[n]->columns/
5290           (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5291           msl_info->image[n]->x_resolution))+0.5);
5292         height=(size_t) (y_resolution*msl_info->image[n]->rows/
5293           (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5294           msl_info->image[n]->y_resolution))+0.5);
5295         resample_image=ResizeImage(msl_info->image[n],width,height,
5296           msl_info->image[n]->filter,msl_info->image[n]->blur,
5297           &msl_info->image[n]->exception);
5298         if (resample_image == (Image *) NULL)
5299           break;
5300         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5301         msl_info->image[n]=resample_image;
5302       }
5303       break;
5304     }
5305       if (LocaleCompare((const char *) tag,"resize") == 0)
5306         {
5307           double
5308             blur;
5309
5310           FilterTypes
5311             filter;
5312
5313           Image
5314             *resize_image;
5315
5316           /*
5317             Resize image.
5318           */
5319           if (msl_info->image[n] == (Image *) NULL)
5320             {
5321               ThrowMSLException(OptionError,"NoImagesDefined",
5322                 (const char *) tag);
5323               break;
5324             }
5325           filter=UndefinedFilter;
5326           blur=1.0;
5327           if (attributes != (const xmlChar **) NULL)
5328             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5329             {
5330               keyword=(const char *) attributes[i++];
5331               attribute=InterpretImageProperties(msl_info->image_info[n],
5332                 msl_info->attributes[n],(const char *) attributes[i]);
5333               CloneString(&value,attribute);
5334               switch (*keyword)
5335               {
5336                 case 'F':
5337                 case 'f':
5338                 {
5339                   if (LocaleCompare(keyword,"filter") == 0)
5340                     {
5341                       option=ParseCommandOption(MagickFilterOptions,MagickFalse,
5342                         value);
5343                       if (option < 0)
5344                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5345                           value);
5346                       filter=(FilterTypes) option;
5347                       break;
5348                     }
5349                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5350                     keyword);
5351                   break;
5352                 }
5353                 case 'G':
5354                 case 'g':
5355                 {
5356                   if (LocaleCompare(keyword,"geometry") == 0)
5357                     {
5358                       flags=ParseRegionGeometry(msl_info->image[n],value,
5359                         &geometry,&exception);
5360                       break;
5361                     }
5362                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5363                     keyword);
5364                   break;
5365                 }
5366                 case 'H':
5367                 case 'h':
5368                 {
5369                   if (LocaleCompare(keyword,"height") == 0)
5370                     {
5371                       geometry.height=StringToUnsignedLong(value);
5372                       break;
5373                     }
5374                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5375                     keyword);
5376                   break;
5377                 }
5378                 case 'S':
5379                 case 's':
5380                 {
5381                   if (LocaleCompare(keyword,"support") == 0)
5382                     {
5383                       blur=InterpretLocaleValue(value,(char **) NULL);
5384                       break;
5385                     }
5386                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5387                     keyword);
5388                   break;
5389                 }
5390                 case 'W':
5391                 case 'w':
5392                 {
5393                   if (LocaleCompare(keyword,"width") == 0)
5394                     {
5395                       geometry.width=StringToLong(value);
5396                       break;
5397                     }
5398                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5399                     keyword);
5400                   break;
5401                 }
5402                 default:
5403                 {
5404                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5405                     keyword);
5406                   break;
5407                 }
5408               }
5409             }
5410           resize_image=ResizeImage(msl_info->image[n],geometry.width,
5411             geometry.height,filter,blur,&msl_info->image[n]->exception);
5412           if (resize_image == (Image *) NULL)
5413             break;
5414           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5415           msl_info->image[n]=resize_image;
5416           break;
5417         }
5418       if (LocaleCompare((const char *) tag,"roll") == 0)
5419         {
5420           Image
5421             *roll_image;
5422
5423           /*
5424             Roll image.
5425           */
5426           if (msl_info->image[n] == (Image *) NULL)
5427             {
5428               ThrowMSLException(OptionError,"NoImagesDefined",
5429                 (const char *) tag);
5430               break;
5431             }
5432           SetGeometry(msl_info->image[n],&geometry);
5433           if (attributes != (const xmlChar **) NULL)
5434             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5435             {
5436               keyword=(const char *) attributes[i++];
5437               attribute=InterpretImageProperties(msl_info->image_info[n],
5438                 msl_info->attributes[n],(const char *) attributes[i]);
5439               CloneString(&value,attribute);
5440               switch (*keyword)
5441               {
5442                 case 'G':
5443                 case 'g':
5444                 {
5445                   if (LocaleCompare(keyword,"geometry") == 0)
5446                     {
5447                       flags=ParsePageGeometry(msl_info->image[n],value,
5448                         &geometry,&exception);
5449                       if ((flags & HeightValue) == 0)
5450                         geometry.height=geometry.width;
5451                       break;
5452                     }
5453                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5454                     keyword);
5455                   break;
5456                 }
5457                 case 'X':
5458                 case 'x':
5459                 {
5460                   if (LocaleCompare(keyword,"x") == 0)
5461                     {
5462                       geometry.x=StringToLong(value);
5463                       break;
5464                     }
5465                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5466                     keyword);
5467                   break;
5468                 }
5469                 case 'Y':
5470                 case 'y':
5471                 {
5472                   if (LocaleCompare(keyword,"y") == 0)
5473                     {
5474                       geometry.y=StringToLong(value);
5475                       break;
5476                     }
5477                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5478                     keyword);
5479                   break;
5480                 }
5481                 default:
5482                 {
5483                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5484                     keyword);
5485                   break;
5486                 }
5487               }
5488             }
5489           roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5490             &msl_info->image[n]->exception);
5491           if (roll_image == (Image *) NULL)
5492             break;
5493           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5494           msl_info->image[n]=roll_image;
5495           break;
5496         }
5497       else if (LocaleCompare((const char *) tag,"roll") == 0)
5498       {
5499         /* init the values */
5500         width=msl_info->image[n]->columns;
5501         height=msl_info->image[n]->rows;
5502         x = y = 0;
5503
5504         if (msl_info->image[n] == (Image *) NULL)
5505         {
5506           ThrowMSLException(OptionError,"NoImagesDefined",
5507             (const char *) tag);
5508           break;
5509         }
5510         if (attributes == (const xmlChar **) NULL)
5511         break;
5512         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5513         {
5514         keyword=(const char *) attributes[i++];
5515         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5516           msl_info->attributes[n],(const char *) attributes[i]));
5517         switch (*keyword)
5518         {
5519           case 'G':
5520           case 'g':
5521           {
5522           if (LocaleCompare(keyword,"geometry") == 0)
5523             {
5524             (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5525             break;
5526             }
5527           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5528           break;
5529           }
5530           case 'X':
5531           case 'x':
5532           {
5533           if (LocaleCompare(keyword,"x") == 0)
5534             {
5535             x = StringToLong( value );
5536             break;
5537             }
5538           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5539           break;
5540           }
5541           case 'Y':
5542           case 'y':
5543           {
5544           if (LocaleCompare(keyword,"y") == 0)
5545             {
5546             y = StringToLong( value );
5547             break;
5548             }
5549           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5550           break;
5551           }
5552           default:
5553           {
5554           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5555           break;
5556           }
5557         }
5558         }
5559
5560         /*
5561           process image.
5562         */
5563         {
5564         Image
5565           *newImage;
5566
5567         newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5568         if (newImage == (Image *) NULL)
5569           break;
5570         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5571         msl_info->image[n]=newImage;
5572         }
5573
5574         break;
5575       }
5576       if (LocaleCompare((const char *) tag,"rotate") == 0)
5577         {
5578           Image
5579             *rotate_image;
5580
5581           /*
5582             Rotate image.
5583           */
5584           if (msl_info->image[n] == (Image *) NULL)
5585             {
5586               ThrowMSLException(OptionError,"NoImagesDefined",
5587                 (const char *) tag);
5588               break;
5589             }
5590           if (attributes != (const xmlChar **) NULL)
5591             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5592             {
5593               keyword=(const char *) attributes[i++];
5594               attribute=InterpretImageProperties(msl_info->image_info[n],
5595                 msl_info->attributes[n],(const char *) attributes[i]);
5596               CloneString(&value,attribute);
5597               switch (*keyword)
5598               {
5599                 case 'D':
5600                 case 'd':
5601                 {
5602                   if (LocaleCompare(keyword,"degrees") == 0)
5603                     {
5604                       geometry_info.rho=InterpretLocaleValue(value,
5605                         (char **) NULL);
5606                       break;
5607                     }
5608                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5609                     keyword);
5610                   break;
5611                 }
5612                 case 'G':
5613                 case 'g':
5614                 {
5615                   if (LocaleCompare(keyword,"geometry") == 0)
5616                     {
5617                       flags=ParseGeometry(value,&geometry_info);
5618                       if ((flags & SigmaValue) == 0)
5619                         geometry_info.sigma=1.0;
5620                       break;
5621                     }
5622                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5623                     keyword);
5624                   break;
5625                 }
5626                 default:
5627                 {
5628                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5629                     keyword);
5630                   break;
5631                 }
5632               }
5633             }
5634           rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5635             &msl_info->image[n]->exception);
5636           if (rotate_image == (Image *) NULL)
5637             break;
5638           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5639           msl_info->image[n]=rotate_image;
5640           break;
5641         }
5642       else if (LocaleCompare((const char *) tag,"rotate") == 0)
5643       {
5644         /* init the values */
5645         double  degrees = 0;
5646
5647         if (msl_info->image[n] == (Image *) NULL)
5648         {
5649           ThrowMSLException(OptionError,"NoImagesDefined",
5650             (const char *) tag);
5651           break;
5652         }
5653         if (attributes == (const xmlChar **) NULL)
5654           break;
5655         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5656         {
5657         keyword=(const char *) attributes[i++];
5658         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5659           msl_info->attributes[n],(const char *) attributes[i]));
5660         switch (*keyword)
5661         {
5662           case 'D':
5663           case 'd':
5664           {
5665           if (LocaleCompare(keyword,"degrees") == 0)
5666             {
5667             degrees = InterpretLocaleValue(value,(char **) NULL);
5668             break;
5669             }
5670           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5671           break;
5672           }
5673           default:
5674           {
5675           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5676           break;
5677           }
5678         }
5679         }
5680
5681         /*
5682           process image.
5683         */
5684         {
5685         Image
5686           *newImage;
5687
5688         newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5689         if (newImage == (Image *) NULL)
5690           break;
5691         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5692         msl_info->image[n]=newImage;
5693         }
5694
5695         break;
5696       }
5697       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5698     }
5699     case 'S':
5700     case 's':
5701     {
5702       if (LocaleCompare((const char *) tag,"sample") == 0)
5703         {
5704           Image
5705             *sample_image;
5706
5707           /*
5708             Sample image.
5709           */
5710           if (msl_info->image[n] == (Image *) NULL)
5711             {
5712               ThrowMSLException(OptionError,"NoImagesDefined",
5713                 (const char *) tag);
5714               break;
5715             }
5716           if (attributes != (const xmlChar **) NULL)
5717             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5718             {
5719               keyword=(const char *) attributes[i++];
5720               attribute=InterpretImageProperties(msl_info->image_info[n],
5721                 msl_info->attributes[n],(const char *) attributes[i]);
5722               CloneString(&value,attribute);
5723               switch (*keyword)
5724               {
5725                 case 'G':
5726                 case 'g':
5727                 {
5728                   if (LocaleCompare(keyword,"geometry") == 0)
5729                     {
5730                       flags=ParseRegionGeometry(msl_info->image[n],value,
5731                         &geometry,&exception);
5732                       break;
5733                     }
5734                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5735                     keyword);
5736                   break;
5737                 }
5738                 case 'H':
5739                 case 'h':
5740                 {
5741                   if (LocaleCompare(keyword,"height") == 0)
5742                     {
5743                       geometry.height=StringToUnsignedLong(value);
5744                       break;
5745                     }
5746                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5747                     keyword);
5748                   break;
5749                 }
5750                 case 'W':
5751                 case 'w':
5752                 {
5753                   if (LocaleCompare(keyword,"width") == 0)
5754                     {
5755                       geometry.width=StringToLong(value);
5756                       break;
5757                     }
5758                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5759                     keyword);
5760                   break;
5761                 }
5762                 default:
5763                 {
5764                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5765                     keyword);
5766                   break;
5767                 }
5768               }
5769             }
5770           sample_image=SampleImage(msl_info->image[n],geometry.width,
5771             geometry.height,&msl_info->image[n]->exception);
5772           if (sample_image == (Image *) NULL)
5773             break;
5774           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5775           msl_info->image[n]=sample_image;
5776           break;
5777         }
5778       if (LocaleCompare((const char *) tag,"scale") == 0)
5779         {
5780           Image
5781             *scale_image;
5782
5783           /*
5784             Scale image.
5785           */
5786           if (msl_info->image[n] == (Image *) NULL)
5787             {
5788               ThrowMSLException(OptionError,"NoImagesDefined",
5789                 (const char *) tag);
5790               break;
5791             }
5792           if (attributes != (const xmlChar **) NULL)
5793             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5794             {
5795               keyword=(const char *) attributes[i++];
5796               attribute=InterpretImageProperties(msl_info->image_info[n],
5797                 msl_info->attributes[n],(const char *) attributes[i]);
5798               CloneString(&value,attribute);
5799               switch (*keyword)
5800               {
5801                 case 'G':
5802                 case 'g':
5803                 {
5804                   if (LocaleCompare(keyword,"geometry") == 0)
5805                     {
5806                       flags=ParseRegionGeometry(msl_info->image[n],value,
5807                         &geometry,&exception);
5808                       break;
5809                     }
5810                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5811                     keyword);
5812                   break;
5813                 }
5814                 case 'H':
5815                 case 'h':
5816                 {
5817                   if (LocaleCompare(keyword,"height") == 0)
5818                     {
5819                       geometry.height=StringToUnsignedLong(value);
5820                       break;
5821                     }
5822                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5823                     keyword);
5824                   break;
5825                 }
5826                 case 'W':
5827                 case 'w':
5828                 {
5829                   if (LocaleCompare(keyword,"width") == 0)
5830                     {
5831                       geometry.width=StringToLong(value);
5832                       break;
5833                     }
5834                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5835                     keyword);
5836                   break;
5837                 }
5838                 default:
5839                 {
5840                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5841                     keyword);
5842                   break;
5843                 }
5844               }
5845             }
5846           scale_image=ScaleImage(msl_info->image[n],geometry.width,
5847             geometry.height,&msl_info->image[n]->exception);
5848           if (scale_image == (Image *) NULL)
5849             break;
5850           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5851           msl_info->image[n]=scale_image;
5852           break;
5853         }
5854       if (LocaleCompare((const char *) tag,"segment") == 0)
5855         {
5856           ColorspaceType
5857             colorspace;
5858
5859           MagickBooleanType
5860             verbose;
5861
5862           /*
5863             Segment image.
5864           */
5865           if (msl_info->image[n] == (Image *) NULL)
5866             {
5867               ThrowMSLException(OptionError,"NoImagesDefined",
5868                 (const char *) tag);
5869               break;
5870             }
5871           geometry_info.rho=1.0;
5872           geometry_info.sigma=1.5;
5873           colorspace=RGBColorspace;
5874           verbose=MagickFalse;
5875           if (attributes != (const xmlChar **) NULL)
5876             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5877             {
5878               keyword=(const char *) attributes[i++];
5879               attribute=InterpretImageProperties(msl_info->image_info[n],
5880                 msl_info->attributes[n],(const char *) attributes[i]);
5881               CloneString(&value,attribute);
5882               switch (*keyword)
5883               {
5884                 case 'C':
5885                 case 'c':
5886                 {
5887                   if (LocaleCompare(keyword,"cluster-threshold") == 0)
5888                     {
5889                       geometry_info.rho=InterpretLocaleValue(value,
5890                         (char **) NULL);
5891                       break;
5892                     }
5893                   if (LocaleCompare(keyword,"colorspace") == 0)
5894                     {
5895                       option=ParseCommandOption(MagickColorspaceOptions,
5896                         MagickFalse,value);
5897                       if (option < 0)
5898                         ThrowMSLException(OptionError,
5899                           "UnrecognizedColorspaceType",value);
5900                       colorspace=(ColorspaceType) option;
5901                       break;
5902                     }
5903                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5904                     keyword);
5905                   break;
5906                 }
5907                 case 'G':
5908                 case 'g':
5909                 {
5910                   if (LocaleCompare(keyword,"geometry") == 0)
5911                     {
5912                       flags=ParseGeometry(value,&geometry_info);
5913                       if ((flags & SigmaValue) == 0)
5914                         geometry_info.sigma=1.5;
5915                       break;
5916                     }
5917                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5918                     keyword);
5919                   break;
5920                 }
5921                 case 'S':
5922                 case 's':
5923                 {
5924                   if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5925                     {
5926                       geometry_info.sigma=InterpretLocaleValue(value,
5927                         (char **) NULL);
5928                       break;
5929                     }
5930                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5931                     keyword);
5932                   break;
5933                 }
5934                 default:
5935                 {
5936                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5937                     keyword);
5938                   break;
5939                 }
5940               }
5941             }
5942           (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5943             geometry_info.rho,geometry_info.sigma);
5944           break;
5945         }
5946       else if (LocaleCompare((const char *) tag, "set") == 0)
5947       {
5948         if (msl_info->image[n] == (Image *) NULL)
5949         {
5950           ThrowMSLException(OptionError,"NoImagesDefined",
5951             (const char *) tag);
5952           break;
5953         }
5954
5955         if (attributes == (const xmlChar **) NULL)
5956           break;
5957         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5958         {
5959           keyword=(const char *) attributes[i++];
5960           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5961             msl_info->attributes[n],(const char *) attributes[i]));
5962           switch (*keyword)
5963           {
5964             case 'C':
5965             case 'c':
5966             {
5967               if (LocaleCompare(keyword,"clip-mask") == 0)
5968                 {
5969                   for (j=0; j < msl_info->n; j++)
5970                   {
5971                     const char
5972                       *property;
5973
5974                     property=GetImageProperty(msl_info->attributes[j],"id");
5975                     if (LocaleCompare(property,value) == 0)
5976                       {
5977                         SetImageMask(msl_info->image[n],msl_info->image[j]);
5978                         break;
5979                       }
5980                   }
5981                   break;
5982                 }
5983               if (LocaleCompare(keyword,"clip-path") == 0)
5984                 {
5985                   for (j=0; j < msl_info->n; j++)
5986                   {
5987                     const char
5988                       *property;
5989
5990                     property=GetImageProperty(msl_info->attributes[j],"id");
5991                     if (LocaleCompare(property,value) == 0)
5992                       {
5993                         SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5994                         break;
5995                       }
5996                   }
5997                   break;
5998                 }
5999               if (LocaleCompare(keyword,"colorspace") == 0)
6000                 {
6001                   ssize_t
6002                     colorspace;
6003
6004                   colorspace=(ColorspaceType) ParseCommandOption(
6005                     MagickColorspaceOptions,MagickFalse,value);
6006                   if (colorspace < 0)
6007                     ThrowMSLException(OptionError,"UnrecognizedColorspace",
6008                       value);
6009                   (void) TransformImageColorspace(msl_info->image[n],
6010                     (ColorspaceType) colorspace);
6011                   break;
6012                 }
6013               (void) SetMSLAttributes(msl_info,keyword,value);
6014               break;
6015             }
6016             case 'D':
6017             case 'd':
6018             {
6019               if (LocaleCompare(keyword,"density") == 0)
6020                 {
6021                   flags=ParseGeometry(value,&geometry_info);
6022                   msl_info->image[n]->x_resolution=geometry_info.rho;
6023                   msl_info->image[n]->y_resolution=geometry_info.sigma;
6024                   if ((flags & SigmaValue) == 0)
6025                     msl_info->image[n]->y_resolution=
6026                       msl_info->image[n]->x_resolution;
6027                   break;
6028                 }
6029               (void) SetMSLAttributes(msl_info,keyword,value);
6030               break;
6031             }
6032             case 'O':
6033             case 'o':
6034             {
6035               if (LocaleCompare(keyword, "opacity") == 0)
6036                 {
6037                   ssize_t  opac = OpaqueAlpha,
6038                   len = (ssize_t) strlen( value );
6039
6040                   if (value[len-1] == '%') {
6041                     char  tmp[100];
6042                     (void) CopyMagickString(tmp,value,len);
6043                     opac = StringToLong( tmp );
6044                     opac = (int)(QuantumRange * ((float)opac/100));
6045                   } else
6046                     opac = StringToLong( value );
6047                   (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6048                   break;
6049               }
6050               (void) SetMSLAttributes(msl_info,keyword,value);
6051               break;
6052             }
6053             case 'P':
6054             case 'p':
6055             {
6056               if (LocaleCompare(keyword, "page") == 0)
6057               {
6058                 char
6059                   page[MaxTextExtent];
6060
6061                 const char
6062                   *image_option;
6063
6064                 MagickStatusType
6065                   flags;
6066
6067                 RectangleInfo
6068                   geometry;
6069
6070                 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6071                 image_option=GetImageOption(msl_info->image_info[n],"page");
6072                 if (image_option != (const char *) NULL)
6073                   flags=ParseAbsoluteGeometry(image_option,&geometry);
6074                 flags=ParseAbsoluteGeometry(value,&geometry);
6075                 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
6076                   (double) geometry.width,(double) geometry.height);
6077                 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
6078                   (void) FormatLocaleString(page,MaxTextExtent,
6079                     "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6080                     (double) geometry.height,(double) geometry.x,(double)
6081                     geometry.y);
6082                 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6083                 msl_info->image_info[n]->page=GetPageGeometry(page);
6084                 break;
6085               }
6086               (void) SetMSLAttributes(msl_info,keyword,value);
6087               break;
6088             }
6089             default:
6090             {
6091               (void) SetMSLAttributes(msl_info,keyword,value);
6092               break;
6093             }
6094           }
6095         }
6096         break;
6097       }
6098       if (LocaleCompare((const char *) tag,"shade") == 0)
6099         {
6100           Image
6101             *shade_image;
6102
6103           MagickBooleanType
6104             gray;
6105
6106           /*
6107             Shade image.
6108           */
6109           if (msl_info->image[n] == (Image *) NULL)
6110             {
6111               ThrowMSLException(OptionError,"NoImagesDefined",
6112                 (const char *) tag);
6113               break;
6114             }
6115           gray=MagickFalse;
6116           if (attributes != (const xmlChar **) NULL)
6117             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6118             {
6119               keyword=(const char *) attributes[i++];
6120               attribute=InterpretImageProperties(msl_info->image_info[n],
6121                 msl_info->attributes[n],(const char *) attributes[i]);
6122               CloneString(&value,attribute);
6123               switch (*keyword)
6124               {
6125                 case 'A':
6126                 case 'a':
6127                 {
6128                   if (LocaleCompare(keyword,"azimuth") == 0)
6129                     {
6130                       geometry_info.rho=InterpretLocaleValue(value,
6131                         (char **) NULL);
6132                       break;
6133                     }
6134                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6135                     keyword);
6136                   break;
6137                 }
6138                 case 'E':
6139                 case 'e':
6140                 {
6141                   if (LocaleCompare(keyword,"elevation") == 0)
6142                     {
6143                       geometry_info.sigma=InterpretLocaleValue(value,
6144                         (char **) NULL);
6145                       break;
6146                     }
6147                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6148                     keyword);
6149                   break;
6150                 }
6151                 case 'G':
6152                 case 'g':
6153                 {
6154                   if (LocaleCompare(keyword,"geometry") == 0)
6155                     {
6156                       flags=ParseGeometry(value,&geometry_info);
6157                       if ((flags & SigmaValue) == 0)
6158                         geometry_info.sigma=1.0;
6159                       break;
6160                     }
6161                   if (LocaleCompare(keyword,"gray") == 0)
6162                     {
6163                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6164                         value);
6165                       if (option < 0)
6166                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6167                           value);
6168                       gray=(MagickBooleanType) option;
6169                       break;
6170                     }
6171                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6172                     keyword);
6173                   break;
6174                 }
6175                 default:
6176                 {
6177                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6178                     keyword);
6179                   break;
6180                 }
6181               }
6182             }
6183           shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6184             geometry_info.sigma,&msl_info->image[n]->exception);
6185           if (shade_image == (Image *) NULL)
6186             break;
6187           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6188           msl_info->image[n]=shade_image;
6189           break;
6190         }
6191       if (LocaleCompare((const char *) tag,"shadow") == 0)
6192         {
6193           Image
6194             *shadow_image;
6195
6196           /*
6197             Shear image.
6198           */
6199           if (msl_info->image[n] == (Image *) NULL)
6200             {
6201               ThrowMSLException(OptionError,"NoImagesDefined",
6202                 (const char *) tag);
6203               break;
6204             }
6205           if (attributes != (const xmlChar **) NULL)
6206             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6207             {
6208               keyword=(const char *) attributes[i++];
6209               attribute=InterpretImageProperties(msl_info->image_info[n],
6210                 msl_info->attributes[n],(const char *) attributes[i]);
6211               CloneString(&value,attribute);
6212               switch (*keyword)
6213               {
6214                 case 'G':
6215                 case 'g':
6216                 {
6217                   if (LocaleCompare(keyword,"geometry") == 0)
6218                     {
6219                       flags=ParseGeometry(value,&geometry_info);
6220                       if ((flags & SigmaValue) == 0)
6221                         geometry_info.sigma=1.0;
6222                       break;
6223                     }
6224                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6225                     keyword);
6226                   break;
6227                 }
6228                 case 'O':
6229                 case 'o':
6230                 {
6231                   if (LocaleCompare(keyword,"opacity") == 0)
6232                     {
6233                       geometry_info.rho=StringToLong(value);
6234                       break;
6235                     }
6236                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6237                     keyword);
6238                   break;
6239                 }
6240                 case 'S':
6241                 case 's':
6242                 {
6243                   if (LocaleCompare(keyword,"sigma") == 0)
6244                     {
6245                       geometry_info.sigma=StringToLong(value);
6246                       break;
6247                     }
6248                   break;
6249                 }
6250                 case 'X':
6251                 case 'x':
6252                 {
6253                   if (LocaleCompare(keyword,"x") == 0)
6254                     {
6255                       geometry_info.xi=InterpretLocaleValue(value,
6256                         (char **) NULL);
6257                       break;
6258                     }
6259                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6260                     keyword);
6261                   break;
6262                 }
6263                 case 'Y':
6264                 case 'y':
6265                 {
6266                   if (LocaleCompare(keyword,"y") == 0)
6267                     {
6268                       geometry_info.psi=StringToLong(value);
6269                       break;
6270                     }
6271                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6272                     keyword);
6273                   break;
6274                 }
6275                 default:
6276                 {
6277                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6278                     keyword);
6279                   break;
6280                 }
6281               }
6282             }
6283           shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
6284             geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
6285             ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
6286           if (shadow_image == (Image *) NULL)
6287             break;
6288           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6289           msl_info->image[n]=shadow_image;
6290           break;
6291         }
6292       if (LocaleCompare((const char *) tag,"sharpen") == 0)
6293       {
6294         double  radius = 0.0,
6295             sigma = 1.0;
6296
6297         if (msl_info->image[n] == (Image *) NULL)
6298           {
6299             ThrowMSLException(OptionError,"NoImagesDefined",
6300               (const char *) tag);
6301             break;
6302           }
6303         /*
6304         NOTE: sharpen can have no attributes, since we use all the defaults!
6305         */
6306         if (attributes != (const xmlChar **) NULL)
6307         {
6308           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6309           {
6310           keyword=(const char *) attributes[i++];
6311           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6312             msl_info->attributes[n],(const char *) attributes[i]));
6313           switch (*keyword)
6314           {
6315             case 'R':
6316             case 'r':
6317             {
6318               if (LocaleCompare(keyword, "radius") == 0)
6319               {
6320                 radius = InterpretLocaleValue(value,(char **) NULL);
6321                 break;
6322               }
6323               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6324               break;
6325             }
6326             case 'S':
6327             case 's':
6328             {
6329               if (LocaleCompare(keyword,"sigma") == 0)
6330               {
6331                 sigma = StringToLong( value );
6332                 break;
6333               }
6334               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6335               break;
6336             }
6337             default:
6338             {
6339               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6340               break;
6341             }
6342           }
6343           }
6344         }
6345
6346         /*
6347           sharpen image.
6348         */
6349         {
6350         Image
6351           *newImage;
6352
6353         newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6354         if (newImage == (Image *) NULL)
6355           break;
6356         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6357         msl_info->image[n]=newImage;
6358         break;
6359         }
6360       }
6361       else if (LocaleCompare((const char *) tag,"shave") == 0)
6362       {
6363         /* init the values */
6364         width = height = 0;
6365         x = y = 0;
6366
6367         if (msl_info->image[n] == (Image *) NULL)
6368         {
6369           ThrowMSLException(OptionError,"NoImagesDefined",
6370             (const char *) tag);
6371           break;
6372         }
6373         if (attributes == (const xmlChar **) NULL)
6374         break;
6375         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6376         {
6377         keyword=(const char *) attributes[i++];
6378         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6379           msl_info->attributes[n],(const char *) attributes[i]));
6380         switch (*keyword)
6381         {
6382           case 'G':
6383           case 'g':
6384           {
6385           if (LocaleCompare(keyword,"geometry") == 0)
6386             {
6387             (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6388             break;
6389             }
6390           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6391           break;
6392           }
6393           case 'H':
6394           case 'h':
6395           {
6396           if (LocaleCompare(keyword,"height") == 0)
6397             {
6398             height = StringToLong( value );
6399             break;
6400             }
6401           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6402           break;
6403           }
6404           case 'W':
6405           case 'w':
6406           {
6407           if (LocaleCompare(keyword,"width") == 0)
6408             {
6409             width = StringToLong( value );
6410             break;
6411             }
6412           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6413           break;
6414           }
6415           default:
6416           {
6417           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6418           break;
6419           }
6420         }
6421         }
6422
6423         /*
6424           process image.
6425         */
6426         {
6427         Image
6428           *newImage;
6429         RectangleInfo
6430           rectInfo;
6431
6432         rectInfo.height = height;
6433         rectInfo.width = width;
6434         rectInfo.x = x;
6435         rectInfo.y = y;
6436
6437
6438         newImage=ShaveImage(msl_info->image[n], &rectInfo,
6439           &msl_info->image[n]->exception);
6440         if (newImage == (Image *) NULL)
6441           break;
6442         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6443         msl_info->image[n]=newImage;
6444         }
6445
6446         break;
6447       }
6448       if (LocaleCompare((const char *) tag,"shear") == 0)
6449         {
6450           Image
6451             *shear_image;
6452
6453           /*
6454             Shear image.
6455           */
6456           if (msl_info->image[n] == (Image *) NULL)
6457             {
6458               ThrowMSLException(OptionError,"NoImagesDefined",
6459                 (const char *) tag);
6460               break;
6461             }
6462           if (attributes != (const xmlChar **) NULL)
6463             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6464             {
6465               keyword=(const char *) attributes[i++];
6466               attribute=InterpretImageProperties(msl_info->image_info[n],
6467                 msl_info->attributes[n],(const char *) attributes[i]);
6468               CloneString(&value,attribute);
6469               switch (*keyword)
6470               {
6471                 case 'F':
6472                 case 'f':
6473                 {
6474                   if (LocaleCompare(keyword, "fill") == 0)
6475                     {
6476                       (void) QueryColorDatabase(value,
6477                         &msl_info->image[n]->background_color,&exception);
6478                       break;
6479                     }
6480                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6481                     keyword);
6482                   break;
6483                 }
6484                 case 'G':
6485                 case 'g':
6486                 {
6487                   if (LocaleCompare(keyword,"geometry") == 0)
6488                     {
6489                       flags=ParseGeometry(value,&geometry_info);
6490                       if ((flags & SigmaValue) == 0)
6491                         geometry_info.sigma=1.0;
6492                       break;
6493                     }
6494                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6495                     keyword);
6496                   break;
6497                 }
6498                 case 'X':
6499                 case 'x':
6500                 {
6501                   if (LocaleCompare(keyword,"x") == 0)
6502                     {
6503                       geometry_info.rho=InterpretLocaleValue(value,
6504                         (char **) NULL);
6505                       break;
6506                     }
6507                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6508                     keyword);
6509                   break;
6510                 }
6511                 case 'Y':
6512                 case 'y':
6513                 {
6514                   if (LocaleCompare(keyword,"y") == 0)
6515                     {
6516                       geometry_info.sigma=StringToLong(value);
6517                       break;
6518                     }
6519                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6520                     keyword);
6521                   break;
6522                 }
6523                 default:
6524                 {
6525                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6526                     keyword);
6527                   break;
6528                 }
6529               }
6530             }
6531           shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6532             geometry_info.sigma,&msl_info->image[n]->exception);
6533           if (shear_image == (Image *) NULL)
6534             break;
6535           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6536           msl_info->image[n]=shear_image;
6537           break;
6538         }
6539       if (LocaleCompare((const char *) tag,"signature") == 0)
6540         {
6541           /*
6542             Signature image.
6543           */
6544           if (msl_info->image[n] == (Image *) NULL)
6545             {
6546               ThrowMSLException(OptionError,"NoImagesDefined",
6547                 (const char *) tag);
6548               break;
6549             }
6550           if (attributes != (const xmlChar **) NULL)
6551             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6552             {
6553               keyword=(const char *) attributes[i++];
6554               attribute=InterpretImageProperties(msl_info->image_info[n],
6555                 msl_info->attributes[n],(const char *) attributes[i]);
6556               CloneString(&value,attribute);
6557               switch (*keyword)
6558               {
6559                 default:
6560                 {
6561                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6562                     keyword);
6563                   break;
6564                 }
6565               }
6566             }
6567           (void) SignatureImage(msl_info->image[n]);
6568           break;
6569         }
6570       if (LocaleCompare((const char *) tag,"solarize") == 0)
6571         {
6572           /*
6573             Solarize image.
6574           */
6575           if (msl_info->image[n] == (Image *) NULL)
6576             {
6577               ThrowMSLException(OptionError,"NoImagesDefined",
6578                 (const char *) tag);
6579               break;
6580             }
6581           geometry_info.rho=QuantumRange/2.0;
6582           if (attributes != (const xmlChar **) NULL)
6583             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6584             {
6585               keyword=(const char *) attributes[i++];
6586               attribute=InterpretImageProperties(msl_info->image_info[n],
6587                 msl_info->attributes[n],(const char *) attributes[i]);
6588               CloneString(&value,attribute);
6589               switch (*keyword)
6590               {
6591                 case 'G':
6592                 case 'g':
6593                 {
6594                   if (LocaleCompare(keyword,"geometry") == 0)
6595                     {
6596                       flags=ParseGeometry(value,&geometry_info);
6597                       break;
6598                     }
6599                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6600                     keyword);
6601                   break;
6602                 }
6603                 case 'T':
6604                 case 't':
6605                 {
6606                   if (LocaleCompare(keyword,"threshold") == 0)
6607                     {
6608                       geometry_info.rho=InterpretLocaleValue(value,
6609                         (char **) NULL);
6610                       break;
6611                     }
6612                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6613                     keyword);
6614                   break;
6615                 }
6616                 default:
6617                 {
6618                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6619                     keyword);
6620                   break;
6621                 }
6622               }
6623             }
6624           (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6625           break;
6626         }
6627       if (LocaleCompare((const char *) tag,"spread") == 0)
6628         {
6629           Image
6630             *spread_image;
6631
6632           /*
6633             Spread image.
6634           */
6635           if (msl_info->image[n] == (Image *) NULL)
6636             {
6637               ThrowMSLException(OptionError,"NoImagesDefined",
6638                 (const char *) tag);
6639               break;
6640             }
6641           if (attributes != (const xmlChar **) NULL)
6642             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6643             {
6644               keyword=(const char *) attributes[i++];
6645               attribute=InterpretImageProperties(msl_info->image_info[n],
6646                 msl_info->attributes[n],(const char *) attributes[i]);
6647               CloneString(&value,attribute);
6648               switch (*keyword)
6649               {
6650                 case 'G':
6651                 case 'g':
6652                 {
6653                   if (LocaleCompare(keyword,"geometry") == 0)
6654                     {
6655                       flags=ParseGeometry(value,&geometry_info);
6656                       if ((flags & SigmaValue) == 0)
6657                         geometry_info.sigma=1.0;
6658                       break;
6659                     }
6660                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6661                     keyword);
6662                   break;
6663                 }
6664                 case 'R':
6665                 case 'r':
6666                 {
6667                   if (LocaleCompare(keyword,"radius") == 0)
6668                     {
6669                       geometry_info.rho=InterpretLocaleValue(value,
6670                         (char **) NULL);
6671                       break;
6672                     }
6673                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6674                     keyword);
6675                   break;
6676                 }
6677                 default:
6678                 {
6679                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6680                     keyword);
6681                   break;
6682                 }
6683               }
6684             }
6685           spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6686             &msl_info->image[n]->exception);
6687           if (spread_image == (Image *) NULL)
6688             break;
6689           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6690           msl_info->image[n]=spread_image;
6691           break;
6692         }
6693       else if (LocaleCompare((const char *) tag,"stegano") == 0)
6694       {
6695         Image *
6696           watermark = (Image*)NULL;
6697
6698         if (msl_info->image[n] == (Image *) NULL)
6699           {
6700             ThrowMSLException(OptionError,"NoImagesDefined",
6701               (const char *) tag);
6702             break;
6703           }
6704         if (attributes == (const xmlChar **) NULL)
6705         break;
6706         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6707         {
6708         keyword=(const char *) attributes[i++];
6709         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6710           msl_info->attributes[n],(const char *) attributes[i]));
6711         switch (*keyword)
6712         {
6713           case 'I':
6714           case 'i':
6715           {
6716           if (LocaleCompare(keyword,"image") == 0)
6717             {
6718             for (j=0; j<msl_info->n;j++)
6719             {
6720               const char *
6721                 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6722               if (theAttr && LocaleCompare(theAttr, value) == 0)
6723               {
6724                 watermark = msl_info->image[j];
6725                 break;
6726               }
6727             }
6728             break;
6729             }
6730           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6731           break;
6732           }
6733           default:
6734           {
6735           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6736           break;
6737           }
6738         }
6739         }
6740
6741         /*
6742           process image.
6743         */
6744         if ( watermark != (Image*) NULL )
6745         {
6746         Image
6747           *newImage;
6748
6749         newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6750         if (newImage == (Image *) NULL)
6751           break;
6752         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6753         msl_info->image[n]=newImage;
6754         break;
6755         } else
6756           ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6757       }
6758       else if (LocaleCompare((const char *) tag,"stereo") == 0)
6759       {
6760         Image *
6761           stereoImage = (Image*)NULL;
6762
6763         if (msl_info->image[n] == (Image *) NULL)
6764           {
6765             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6766             break;
6767           }
6768         if (attributes == (const xmlChar **) NULL)
6769         break;
6770         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6771         {
6772         keyword=(const char *) attributes[i++];
6773         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6774           msl_info->attributes[n],(const char *) attributes[i]));
6775         switch (*keyword)
6776         {
6777           case 'I':
6778           case 'i':
6779           {
6780           if (LocaleCompare(keyword,"image") == 0)
6781             {
6782             for (j=0; j<msl_info->n;j++)
6783             {
6784               const char *
6785                 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6786               if (theAttr && LocaleCompare(theAttr, value) == 0)
6787               {
6788                 stereoImage = msl_info->image[j];
6789                 break;
6790               }
6791             }
6792             break;
6793             }
6794           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6795           break;
6796           }
6797           default:
6798           {
6799           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6800           break;
6801           }
6802         }
6803         }
6804
6805         /*
6806           process image.
6807         */
6808         if ( stereoImage != (Image*) NULL )
6809         {
6810         Image
6811           *newImage;
6812
6813         newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6814         if (newImage == (Image *) NULL)
6815           break;
6816         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6817         msl_info->image[n]=newImage;
6818         break;
6819         } else
6820           ThrowMSLException(OptionError,"Missing stereo image",keyword);
6821       }
6822       if (LocaleCompare((const char *) tag,"swap") == 0)
6823         {
6824           Image
6825             *p,
6826             *q,
6827             *swap;
6828
6829           ssize_t
6830             index,
6831             swap_index;
6832
6833           if (msl_info->image[n] == (Image *) NULL)
6834             {
6835               ThrowMSLException(OptionError,"NoImagesDefined",
6836                 (const char *) tag);
6837               break;
6838             }
6839           index=(-1);
6840           swap_index=(-2);
6841           if (attributes != (const xmlChar **) NULL)
6842             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6843             {
6844               keyword=(const char *) attributes[i++];
6845               attribute=InterpretImageProperties(msl_info->image_info[n],
6846                 msl_info->attributes[n],(const char *) attributes[i]);
6847               CloneString(&value,attribute);
6848               switch (*keyword)
6849               {
6850                 case 'G':
6851                 case 'g':
6852                 {
6853                   if (LocaleCompare(keyword,"indexes") == 0)
6854                     {
6855                       flags=ParseGeometry(value,&geometry_info);
6856                       index=(ssize_t) geometry_info.rho;
6857                       if ((flags & SigmaValue) == 0)
6858                         swap_index=(ssize_t) geometry_info.sigma;
6859                       break;
6860                     }
6861                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6862                     keyword);
6863                   break;
6864                 }
6865                 default:
6866                 {
6867                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6868                     keyword);
6869                   break;
6870                 }
6871               }
6872             }
6873           /*
6874             Swap images.
6875           */
6876           p=GetImageFromList(msl_info->image[n],index);
6877           q=GetImageFromList(msl_info->image[n],swap_index);
6878           if ((p == (Image *) NULL) || (q == (Image *) NULL))
6879             {
6880               ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
6881               break;
6882             }
6883           swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6884           ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6885           ReplaceImageInList(&q,swap);
6886           msl_info->image[n]=GetFirstImageInList(q);
6887           break;
6888         }
6889       if (LocaleCompare((const char *) tag,"swirl") == 0)
6890         {
6891           Image
6892             *swirl_image;
6893
6894           /*
6895             Swirl image.
6896           */
6897           if (msl_info->image[n] == (Image *) NULL)
6898             {
6899               ThrowMSLException(OptionError,"NoImagesDefined",
6900                 (const char *) tag);
6901               break;
6902             }
6903           if (attributes != (const xmlChar **) NULL)
6904             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6905             {
6906               keyword=(const char *) attributes[i++];
6907               attribute=InterpretImageProperties(msl_info->image_info[n],
6908                 msl_info->attributes[n],(const char *) attributes[i]);
6909               CloneString(&value,attribute);
6910               switch (*keyword)
6911               {
6912                 case 'D':
6913                 case 'd':
6914                 {
6915                   if (LocaleCompare(keyword,"degrees") == 0)
6916                     {
6917                       geometry_info.rho=InterpretLocaleValue(value,
6918                         (char **) NULL);
6919                       break;
6920                     }
6921                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6922                     keyword);
6923                   break;
6924                 }
6925                 case 'G':
6926                 case 'g':
6927                 {
6928                   if (LocaleCompare(keyword,"geometry") == 0)
6929                     {
6930                       flags=ParseGeometry(value,&geometry_info);
6931                       if ((flags & SigmaValue) == 0)
6932                         geometry_info.sigma=1.0;
6933                       break;
6934                     }
6935                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6936                     keyword);
6937                   break;
6938                 }
6939                 default:
6940                 {
6941                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6942                     keyword);
6943                   break;
6944                 }
6945               }
6946             }
6947           swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6948             &msl_info->image[n]->exception);
6949           if (swirl_image == (Image *) NULL)
6950             break;
6951           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6952           msl_info->image[n]=swirl_image;
6953           break;
6954         }
6955       if (LocaleCompare((const char *) tag,"sync") == 0)
6956         {
6957           /*
6958             Sync image.
6959           */
6960           if (msl_info->image[n] == (Image *) NULL)
6961             {
6962               ThrowMSLException(OptionError,"NoImagesDefined",
6963                 (const char *) tag);
6964               break;
6965             }
6966           if (attributes != (const xmlChar **) NULL)
6967             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6968             {
6969               keyword=(const char *) attributes[i++];
6970               attribute=InterpretImageProperties(msl_info->image_info[n],
6971                 msl_info->attributes[n],(const char *) attributes[i]);
6972               CloneString(&value,attribute);
6973               switch (*keyword)
6974               {
6975                 default:
6976                 {
6977                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6978                     keyword);
6979                   break;
6980                 }
6981               }
6982             }
6983           (void) SyncImage(msl_info->image[n]);
6984           break;
6985         }
6986       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6987     }
6988     case 'T':
6989     case 't':
6990     {
6991       if (LocaleCompare((const char *) tag,"map") == 0)
6992         {
6993           Image
6994             *texture_image;
6995
6996           /*
6997             Texture image.
6998           */
6999           if (msl_info->image[n] == (Image *) NULL)
7000             {
7001               ThrowMSLException(OptionError,"NoImagesDefined",
7002                 (const char *) tag);
7003               break;
7004             }
7005           texture_image=NewImageList();
7006           if (attributes != (const xmlChar **) NULL)
7007             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7008             {
7009               keyword=(const char *) attributes[i++];
7010               attribute=InterpretImageProperties(msl_info->image_info[n],
7011                 msl_info->attributes[n],(const char *) attributes[i]);
7012               CloneString(&value,attribute);
7013               switch (*keyword)
7014               {
7015                 case 'I':
7016                 case 'i':
7017                 {
7018                   if (LocaleCompare(keyword,"image") == 0)
7019                     for (j=0; j < msl_info->n; j++)
7020                     {
7021                       const char
7022                         *attribute;
7023
7024                       attribute=GetImageProperty(msl_info->attributes[j],"id");
7025                       if ((attribute != (const char *) NULL)  &&
7026                           (LocaleCompare(attribute,value) == 0))
7027                         {
7028                           texture_image=CloneImage(msl_info->image[j],0,0,
7029                             MagickFalse,&exception);
7030                           break;
7031                         }
7032                     }
7033                   break;
7034                 }
7035                 default:
7036                 {
7037                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
7038                     keyword);
7039                   break;
7040                 }
7041               }
7042             }
7043           (void) TextureImage(msl_info->image[n],texture_image);
7044           texture_image=DestroyImage(texture_image);
7045           break;
7046         }
7047       else if (LocaleCompare((const char *) tag,"threshold") == 0)
7048       {
7049         /* init the values */
7050         double  threshold = 0;
7051
7052         if (msl_info->image[n] == (Image *) NULL)
7053           {
7054             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7055             break;
7056           }
7057         if (attributes == (const xmlChar **) NULL)
7058         break;
7059         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7060         {
7061         keyword=(const char *) attributes[i++];
7062         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7063           msl_info->attributes[n],(const char *) attributes[i]));
7064         switch (*keyword)
7065         {
7066           case 'T':
7067           case 't':
7068           {
7069           if (LocaleCompare(keyword,"threshold") == 0)
7070             {
7071             threshold = InterpretLocaleValue(value,(char **) NULL);
7072             break;
7073             }
7074           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7075           break;
7076           }
7077           default:
7078           {
7079           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7080           break;
7081           }
7082         }
7083         }
7084
7085         /*
7086           process image.
7087         */
7088         {
7089         BilevelImageChannel(msl_info->image[n],
7090           (ChannelType) ((ssize_t) (CompositeChannels &~ (ssize_t) OpacityChannel)),
7091           threshold);
7092         break;
7093         }
7094       }
7095       else if (LocaleCompare((const char *) tag, "transparent") == 0)
7096       {
7097         if (msl_info->image[n] == (Image *) NULL)
7098           {
7099             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7100             break;
7101           }
7102         if (attributes == (const xmlChar **) NULL)
7103           break;
7104         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7105         {
7106           keyword=(const char *) attributes[i++];
7107           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7108             msl_info->attributes[n],(const char *) attributes[i]));
7109           switch (*keyword)
7110           {
7111             case 'C':
7112             case 'c':
7113             {
7114               if (LocaleCompare(keyword,"color") == 0)
7115               {
7116                 PixelInfo
7117                   target;
7118
7119                 (void) QueryMagickColor(value,&target,&exception);
7120                 (void) TransparentPaintImage(msl_info->image[n],&target,
7121                   TransparentAlpha,MagickFalse);
7122                 break;
7123               }
7124               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7125               break;
7126             }
7127             default:
7128             {
7129               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7130             break;
7131             }
7132           }
7133         }
7134         break;
7135       }
7136       else if (LocaleCompare((const char *) tag, "trim") == 0)
7137       {
7138         if (msl_info->image[n] == (Image *) NULL)
7139           {
7140             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7141             break;
7142           }
7143
7144         /* no attributes here */
7145
7146         /* process the image */
7147         {
7148           Image
7149             *newImage;
7150           RectangleInfo
7151             rectInfo;
7152
7153           /* all zeros on a crop == trim edges! */
7154           rectInfo.height = rectInfo.width = 0;
7155           rectInfo.x =  rectInfo.y = 0;
7156
7157           newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7158           if (newImage == (Image *) NULL)
7159             break;
7160           msl_info->image[n]=DestroyImage(msl_info->image[n]);
7161           msl_info->image[n]=newImage;
7162           break;
7163         }
7164       }
7165       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7166     }
7167     case 'W':
7168     case 'w':
7169     {
7170       if (LocaleCompare((const char *) tag,"write") == 0)
7171         {
7172           if (msl_info->image[n] == (Image *) NULL)
7173             {
7174               ThrowMSLException(OptionError,"NoImagesDefined",
7175                 (const char *) tag);
7176               break;
7177             }
7178           if (attributes == (const xmlChar **) NULL)
7179             break;
7180           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7181           {
7182             keyword=(const char *) attributes[i++];
7183             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7184               msl_info->attributes[n],(const char *) attributes[i]));
7185             switch (*keyword)
7186             {
7187               case 'F':
7188               case 'f':
7189               {
7190                 if (LocaleCompare(keyword,"filename") == 0)
7191                   {
7192                     (void) CopyMagickString(msl_info->image[n]->filename,value,
7193                       MaxTextExtent);
7194                     break;
7195                   }
7196                 (void) SetMSLAttributes(msl_info,keyword,value);
7197               }
7198               default:
7199               {
7200                 (void) SetMSLAttributes(msl_info,keyword,value);
7201                 break;
7202               }
7203             }
7204           }
7205
7206           /* process */
7207           {
7208             (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7209             break;
7210           }
7211         }
7212       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7213     }
7214     default:
7215     {
7216       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7217       break;
7218     }
7219   }
7220   if ( value != NULL )
7221     value=DestroyString(value);
7222   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  )");
7223 }
7224
7225 static void MSLEndElement(void *context,const xmlChar *tag)
7226 {
7227   ssize_t
7228     n;
7229
7230   MSLInfo
7231     *msl_info;
7232
7233   /*
7234     Called when the end of an element has been detected.
7235   */
7236   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.endElement(%s)",
7237     tag);
7238   msl_info=(MSLInfo *) context;
7239   n=msl_info->n;
7240   switch (*tag)
7241   {
7242     case 'C':
7243     case 'c':
7244     {
7245       if (LocaleCompare((const char *) tag,"comment") == 0 )
7246         {
7247           (void) DeleteImageProperty(msl_info->image[n],"comment");
7248           if (msl_info->content == (char *) NULL)
7249             break;
7250           StripString(msl_info->content);
7251           (void) SetImageProperty(msl_info->image[n],"comment",
7252             msl_info->content);
7253           break;
7254         }
7255       break;
7256     }
7257     case 'G':
7258     case 'g':
7259     {
7260       if (LocaleCompare((const char *) tag, "group") == 0 )
7261       {
7262         if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7263         {
7264           ssize_t  i = (ssize_t)
7265             (msl_info->group_info[msl_info->number_groups-1].numImages);
7266           while ( i-- )
7267           {
7268             if (msl_info->image[msl_info->n] != (Image *) NULL)
7269               msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7270             msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7271             msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7272             msl_info->n--;
7273           }
7274         }
7275         msl_info->number_groups--;
7276       }
7277       break;
7278     }
7279     case 'I':
7280     case 'i':
7281     {
7282       if (LocaleCompare((const char *) tag, "image") == 0)
7283         MSLPopImage(msl_info);
7284        break;
7285     }
7286     case 'L':
7287     case 'l':
7288     {
7289       if (LocaleCompare((const char *) tag,"label") == 0 )
7290         {
7291           (void) DeleteImageProperty(msl_info->image[n],"label");
7292           if (msl_info->content == (char *) NULL)
7293             break;
7294           StripString(msl_info->content);
7295           (void) SetImageProperty(msl_info->image[n],"label",
7296             msl_info->content);
7297           break;
7298         }
7299       break;
7300     }
7301     case 'M':
7302     case 'm':
7303     {
7304       if (LocaleCompare((const char *) tag, "msl") == 0 )
7305       {
7306         /*
7307           This our base element.
7308             at the moment we don't do anything special
7309             but someday we might!
7310         */
7311       }
7312       break;
7313     }
7314     default:
7315       break;
7316   }
7317   if (msl_info->content != (char *) NULL)
7318     msl_info->content=DestroyString(msl_info->content);
7319 }
7320
7321 static void MSLCharacters(void *context,const xmlChar *c,int length)
7322 {
7323   MSLInfo
7324     *msl_info;
7325
7326   register char
7327     *p;
7328
7329   register ssize_t
7330     i;
7331
7332   /*
7333     Receiving some characters from the parser.
7334   */
7335   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7336     "  SAX.characters(%s,%d)",c,length);
7337   msl_info=(MSLInfo *) context;
7338   if (msl_info->content != (char *) NULL)
7339     msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7340       strlen(msl_info->content)+length+MaxTextExtent,
7341       sizeof(*msl_info->content));
7342   else
7343     {
7344       msl_info->content=(char *) NULL;
7345       if (~length >= (MaxTextExtent-1))
7346         msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7347           sizeof(*msl_info->content));
7348       if (msl_info->content != (char *) NULL)
7349         *msl_info->content='\0';
7350     }
7351   if (msl_info->content == (char *) NULL)
7352     return;
7353   p=msl_info->content+strlen(msl_info->content);
7354   for (i=0; i < length; i++)
7355     *p++=c[i];
7356   *p='\0';
7357 }
7358
7359 static void MSLReference(void *context,const xmlChar *name)
7360 {
7361   MSLInfo
7362     *msl_info;
7363
7364   xmlParserCtxtPtr
7365     parser;
7366
7367   /*
7368     Called when an entity reference is detected.
7369   */
7370   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7371     "  SAX.reference(%s)",name);
7372   msl_info=(MSLInfo *) context;
7373   parser=msl_info->parser;
7374   if (*name == '#')
7375     (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7376   else
7377     (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7378 }
7379
7380 static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7381 {
7382   MSLInfo
7383     *msl_info;
7384
7385   /*
7386     Receiving some ignorable whitespaces from the parser.
7387   */
7388   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7389     "  SAX.ignorableWhitespace(%.30s, %d)",c,length);
7390   msl_info=(MSLInfo *) context;
7391   (void) msl_info;
7392 }
7393
7394 static void MSLProcessingInstructions(void *context,const xmlChar *target,
7395   const xmlChar *data)
7396 {
7397   MSLInfo
7398     *msl_info;
7399
7400   /*
7401     A processing instruction has been parsed.
7402   */
7403   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7404     "  SAX.processingInstruction(%s, %s)",
7405     target,data);
7406   msl_info=(MSLInfo *) context;
7407   (void) msl_info;
7408 }
7409
7410 static void MSLComment(void *context,const xmlChar *value)
7411 {
7412   MSLInfo
7413     *msl_info;
7414
7415   /*
7416     A comment has been parsed.
7417   */
7418   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7419     "  SAX.comment(%s)",value);
7420   msl_info=(MSLInfo *) context;
7421   (void) msl_info;
7422 }
7423
7424 static void MSLWarning(void *context,const char *format,...)
7425 {
7426   char
7427     *message,
7428     reason[MaxTextExtent];
7429
7430   MSLInfo
7431     *msl_info;
7432
7433   va_list
7434     operands;
7435
7436   /**
7437     Display and format a warning messages, gives file, line, position and
7438     extra parameters.
7439   */
7440   va_start(operands,format);
7441   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.warning: ");
7442   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7443   msl_info=(MSLInfo *) context;
7444   (void) msl_info;
7445 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7446   (void) vsprintf(reason,format,operands);
7447 #else
7448   (void) vsnprintf(reason,MaxTextExtent,format,operands);
7449 #endif
7450   message=GetExceptionMessage(errno);
7451   ThrowMSLException(CoderError,reason,message);
7452   message=DestroyString(message);
7453   va_end(operands);
7454 }
7455
7456 static void MSLError(void *context,const char *format,...)
7457 {
7458   char
7459     reason[MaxTextExtent];
7460
7461   MSLInfo
7462     *msl_info;
7463
7464   va_list
7465     operands;
7466
7467   /*
7468     Display and format a error formats, gives file, line, position and
7469     extra parameters.
7470   */
7471   va_start(operands,format);
7472   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.error: ");
7473   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7474   msl_info=(MSLInfo *) context;
7475   (void) msl_info;
7476 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7477   (void) vsprintf(reason,format,operands);
7478 #else
7479   (void) vsnprintf(reason,MaxTextExtent,format,operands);
7480 #endif
7481   ThrowMSLException(DelegateFatalError,reason,"SAX error");
7482   va_end(operands);
7483 }
7484
7485 static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7486 {
7487   MSLInfo
7488     *msl_info;
7489
7490    xmlNodePtr
7491      child;
7492
7493   xmlParserCtxtPtr
7494     parser;
7495
7496   /*
7497     Called when a pcdata block has been parsed.
7498   */
7499   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7500     "  SAX.pcdata(%s, %d)",value,length);
7501   msl_info=(MSLInfo *) context;
7502   (void) msl_info;
7503   parser=msl_info->parser;
7504   child=xmlGetLastChild(parser->node);
7505   if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7506     {
7507       xmlTextConcat(child,value,length);
7508       return;
7509     }
7510   (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7511 }
7512
7513 static void MSLExternalSubset(void *context,const xmlChar *name,
7514   const xmlChar *external_id,const xmlChar *system_id)
7515 {
7516   MSLInfo
7517     *msl_info;
7518
7519   xmlParserCtxt
7520     parser_context;
7521
7522   xmlParserCtxtPtr
7523     parser;
7524
7525   xmlParserInputPtr
7526     input;
7527
7528   /*
7529     Does this document has an external subset?
7530   */
7531   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7532     "  SAX.externalSubset(%s %s %s)",name,
7533     (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7534     (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
7535   msl_info=(MSLInfo *) context;
7536   (void) msl_info;
7537   parser=msl_info->parser;
7538   if (((external_id == NULL) && (system_id == NULL)) ||
7539       ((parser->validate == 0) || (parser->wellFormed == 0) ||
7540       (msl_info->document == 0)))
7541     return;
7542   input=MSLResolveEntity(context,external_id,system_id);
7543   if (input == NULL)
7544     return;
7545   (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7546   parser_context=(*parser);
7547   parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7548   if (parser->inputTab == (xmlParserInputPtr *) NULL)
7549     {
7550       parser->errNo=XML_ERR_NO_MEMORY;
7551       parser->input=parser_context.input;
7552       parser->inputNr=parser_context.inputNr;
7553       parser->inputMax=parser_context.inputMax;
7554       parser->inputTab=parser_context.inputTab;
7555       return;
7556   }
7557   parser->inputNr=0;
7558   parser->inputMax=5;
7559   parser->input=NULL;
7560   xmlPushInput(parser,input);
7561   (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7562   if (input->filename == (char *) NULL)
7563     input->filename=(char *) xmlStrdup(system_id);
7564   input->line=1;
7565   input->col=1;
7566   input->base=parser->input->cur;
7567   input->cur=parser->input->cur;
7568   input->free=NULL;
7569   xmlParseExternalSubset(parser,external_id,system_id);
7570   while (parser->inputNr > 1)
7571     (void) xmlPopInput(parser);
7572   xmlFreeInputStream(parser->input);
7573   xmlFree(parser->inputTab);
7574   parser->input=parser_context.input;
7575   parser->inputNr=parser_context.inputNr;
7576   parser->inputMax=parser_context.inputMax;
7577   parser->inputTab=parser_context.inputTab;
7578 }
7579
7580 #if defined(__cplusplus) || defined(c_plusplus)
7581 }
7582 #endif
7583
7584 static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7585   ExceptionInfo *exception)
7586 {
7587   char
7588     message[MaxTextExtent];
7589
7590   Image
7591     *msl_image;
7592
7593   int
7594     status;
7595
7596   ssize_t
7597     n;
7598
7599   MSLInfo
7600     msl_info;
7601
7602   xmlSAXHandler
7603     sax_modules;
7604
7605   xmlSAXHandlerPtr
7606     sax_handler;
7607
7608   /*
7609     Open image file.
7610   */
7611   assert(image_info != (const ImageInfo *) NULL);
7612   assert(image_info->signature == MagickSignature);
7613   if (image_info->debug != MagickFalse)
7614     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7615       image_info->filename);
7616   assert(image != (Image **) NULL);
7617   msl_image=AcquireImage(image_info);
7618   status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7619   if (status == MagickFalse)
7620     {
7621       ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7622         msl_image->filename);
7623       msl_image=DestroyImageList(msl_image);
7624       return(MagickFalse);
7625     }
7626   msl_image->columns=1;
7627   msl_image->rows=1;
7628   /*
7629     Parse MSL file.
7630   */
7631   (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7632   msl_info.exception=exception;
7633   msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7634     sizeof(*msl_info.image_info));
7635   msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7636     sizeof(*msl_info.draw_info));
7637   /* top of the stack is the MSL file itself */
7638   msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
7639   msl_info.attributes=(Image **) AcquireMagickMemory(
7640     sizeof(*msl_info.attributes));
7641   msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7642     sizeof(*msl_info.group_info));
7643   if ((msl_info.image_info == (ImageInfo **) NULL) ||
7644       (msl_info.image == (Image **) NULL) ||
7645       (msl_info.attributes == (Image **) NULL) ||
7646       (msl_info.group_info == (MSLGroupInfo *) NULL))
7647     ThrowFatalException(ResourceLimitFatalError,
7648       "UnableToInterpretMSLImage");
7649   *msl_info.image_info=CloneImageInfo(image_info);
7650   *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7651   *msl_info.attributes=AcquireImage(image_info);
7652   msl_info.group_info[0].numImages=0;
7653   /* the first slot is used to point to the MSL file image */
7654   *msl_info.image=msl_image;
7655   if (*image != (Image *) NULL)
7656     MSLPushImage(&msl_info,*image);
7657   (void) xmlSubstituteEntitiesDefault(1);
7658   (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7659   sax_modules.internalSubset=MSLInternalSubset;
7660   sax_modules.isStandalone=MSLIsStandalone;
7661   sax_modules.hasInternalSubset=MSLHasInternalSubset;
7662   sax_modules.hasExternalSubset=MSLHasExternalSubset;
7663   sax_modules.resolveEntity=MSLResolveEntity;
7664   sax_modules.getEntity=MSLGetEntity;
7665   sax_modules.entityDecl=MSLEntityDeclaration;
7666   sax_modules.notationDecl=MSLNotationDeclaration;
7667   sax_modules.attributeDecl=MSLAttributeDeclaration;
7668   sax_modules.elementDecl=MSLElementDeclaration;
7669   sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7670   sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7671   sax_modules.startDocument=MSLStartDocument;
7672   sax_modules.endDocument=MSLEndDocument;
7673   sax_modules.startElement=MSLStartElement;
7674   sax_modules.endElement=MSLEndElement;
7675   sax_modules.reference=MSLReference;
7676   sax_modules.characters=MSLCharacters;
7677   sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7678   sax_modules.processingInstruction=MSLProcessingInstructions;
7679   sax_modules.comment=MSLComment;
7680   sax_modules.warning=MSLWarning;
7681   sax_modules.error=MSLError;
7682   sax_modules.fatalError=MSLError;
7683   sax_modules.getParameterEntity=MSLGetParameterEntity;
7684   sax_modules.cdataBlock=MSLCDataBlock;
7685   sax_modules.externalSubset=MSLExternalSubset;
7686   sax_handler=(&sax_modules);
7687   msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
7688     msl_image->filename);
7689   while (ReadBlobString(msl_image,message) != (char *) NULL)
7690   {
7691     n=(ssize_t) strlen(message);
7692     if (n == 0)
7693       continue;
7694     status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7695     if (status != 0)
7696       break;
7697     (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7698     if (msl_info.exception->severity >= ErrorException)
7699       break;
7700   }
7701   if (msl_info.exception->severity == UndefinedException)
7702     (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7703   xmlFreeParserCtxt(msl_info.parser);
7704   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7705   xmlCleanupParser();
7706   msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7707     msl_info.group_info);
7708   if (*image == (Image *) NULL)
7709     *image=(*msl_info.image);
7710   if ((*msl_info.image)->exception.severity != UndefinedException)
7711     return(MagickFalse);
7712   return(MagickTrue);
7713 }
7714
7715 static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7716 {
7717   Image
7718     *image;
7719
7720   /*
7721     Open image file.
7722   */
7723   assert(image_info != (const ImageInfo *) NULL);
7724   assert(image_info->signature == MagickSignature);
7725   if (image_info->debug != MagickFalse)
7726     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7727       image_info->filename);
7728   assert(exception != (ExceptionInfo *) NULL);
7729   assert(exception->signature == MagickSignature);
7730   image=(Image *) NULL;
7731   (void) ProcessMSLScript(image_info,&image,exception);
7732   return(GetFirstImageInList(image));
7733 }
7734 #endif
7735 \f
7736 /*
7737 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7738 %                                                                             %
7739 %                                                                             %
7740 %                                                                             %
7741 %   R e g i s t e r M S L I m a g e                                           %
7742 %                                                                             %
7743 %                                                                             %
7744 %                                                                             %
7745 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7746 %
7747 %  RegisterMSLImage() adds attributes for the MSL image format to
7748 %  the list of supported formats.  The attributes include the image format
7749 %  tag, a method to read and/or write the format, whether the format
7750 %  supports the saving of more than one frame to the same file or blob,
7751 %  whether the format supports native in-memory I/O, and a brief
7752 %  description of the format.
7753 %
7754 %  The format of the RegisterMSLImage method is:
7755 %
7756 %      size_t RegisterMSLImage(void)
7757 %
7758 */
7759 ModuleExport size_t RegisterMSLImage(void)
7760 {
7761   MagickInfo
7762     *entry;
7763
7764   entry=SetMagickInfo("MSL");
7765 #if defined(MAGICKCORE_XML_DELEGATE)
7766   entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7767   entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7768 #endif
7769   entry->description=ConstantString("Magick Scripting Language");
7770   entry->module=ConstantString("MSL");
7771   (void) RegisterMagickInfo(entry);
7772   return(MagickImageCoderSignature);
7773 }
7774 \f
7775 #if defined(MAGICKCORE_XML_DELEGATE)
7776 /*
7777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7778 %                                                                             %
7779 %                                                                             %
7780 %                                                                             %
7781 %   S e t M S L A t t r i b u t e s                                           %
7782 %                                                                             %
7783 %                                                                             %
7784 %                                                                             %
7785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7786 %
7787 %  SetMSLAttributes() ...
7788 %
7789 %  The format of the SetMSLAttributes method is:
7790 %
7791 %      MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
7792 %        const char *keyword,const char *value)
7793 %
7794 %  A description of each parameter follows:
7795 %
7796 %    o msl_info: the MSL info.
7797 %
7798 %    o keyword: the keyword.
7799 %
7800 %    o value: the value.
7801 %
7802 */
7803 static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7804   const char *value)
7805 {
7806   Image
7807     *attributes;
7808
7809   DrawInfo
7810     *draw_info;
7811
7812   ExceptionInfo
7813     *exception;
7814
7815   GeometryInfo
7816     geometry_info;
7817
7818   Image
7819     *image;
7820
7821   ImageInfo
7822     *image_info;
7823
7824   int
7825     flags;
7826
7827   ssize_t
7828     n;
7829
7830   assert(msl_info != (MSLInfo *) NULL);
7831   if (keyword == (const char *) NULL)
7832     return(MagickTrue);
7833   if (value == (const char *) NULL)
7834     return(MagickTrue);
7835   exception=msl_info->exception;
7836   n=msl_info->n;
7837   attributes=msl_info->attributes[n];
7838   image_info=msl_info->image_info[n];
7839   draw_info=msl_info->draw_info[n];
7840   image=msl_info->image[n];
7841   switch (*keyword)
7842   {
7843     case 'A':
7844     case 'a':
7845     {
7846       if (LocaleCompare(keyword,"adjoin") == 0)
7847         {
7848           ssize_t
7849             adjoin;
7850
7851           adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
7852           if (adjoin < 0)
7853             ThrowMSLException(OptionError,"UnrecognizedType",value);
7854           image_info->adjoin=(MagickBooleanType) adjoin;
7855           break;
7856         }
7857       if (LocaleCompare(keyword,"alpha") == 0)
7858         {
7859           ssize_t
7860             alpha;
7861
7862           alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
7863           if (alpha < 0)
7864             ThrowMSLException(OptionError,"UnrecognizedType",value);
7865           if (image != (Image *) NULL)
7866             (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha);
7867           break;
7868         }
7869       if (LocaleCompare(keyword,"antialias") == 0)
7870         {
7871           ssize_t
7872             antialias;
7873
7874           antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
7875           if (antialias < 0)
7876             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7877           image_info->antialias=(MagickBooleanType) antialias;
7878           break;
7879         }
7880       if (LocaleCompare(keyword,"area-limit") == 0)
7881         {
7882           MagickSizeType
7883             limit;
7884
7885           limit=MagickResourceInfinity;
7886           if (LocaleCompare(value,"unlimited") != 0)
7887             limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
7888           (void) SetMagickResourceLimit(AreaResource,limit);
7889           break;
7890         }
7891       if (LocaleCompare(keyword,"attenuate") == 0)
7892         {
7893           (void) SetImageOption(image_info,keyword,value);
7894           break;
7895         }
7896       if (LocaleCompare(keyword,"authenticate") == 0)
7897         {
7898           (void) CloneString(&image_info->density,value);
7899           break;
7900         }
7901       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7902       break;
7903     }
7904     case 'B':
7905     case 'b':
7906     {
7907       if (LocaleCompare(keyword,"background") == 0)
7908         {
7909           (void) QueryColorDatabase(value,&image_info->background_color,
7910             exception);
7911           break;
7912         }
7913       if (LocaleCompare(keyword,"bias") == 0)
7914         {
7915           if (image == (Image *) NULL)
7916             break;
7917           image->bias=SiPrefixToDouble(value,QuantumRange);
7918           break;
7919         }
7920       if (LocaleCompare(keyword,"blue-primary") == 0)
7921         {
7922           if (image == (Image *) NULL)
7923             break;
7924           flags=ParseGeometry(value,&geometry_info);
7925           image->chromaticity.blue_primary.x=geometry_info.rho;
7926           image->chromaticity.blue_primary.y=geometry_info.sigma;
7927           if ((flags & SigmaValue) == 0)
7928             image->chromaticity.blue_primary.y=
7929               image->chromaticity.blue_primary.x;
7930           break;
7931         }
7932       if (LocaleCompare(keyword,"bordercolor") == 0)
7933         {
7934           (void) QueryColorDatabase(value,&image_info->border_color,
7935             exception);
7936           break;
7937         }
7938       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7939       break;
7940     }
7941     case 'D':
7942     case 'd':
7943     {
7944       if (LocaleCompare(keyword,"density") == 0)
7945         {
7946           (void) CloneString(&image_info->density,value);
7947           (void) CloneString(&draw_info->density,value);
7948           break;
7949         }
7950       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7951       break;
7952     }
7953     case 'F':
7954     case 'f':
7955     {
7956       if (LocaleCompare(keyword,"fill") == 0)
7957         {
7958           (void) QueryColorDatabase(value,&draw_info->fill,exception);
7959           (void) SetImageOption(image_info,keyword,value);
7960           break;
7961         }
7962       if (LocaleCompare(keyword,"filename") == 0)
7963         {
7964           (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7965           break;
7966         }
7967       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7968       break;
7969     }
7970     case 'G':
7971     case 'g':
7972     {
7973       if (LocaleCompare(keyword,"gravity") == 0)
7974         {
7975           ssize_t
7976             gravity;
7977
7978           gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
7979           if (gravity < 0)
7980             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7981           (void) SetImageOption(image_info,keyword,value);
7982           break;
7983         }
7984       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7985       break;
7986     }
7987     case 'I':
7988     case 'i':
7989     {
7990       if (LocaleCompare(keyword,"id") == 0)
7991         {
7992           (void) SetImageProperty(attributes,keyword,value);
7993           break;
7994         }
7995       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7996       break;
7997     }
7998     case 'M':
7999     case 'm':
8000     {
8001       if (LocaleCompare(keyword,"magick") == 0)
8002         {
8003           (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
8004           break;
8005         }
8006       if (LocaleCompare(keyword,"mattecolor") == 0)
8007         {
8008           (void) QueryColorDatabase(value,&image_info->matte_color,
8009             exception);
8010           break;
8011         }
8012       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8013       break;
8014     }
8015     case 'P':
8016     case 'p':
8017     {
8018       if (LocaleCompare(keyword,"pointsize") == 0)
8019         {
8020           image_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8021           draw_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8022           break;
8023         }
8024       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8025       break;
8026     }
8027     case 'Q':
8028     case 'q':
8029     {
8030       if (LocaleCompare(keyword,"quality") == 0)
8031         {
8032           image_info->quality=StringToLong(value);
8033           if (image == (Image *) NULL)
8034             break;
8035           image->quality=StringToLong(value);
8036           break;
8037         }
8038       break;
8039     }
8040     case 'S':
8041     case 's':
8042     {
8043       if (LocaleCompare(keyword,"size") == 0)
8044         {
8045           (void) CloneString(&image_info->size,value);
8046           break;
8047         }
8048       if (LocaleCompare(keyword,"stroke") == 0)
8049         {
8050           (void) QueryColorDatabase(value,&draw_info->stroke,exception);
8051           (void) SetImageOption(image_info,keyword,value);
8052           break;
8053         }
8054       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8055       break;
8056     }
8057     default:
8058     {
8059       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8060       break;
8061     }
8062   }
8063   return(MagickTrue);
8064 }
8065 #endif
8066 \f
8067 /*
8068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8069 %                                                                             %
8070 %                                                                             %
8071 %                                                                             %
8072 %   U n r e g i s t e r M S L I m a g e                                       %
8073 %                                                                             %
8074 %                                                                             %
8075 %                                                                             %
8076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8077 %
8078 %  UnregisterMSLImage() removes format registrations made by the
8079 %  MSL module from the list of supported formats.
8080 %
8081 %  The format of the UnregisterMSLImage method is:
8082 %
8083 %      UnregisterMSLImage(void)
8084 %
8085 */
8086 ModuleExport void UnregisterMSLImage(void)
8087 {
8088   (void) UnregisterMagickInfo("MSL");
8089 }
8090 \f
8091 #if defined(MAGICKCORE_XML_DELEGATE)
8092 /*
8093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8094 %                                                                             %
8095 %                                                                             %
8096 %                                                                             %
8097 %   W r i t e M S L I m a g e                                                 %
8098 %                                                                             %
8099 %                                                                             %
8100 %                                                                             %
8101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8102 %
8103 %  WriteMSLImage() writes an image to a file in MVG image format.
8104 %
8105 %  The format of the WriteMSLImage method is:
8106 %
8107 %      MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8108 %
8109 %  A description of each parameter follows.
8110 %
8111 %    o image_info: the image info.
8112 %
8113 %    o image:  The image.
8114 %
8115 */
8116 static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8117 {
8118   assert(image_info != (const ImageInfo *) NULL);
8119   assert(image_info->signature == MagickSignature);
8120   assert(image != (Image *) NULL);
8121   assert(image->signature == MagickSignature);
8122   if (image->debug != MagickFalse)
8123     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8124   (void) ReferenceImage(image);
8125   (void) ProcessMSLScript(image_info,&image,&image->exception);
8126   return(MagickTrue);
8127 }
8128 #endif