]> granicus.if.org Git - imagemagick/blob - coders/msl.c
(no commit message)
[imagemagick] / coders / msl.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                             M   M  SSSSS  L                                 %
7 %                             MM MM  SS     L                                 %
8 %                             M M M   SSS   L                                 %
9 %                             M   M     SS  L                                 %
10 %                             M   M  SSSSS  LLLLL                             %
11 %                                                                             %
12 %                                                                             %
13 %                    Execute Magick Scripting Language Scripts.               %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                John Cristy                                  %
17 %                             Leonard Rosenthol                               %
18 %                             William Radcliffe                               %
19 %                               December 2001                                 %
20 %                                                                             %
21 %                                                                             %
22 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
23 %  dedicated to making software imaging solutions freely available.           %
24 %                                                                             %
25 %  You may not use this file except in compliance with the License.  You may  %
26 %  obtain a copy of the License at                                            %
27 %                                                                             %
28 %    http://www.imagemagick.org/script/license.php                            %
29 %                                                                             %
30 %  Unless required by applicable law or agreed to in writing, software        %
31 %  distributed under the License is distributed on an "AS IS" BASIS,          %
32 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
33 %  See the License for the specific language governing permissions and        %
34 %  limitations under the License.                                             %
35 %                                                                             %
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37 %
38 %
39 */
40 \f
41 /*
42   Include declarations.
43 */
44 #include "MagickCore/studio.h"
45 #include "MagickCore/annotate.h"
46 #include "MagickCore/artifact.h"
47 #include "MagickCore/blob.h"
48 #include "MagickCore/blob-private.h"
49 #include "MagickCore/cache.h"
50 #include "MagickCore/cache-view.h"
51 #include "MagickCore/color.h"
52 #include "MagickCore/colormap.h"
53 #include "MagickCore/color-private.h"
54 #include "MagickCore/composite.h"
55 #include "MagickCore/constitute.h"
56 #include "MagickCore/decorate.h"
57 #include "MagickCore/display.h"
58 #include "MagickCore/draw.h"
59 #include "MagickCore/effect.h"
60 #include "MagickCore/enhance.h"
61 #include "MagickCore/exception.h"
62 #include "MagickCore/exception-private.h"
63 #include "MagickCore/fx.h"
64 #include "MagickCore/geometry.h"
65 #include "MagickCore/image.h"
66 #include "MagickCore/image-private.h"
67 #include "MagickCore/list.h"
68 #include "MagickCore/log.h"
69 #include "MagickCore/magick.h"
70 #include "MagickCore/memory_.h"
71 #include "MagickCore/module.h"
72 #include "MagickCore/option.h"
73 #include "MagickCore/paint.h"
74 #include "MagickCore/pixel-accessor.h"
75 #include "MagickCore/profile.h"
76 #include "MagickCore/property.h"
77 #include "MagickCore/quantize.h"
78 #include "MagickCore/quantum-private.h"
79 #include "MagickCore/registry.h"
80 #include "MagickCore/resize.h"
81 #include "MagickCore/resource_.h"
82 #include "MagickCore/segment.h"
83 #include "MagickCore/shear.h"
84 #include "MagickCore/signature.h"
85 #include "MagickCore/static.h"
86 #include "MagickCore/string_.h"
87 #include "MagickCore/string-private.h"
88 #include "MagickCore/transform.h"
89 #include "MagickCore/threshold.h"
90 #include "MagickCore/utility.h"
91 #if defined(MAGICKCORE_XML_DELEGATE)
92 #  if defined(MAGICKCORE_WINDOWS_SUPPORT)
93 #    if defined(__MINGW32__)
94 #      define _MSC_VER
95 #    else
96 #      include <win32config.h>
97 #    endif
98 #  endif
99 #  include <libxml/parser.h>
100 #  include <libxml/xmlmemory.h>
101 #  include <libxml/parserInternals.h>
102 #  include <libxml/xmlerror.h>
103 #endif
104 \f
105 /*
106   Define Declatations.
107 */
108 #define ThrowMSLException(severity,tag,reason) \
109   (void) ThrowMagickException(msl_info->exception,GetMagickModule(),severity, \
110     tag,"`%s'",reason);
111 \f
112 /*
113   Typedef declaractions.
114 */
115 typedef struct _MSLGroupInfo
116 {
117   size_t
118     numImages;  /* how many images are in this group */
119 } MSLGroupInfo;
120
121 typedef struct _MSLInfo
122 {
123   ExceptionInfo
124     *exception;
125
126   ssize_t
127     n,
128     number_groups;
129
130   ImageInfo
131     **image_info;
132
133   DrawInfo
134    **draw_info;
135
136   Image
137     **attributes,
138     **image;
139
140   char
141     *content;
142
143   MSLGroupInfo
144     *group_info;
145
146 #if defined(MAGICKCORE_XML_DELEGATE)
147   xmlParserCtxtPtr
148     parser;
149
150   xmlDocPtr
151     document;
152 #endif
153 } MSLInfo;
154 \f
155 /*
156   Forward declarations.
157 */
158 #if defined(MAGICKCORE_XML_DELEGATE)
159 static MagickBooleanType
160   WriteMSLImage(const ImageInfo *,Image *);
161
162 static MagickBooleanType
163   SetMSLAttributes(MSLInfo *,const char *,const char *);
164 #endif
165 \f
166 #if defined(MAGICKCORE_XML_DELEGATE)
167 \f
168 /*
169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170 %                                                                             %
171 %                                                                             %
172 %                                                                             %
173 %   R e a d M S L I m a g e                                                   %
174 %                                                                             %
175 %                                                                             %
176 %                                                                             %
177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178 %
179 %  ReadMSLImage() reads a Magick Scripting Language file and returns it.
180 %  It allocates the memory necessary for the new Image structure and returns a
181 %  pointer to the new image.
182 %
183 %  The format of the ReadMSLImage method is:
184 %
185 %      Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
186 %
187 %  A description of each parameter follows:
188 %
189 %    o image_info: the image info.
190 %
191 %    o exception: return any errors or warnings in this structure.
192 %
193 */
194
195 #if defined(__cplusplus) || defined(c_plusplus)
196 extern "C" {
197 #endif
198
199 static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
200   ExceptionInfo *exception)
201 {
202   char
203     key[MaxTextExtent];
204
205   ExceptionInfo
206     *sans_exception;
207
208   Image
209     *image;
210
211   ImageInfo
212     *read_info;
213
214   (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
215   sans_exception=AcquireExceptionInfo();
216   image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
217   sans_exception=DestroyExceptionInfo(sans_exception);
218   if (image != (Image *) NULL)
219     return(image);
220   read_info=CloneImageInfo(image_info);
221   (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
222   image=ReadImage(read_info,exception);
223   read_info=DestroyImageInfo(read_info);
224   if (image != (Image *) NULL)
225     (void) SetImageRegistry(ImageRegistryType,key,image,exception);
226   return(image);
227 }
228
229 static int IsPathDirectory(const char *path)
230 {
231   MagickBooleanType
232     status;
233
234   struct stat
235     attributes;
236
237   if ((path == (const char *) NULL) || (*path == '\0'))
238     return(MagickFalse);
239   status=GetPathAttributes(path,&attributes);
240   if (status == MagickFalse)
241     return(-1);
242   if (S_ISDIR(attributes.st_mode) == 0)
243     return(0);
244   return(1);
245 }
246
247 static int MSLIsStandalone(void *context)
248 {
249   MSLInfo
250     *msl_info;
251
252   /*
253     Is this document tagged standalone?
254   */
255   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.MSLIsStandalone()");
256   msl_info=(MSLInfo *) context;
257   return(msl_info->document->standalone == 1);
258 }
259
260 static int MSLHasInternalSubset(void *context)
261 {
262   MSLInfo
263     *msl_info;
264
265   /*
266     Does this document has an internal subset?
267   */
268   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
269     "  SAX.MSLHasInternalSubset()");
270   msl_info=(MSLInfo *) context;
271   return(msl_info->document->intSubset != NULL);
272 }
273
274 static int MSLHasExternalSubset(void *context)
275 {
276   MSLInfo
277     *msl_info;
278
279   /*
280     Does this document has an external subset?
281   */
282   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
283     "  SAX.MSLHasExternalSubset()");
284   msl_info=(MSLInfo *) context;
285   return(msl_info->document->extSubset != NULL);
286 }
287
288 static void MSLInternalSubset(void *context,const xmlChar *name,
289   const xmlChar *external_id,const xmlChar *system_id)
290 {
291   MSLInfo
292     *msl_info;
293
294   /*
295     Does this document has an internal subset?
296   */
297   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
298     "  SAX.internalSubset(%s %s %s)",name,
299     (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
300     (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
301   msl_info=(MSLInfo *) context;
302   (void) xmlCreateIntSubset(msl_info->document,name,external_id,system_id);
303 }
304
305 static xmlParserInputPtr MSLResolveEntity(void *context,
306   const xmlChar *public_id,const xmlChar *system_id)
307 {
308   MSLInfo
309     *msl_info;
310
311   xmlParserInputPtr
312     stream;
313
314   /*
315     Special entity resolver, better left to the parser, it has more
316     context than the application layer.  The default behaviour is to
317     not resolve the entities, in that case the ENTITY_REF nodes are
318     built in the structure (and the parameter values).
319   */
320   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
321     "  SAX.resolveEntity(%s, %s)",
322     (public_id != (const xmlChar *) NULL ? (const char *) public_id : "none"),
323     (system_id != (const xmlChar *) NULL ? (const char *) system_id : "none"));
324   msl_info=(MSLInfo *) context;
325   stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
326     public_id,msl_info->parser);
327   return(stream);
328 }
329
330 static xmlEntityPtr MSLGetEntity(void *context,const xmlChar *name)
331 {
332   MSLInfo
333     *msl_info;
334
335   /*
336     Get an entity by name.
337   */
338   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
339     "  SAX.MSLGetEntity(%s)",(const char *) name);
340   msl_info=(MSLInfo *) context;
341   return(xmlGetDocEntity(msl_info->document,name));
342 }
343
344 static xmlEntityPtr MSLGetParameterEntity(void *context,const xmlChar *name)
345 {
346   MSLInfo
347     *msl_info;
348
349   /*
350     Get a parameter entity by name.
351   */
352   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
353     "  SAX.getParameterEntity(%s)",(const char *) name);
354   msl_info=(MSLInfo *) context;
355   return(xmlGetParameterEntity(msl_info->document,name));
356 }
357
358 static void MSLEntityDeclaration(void *context,const xmlChar *name,int type,
359   const xmlChar *public_id,const xmlChar *system_id,xmlChar *content)
360 {
361   MSLInfo
362     *msl_info;
363
364   /*
365     An entity definition has been parsed.
366   */
367   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
368     "  SAX.entityDecl(%s, %d, %s, %s, %s)",name,type,
369     public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
370     system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
371     content);
372   msl_info=(MSLInfo *) context;
373   if (msl_info->parser->inSubset == 1)
374     (void) xmlAddDocEntity(msl_info->document,name,type,public_id,system_id,
375       content);
376   else
377     if (msl_info->parser->inSubset == 2)
378       (void) xmlAddDtdEntity(msl_info->document,name,type,public_id,system_id,
379         content);
380 }
381
382 static void MSLAttributeDeclaration(void *context,const xmlChar *element,
383   const xmlChar *name,int type,int value,const xmlChar *default_value,
384   xmlEnumerationPtr tree)
385 {
386   MSLInfo
387     *msl_info;
388
389   xmlChar
390     *fullname,
391     *prefix;
392
393   xmlParserCtxtPtr
394     parser;
395
396   /*
397     An attribute definition has been parsed.
398   */
399   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
400     "  SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",element,name,type,value,
401     default_value);
402   msl_info=(MSLInfo *) context;
403   fullname=(xmlChar *) NULL;
404   prefix=(xmlChar *) NULL;
405   parser=msl_info->parser;
406   fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
407   if (parser->inSubset == 1)
408     (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->intSubset,
409       element,fullname,prefix,(xmlAttributeType) type,
410       (xmlAttributeDefault) value,default_value,tree);
411   else
412     if (parser->inSubset == 2)
413       (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->extSubset,
414         element,fullname,prefix,(xmlAttributeType) type,
415         (xmlAttributeDefault) value,default_value,tree);
416   if (prefix != (xmlChar *) NULL)
417     xmlFree(prefix);
418   if (fullname != (xmlChar *) NULL)
419     xmlFree(fullname);
420 }
421
422 static void MSLElementDeclaration(void *context,const xmlChar *name,int type,
423   xmlElementContentPtr content)
424 {
425   MSLInfo
426     *msl_info;
427
428   xmlParserCtxtPtr
429     parser;
430
431   /*
432     An element definition has been parsed.
433   */
434   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
435     "  SAX.elementDecl(%s, %d, ...)",name,type);
436   msl_info=(MSLInfo *) context;
437   parser=msl_info->parser;
438   if (parser->inSubset == 1)
439     (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->intSubset,
440       name,(xmlElementTypeVal) type,content);
441   else
442     if (parser->inSubset == 2)
443       (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->extSubset,
444         name,(xmlElementTypeVal) type,content);
445 }
446
447 static void MSLNotationDeclaration(void *context,const xmlChar *name,
448   const xmlChar *public_id,const xmlChar *system_id)
449 {
450   MSLInfo
451     *msl_info;
452
453   xmlParserCtxtPtr
454     parser;
455
456   /*
457     What to do when a notation declaration has been parsed.
458   */
459   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
460     "  SAX.notationDecl(%s, %s, %s)",name,
461     public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
462     system_id != (const xmlChar *) NULL ? (const char *) system_id : "none");
463   msl_info=(MSLInfo *) context;
464   parser=msl_info->parser;
465   if (parser->inSubset == 1)
466     (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
467       name,public_id,system_id);
468   else
469     if (parser->inSubset == 2)
470       (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
471         name,public_id,system_id);
472 }
473
474 static void MSLUnparsedEntityDeclaration(void *context,const xmlChar *name,
475   const xmlChar *public_id,const xmlChar *system_id,const xmlChar *notation)
476 {
477   MSLInfo
478     *msl_info;
479
480   /*
481     What to do when an unparsed entity declaration is parsed.
482   */
483   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
484     "  SAX.unparsedEntityDecl(%s, %s, %s, %s)",name,
485     public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
486     system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
487     notation);
488   msl_info=(MSLInfo *) context;
489   (void) xmlAddDocEntity(msl_info->document,name,
490     XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,public_id,system_id,notation);
491
492 }
493
494 static void MSLSetDocumentLocator(void *context,xmlSAXLocatorPtr location)
495 {
496   MSLInfo
497     *msl_info;
498
499   /*
500     Receive the document locator at startup, actually xmlDefaultSAXLocator.
501   */
502   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
503     "  SAX.setDocumentLocator()\n");
504   (void) location;
505   msl_info=(MSLInfo *) context;
506   (void) msl_info;
507 }
508
509 static void MSLStartDocument(void *context)
510 {
511   MSLInfo
512     *msl_info;
513
514   xmlParserCtxtPtr
515     parser;
516
517   /*
518     Called when the document start being processed.
519   */
520   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
521     "  SAX.startDocument()");
522   msl_info=(MSLInfo *) context;
523   parser=msl_info->parser;
524   msl_info->document=xmlNewDoc(parser->version);
525   if (msl_info->document == (xmlDocPtr) NULL)
526     return;
527   if (parser->encoding == NULL)
528     msl_info->document->encoding=NULL;
529   else
530     msl_info->document->encoding=xmlStrdup(parser->encoding);
531   msl_info->document->standalone=parser->standalone;
532 }
533
534 static void MSLEndDocument(void *context)
535 {
536   MSLInfo
537     *msl_info;
538
539   /*
540     Called when the document end has been detected.
541   */
542   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.endDocument()");
543   msl_info=(MSLInfo *) context;
544   if (msl_info->content != (char *) NULL)
545     msl_info->content=DestroyString(msl_info->content);
546 }
547
548 static void MSLPushImage(MSLInfo *msl_info,Image *image)
549 {
550   ssize_t
551     n;
552
553   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
554   assert(msl_info != (MSLInfo *) NULL);
555   msl_info->n++;
556   n=msl_info->n;
557   msl_info->image_info=(ImageInfo **) ResizeQuantumMemory(msl_info->image_info,
558     (n+1),sizeof(*msl_info->image_info));
559   msl_info->draw_info=(DrawInfo **) ResizeQuantumMemory(msl_info->draw_info,
560     (n+1),sizeof(*msl_info->draw_info));
561   msl_info->attributes=(Image **) ResizeQuantumMemory(msl_info->attributes,
562     (n+1),sizeof(*msl_info->attributes));
563   msl_info->image=(Image **) ResizeQuantumMemory(msl_info->image,(n+1),
564     sizeof(*msl_info->image));
565   if ((msl_info->image_info == (ImageInfo **) NULL) ||
566     (msl_info->draw_info == (DrawInfo **) NULL) ||
567     (msl_info->attributes == (Image **) NULL) ||
568     (msl_info->image == (Image **) NULL))
569       ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
570   msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
571   msl_info->draw_info[n]=CloneDrawInfo(msl_info->image_info[n-1],
572     msl_info->draw_info[n-1]);
573   if (image == (Image *) NULL)
574     msl_info->attributes[n]=AcquireImage(msl_info->image_info[n]);
575   else
576     msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,&image->exception);
577   msl_info->image[n]=(Image *) image;
578   if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
579     (msl_info->attributes[n] == (Image *) NULL))
580     ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
581   if (msl_info->number_groups != 0)
582     msl_info->group_info[msl_info->number_groups-1].numImages++;
583 }
584
585 static void MSLPopImage(MSLInfo *msl_info)
586 {
587   if (msl_info->number_groups != 0)
588     return;
589   if (msl_info->image[msl_info->n] != (Image *) NULL)
590     msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
591   msl_info->attributes[msl_info->n]=DestroyImage(
592     msl_info->attributes[msl_info->n]);
593   msl_info->image_info[msl_info->n]=DestroyImageInfo(
594     msl_info->image_info[msl_info->n]);
595   msl_info->n--;
596 }
597
598 static void MSLStartElement(void *context,const xmlChar *tag,
599   const xmlChar **attributes)
600 {
601   AffineMatrix
602     affine,
603     current;
604
605   ChannelType
606     channel;
607
608   char
609     key[MaxTextExtent],
610     *value;
611
612   const char
613     *attribute,
614     *keyword;
615
616   double
617     angle;
618
619   DrawInfo
620     *draw_info;
621
622   ExceptionInfo
623     exception;
624
625   GeometryInfo
626     geometry_info;
627
628   Image
629     *image;
630
631   int
632     flags;
633
634   ssize_t
635     option,
636     j,
637     n,
638     x,
639     y;
640
641   MSLInfo
642     *msl_info;
643
644   RectangleInfo
645     geometry;
646
647   register ssize_t
648     i;
649
650   size_t
651     height,
652     width;
653
654   /*
655     Called when an opening tag has been processed.
656   */
657   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
658     "  SAX.startElement(%s",tag);
659   GetExceptionInfo(&exception);
660   msl_info=(MSLInfo *) context;
661   n=msl_info->n;
662   keyword=(const char *) NULL;
663   value=(char *) NULL;
664   SetGeometryInfo(&geometry_info);
665   channel=DefaultChannels;
666   switch (*tag)
667   {
668     case 'A':
669     case 'a':
670     {
671       if (LocaleCompare((const char *) tag,"add-noise") == 0)
672         {
673           Image
674             *noise_image;
675
676           NoiseType
677             noise;
678
679           /*
680             Add noise image.
681           */
682           if (msl_info->image[n] == (Image *) NULL)
683             {
684               ThrowMSLException(OptionError,"NoImagesDefined",
685                 (const char *) tag);
686               break;
687             }
688           noise=UniformNoise;
689           if (attributes != (const xmlChar **) NULL)
690             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
691             {
692               keyword=(const char *) attributes[i++];
693               attribute=InterpretImageProperties(msl_info->image_info[n],
694                 msl_info->attributes[n],(const char *) attributes[i]);
695               CloneString(&value,attribute);
696               switch (*keyword)
697               {
698                 case 'C':
699                 case 'c':
700                 {
701                   if (LocaleCompare(keyword,"channel") == 0)
702                     {
703                       option=ParseChannelOption(value);
704                       if (option < 0)
705                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
706                           value);
707                       channel=(ChannelType) option;
708                       break;
709                     }
710                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
711                     keyword);
712                   break;
713                 }
714                 case 'N':
715                 case 'n':
716                 {
717                   if (LocaleCompare(keyword,"noise") == 0)
718                     {
719                       option=ParseCommandOption(MagickNoiseOptions,MagickFalse,
720                         value);
721                       if (option < 0)
722                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
723                           value);
724                       noise=(NoiseType) option;
725                       break;
726                     }
727                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
728                     keyword);
729                   break;
730                 }
731                 default:
732                 {
733                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
734                     keyword);
735                   break;
736                 }
737               }
738             }
739           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         {
3513           char level[MaxTextExtent + 1];
3514           (void) FormatLocaleString(level,MaxTextExtent,"%3.6f/%3.6f/%3.6f/",
3515             levelBlack,levelGamma,levelWhite);
3516           LevelImage ( msl_info->image[n], level );
3517           break;
3518         }
3519       }
3520     }
3521     case 'M':
3522     case 'm':
3523     {
3524       if (LocaleCompare((const char *) tag,"magnify") == 0)
3525         {
3526           Image
3527             *magnify_image;
3528
3529           /*
3530             Magnify image.
3531           */
3532           if (msl_info->image[n] == (Image *) NULL)
3533             {
3534               ThrowMSLException(OptionError,"NoImagesDefined",
3535                 (const char *) tag);
3536               break;
3537             }
3538           if (attributes != (const xmlChar **) NULL)
3539             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3540             {
3541               keyword=(const char *) attributes[i++];
3542               attribute=InterpretImageProperties(msl_info->image_info[n],
3543                 msl_info->attributes[n],(const char *) attributes[i]);
3544               CloneString(&value,attribute);
3545               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3546             }
3547           magnify_image=MagnifyImage(msl_info->image[n],
3548             &msl_info->image[n]->exception);
3549           if (magnify_image == (Image *) NULL)
3550             break;
3551           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3552           msl_info->image[n]=magnify_image;
3553           break;
3554         }
3555       if (LocaleCompare((const char *) tag,"map") == 0)
3556         {
3557           Image
3558             *affinity_image;
3559
3560           MagickBooleanType
3561             dither;
3562
3563           QuantizeInfo
3564             *quantize_info;
3565
3566           /*
3567             Map image.
3568           */
3569           if (msl_info->image[n] == (Image *) NULL)
3570             {
3571               ThrowMSLException(OptionError,"NoImagesDefined",
3572                 (const char *) tag);
3573               break;
3574             }
3575           affinity_image=NewImageList();
3576           dither=MagickFalse;
3577           if (attributes != (const xmlChar **) NULL)
3578             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3579             {
3580               keyword=(const char *) attributes[i++];
3581               attribute=InterpretImageProperties(msl_info->image_info[n],
3582                 msl_info->attributes[n],(const char *) attributes[i]);
3583               CloneString(&value,attribute);
3584               switch (*keyword)
3585               {
3586                 case 'D':
3587                 case 'd':
3588                 {
3589                   if (LocaleCompare(keyword,"dither") == 0)
3590                     {
3591                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
3592                         value);
3593                       if (option < 0)
3594                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3595                           value);
3596                       dither=(MagickBooleanType) option;
3597                       break;
3598                     }
3599                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3600                     keyword);
3601                   break;
3602                 }
3603                 case 'I':
3604                 case 'i':
3605                 {
3606                   if (LocaleCompare(keyword,"image") == 0)
3607                     for (j=0; j < msl_info->n; j++)
3608                     {
3609                       const char
3610                         *attribute;
3611
3612                       attribute=GetImageProperty(msl_info->attributes[j],"id");
3613                       if ((attribute != (const char *) NULL)  &&
3614                           (LocaleCompare(attribute,value) == 0))
3615                         {
3616                           affinity_image=CloneImage(msl_info->image[j],0,0,
3617                             MagickFalse,&exception);
3618                           break;
3619                         }
3620                     }
3621                   break;
3622                 }
3623                 default:
3624                 {
3625                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3626                     keyword);
3627                   break;
3628                 }
3629               }
3630             }
3631           quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3632           quantize_info->dither=dither;
3633           (void) RemapImages(quantize_info,msl_info->image[n],
3634             affinity_image);
3635           quantize_info=DestroyQuantizeInfo(quantize_info);
3636           affinity_image=DestroyImage(affinity_image);
3637           break;
3638         }
3639       if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
3640         {
3641           double
3642             opacity;
3643
3644           PixelInfo
3645             target;
3646
3647           PaintMethod
3648             paint_method;
3649
3650           /*
3651             Matte floodfill image.
3652           */
3653           opacity=0.0;
3654           if (msl_info->image[n] == (Image *) NULL)
3655             {
3656               ThrowMSLException(OptionError,"NoImagesDefined",
3657                 (const char *) tag);
3658               break;
3659             }
3660           SetGeometry(msl_info->image[n],&geometry);
3661           paint_method=FloodfillMethod;
3662           if (attributes != (const xmlChar **) NULL)
3663             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3664             {
3665               keyword=(const char *) attributes[i++];
3666               attribute=InterpretImageProperties(msl_info->image_info[n],
3667                 msl_info->attributes[n],(const char *) attributes[i]);
3668               CloneString(&value,attribute);
3669               switch (*keyword)
3670               {
3671                 case 'B':
3672                 case 'b':
3673                 {
3674                   if (LocaleCompare(keyword,"bordercolor") == 0)
3675                     {
3676                       (void) QueryMagickColor(value,&target,&exception);
3677                       paint_method=FillToBorderMethod;
3678                       break;
3679                     }
3680                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3681                     keyword);
3682                   break;
3683                 }
3684                 case 'F':
3685                 case 'f':
3686                 {
3687                   if (LocaleCompare(keyword,"fuzz") == 0)
3688                     {
3689                       msl_info->image[n]->fuzz=InterpretLocaleValue(value,
3690                         (char **) NULL);
3691                       break;
3692                     }
3693                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3694                     keyword);
3695                   break;
3696                 }
3697                 case 'G':
3698                 case 'g':
3699                 {
3700                   if (LocaleCompare(keyword,"geometry") == 0)
3701                     {
3702                       flags=ParsePageGeometry(msl_info->image[n],value,
3703                         &geometry,&exception);
3704                       if ((flags & HeightValue) == 0)
3705                         geometry.height=geometry.width;
3706                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
3707                         geometry.x,geometry.y,&target,&exception);
3708                       break;
3709                     }
3710                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3711                     keyword);
3712                   break;
3713                 }
3714                 case 'O':
3715                 case 'o':
3716                 {
3717                   if (LocaleCompare(keyword,"opacity") == 0)
3718                     {
3719                       opacity=InterpretLocaleValue(value,(char **) NULL);
3720                       break;
3721                     }
3722                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3723                     keyword);
3724                   break;
3725                 }
3726                 case 'X':
3727                 case 'x':
3728                 {
3729                   if (LocaleCompare(keyword,"x") == 0)
3730                     {
3731                       geometry.x=StringToLong(value);
3732                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
3733                         geometry.x,geometry.y,&target,&exception);
3734                       break;
3735                     }
3736                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3737                     keyword);
3738                   break;
3739                 }
3740                 case 'Y':
3741                 case 'y':
3742                 {
3743                   if (LocaleCompare(keyword,"y") == 0)
3744                     {
3745                       geometry.y=StringToLong(value);
3746                       (void) GetOneVirtualMagickPixel(msl_info->image[n],
3747                         geometry.x,geometry.y,&target,&exception);
3748                       break;
3749                     }
3750                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3751                     keyword);
3752                   break;
3753                 }
3754                 default:
3755                 {
3756                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3757                     keyword);
3758                   break;
3759                 }
3760               }
3761             }
3762           draw_info=CloneDrawInfo(msl_info->image_info[n],
3763             msl_info->draw_info[n]);
3764           draw_info->fill.alpha=ClampToQuantum(opacity);
3765           (void) FloodfillPaintImage(msl_info->image[n],OpacityChannel,
3766             draw_info,&target,geometry.x,geometry.y,
3767             paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
3768           draw_info=DestroyDrawInfo(draw_info);
3769           break;
3770         }
3771       if (LocaleCompare((const char *) tag,"median-filter") == 0)
3772         {
3773           Image
3774             *median_image;
3775
3776           /*
3777             Median-filter image.
3778           */
3779           if (msl_info->image[n] == (Image *) NULL)
3780             {
3781               ThrowMSLException(OptionError,"NoImagesDefined",
3782                 (const char *) tag);
3783               break;
3784             }
3785           if (attributes != (const xmlChar **) NULL)
3786             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3787             {
3788               keyword=(const char *) attributes[i++];
3789               attribute=InterpretImageProperties(msl_info->image_info[n],
3790                 msl_info->attributes[n],(const char *) attributes[i]);
3791               CloneString(&value,attribute);
3792               switch (*keyword)
3793               {
3794                 case 'G':
3795                 case 'g':
3796                 {
3797                   if (LocaleCompare(keyword,"geometry") == 0)
3798                     {
3799                       flags=ParseGeometry(value,&geometry_info);
3800                       if ((flags & SigmaValue) == 0)
3801                         geometry_info.sigma=1.0;
3802                       break;
3803                     }
3804                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3805                     keyword);
3806                   break;
3807                 }
3808                 case 'R':
3809                 case 'r':
3810                 {
3811                   if (LocaleCompare(keyword,"radius") == 0)
3812                     {
3813                       geometry_info.rho=InterpretLocaleValue(value,
3814                         (char **) NULL);
3815                       break;
3816                     }
3817                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3818                     keyword);
3819                   break;
3820                 }
3821                 default:
3822                 {
3823                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3824                     keyword);
3825                   break;
3826                 }
3827               }
3828             }
3829           median_image=StatisticImage(msl_info->image[n],MedianStatistic,
3830             (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3831             &msl_info->image[n]->exception);
3832           if (median_image == (Image *) NULL)
3833             break;
3834           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3835           msl_info->image[n]=median_image;
3836           break;
3837         }
3838       if (LocaleCompare((const char *) tag,"minify") == 0)
3839         {
3840           Image
3841             *minify_image;
3842
3843           /*
3844             Minify image.
3845           */
3846           if (msl_info->image[n] == (Image *) NULL)
3847             {
3848               ThrowMSLException(OptionError,"NoImagesDefined",
3849                 (const char *) tag);
3850               break;
3851             }
3852           if (attributes != (const xmlChar **) NULL)
3853             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3854             {
3855               keyword=(const char *) attributes[i++];
3856               attribute=InterpretImageProperties(msl_info->image_info[n],
3857                 msl_info->attributes[n],(const char *) attributes[i]);
3858               CloneString(&value,attribute);
3859               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3860             }
3861           minify_image=MinifyImage(msl_info->image[n],
3862             &msl_info->image[n]->exception);
3863           if (minify_image == (Image *) NULL)
3864             break;
3865           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3866           msl_info->image[n]=minify_image;
3867           break;
3868         }
3869       if (LocaleCompare((const char *) tag,"msl") == 0 )
3870         break;
3871       if (LocaleCompare((const char *) tag,"modulate") == 0)
3872         {
3873           char
3874             modulate[MaxTextExtent];
3875
3876           /*
3877             Modulate image.
3878           */
3879           if (msl_info->image[n] == (Image *) NULL)
3880             {
3881               ThrowMSLException(OptionError,"NoImagesDefined",
3882                 (const char *) tag);
3883               break;
3884             }
3885           geometry_info.rho=100.0;
3886           geometry_info.sigma=100.0;
3887           geometry_info.xi=100.0;
3888           if (attributes != (const xmlChar **) NULL)
3889             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3890             {
3891               keyword=(const char *) attributes[i++];
3892               attribute=InterpretImageProperties(msl_info->image_info[n],
3893                 msl_info->attributes[n],(const char *) attributes[i]);
3894               CloneString(&value,attribute);
3895               switch (*keyword)
3896               {
3897                 case 'B':
3898                 case 'b':
3899                 {
3900                   if (LocaleCompare(keyword,"blackness") == 0)
3901                     {
3902                       geometry_info.rho=InterpretLocaleValue(value,
3903                         (char **) NULL);
3904                       break;
3905                     }
3906                   if (LocaleCompare(keyword,"brightness") == 0)
3907                     {
3908                       geometry_info.rho=InterpretLocaleValue(value,
3909                         (char **) NULL);
3910                       break;
3911                     }
3912                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3913                     keyword);
3914                   break;
3915                 }
3916                 case 'F':
3917                 case 'f':
3918                 {
3919                   if (LocaleCompare(keyword,"factor") == 0)
3920                     {
3921                       flags=ParseGeometry(value,&geometry_info);
3922                       break;
3923                     }
3924                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3925                     keyword);
3926                   break;
3927                 }
3928                 case 'H':
3929                 case 'h':
3930                 {
3931                   if (LocaleCompare(keyword,"hue") == 0)
3932                     {
3933                       geometry_info.xi=InterpretLocaleValue(value,
3934                         (char **) NULL);
3935                       break;
3936                     }
3937                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3938                     keyword);
3939                   break;
3940                 }
3941                 case 'L':
3942                 case 'l':
3943                 {
3944                   if (LocaleCompare(keyword,"lightness") == 0)
3945                     {
3946                       geometry_info.rho=InterpretLocaleValue(value,
3947                         (char **) NULL);
3948                       break;
3949                     }
3950                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3951                     keyword);
3952                   break;
3953                 }
3954                 case 'S':
3955                 case 's':
3956                 {
3957                   if (LocaleCompare(keyword,"saturation") == 0)
3958                     {
3959                       geometry_info.sigma=InterpretLocaleValue(value,
3960                         (char **) NULL);
3961                       break;
3962                     }
3963                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3964                     keyword);
3965                   break;
3966                 }
3967                 case 'W':
3968                 case 'w':
3969                 {
3970                   if (LocaleCompare(keyword,"whiteness") == 0)
3971                     {
3972                       geometry_info.sigma=InterpretLocaleValue(value,
3973                         (char **) NULL);
3974                       break;
3975                     }
3976                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3977                     keyword);
3978                   break;
3979                 }
3980                 default:
3981                 {
3982                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3983                     keyword);
3984                   break;
3985                 }
3986               }
3987             }
3988           (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
3989             geometry_info.rho,geometry_info.sigma,geometry_info.xi);
3990           (void) ModulateImage(msl_info->image[n],modulate);
3991           break;
3992         }
3993       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3994     }
3995     case 'N':
3996     case 'n':
3997     {
3998       if (LocaleCompare((const char *) tag,"negate") == 0)
3999         {
4000           MagickBooleanType
4001             gray;
4002
4003           /*
4004             Negate image.
4005           */
4006           if (msl_info->image[n] == (Image *) NULL)
4007             {
4008               ThrowMSLException(OptionError,"NoImagesDefined",
4009                 (const char *) tag);
4010               break;
4011             }
4012           gray=MagickFalse;
4013           if (attributes != (const xmlChar **) NULL)
4014             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4015             {
4016               keyword=(const char *) attributes[i++];
4017               attribute=InterpretImageProperties(msl_info->image_info[n],
4018                 msl_info->attributes[n],(const char *) attributes[i]);
4019               CloneString(&value,attribute);
4020               switch (*keyword)
4021               {
4022                 case 'C':
4023                 case 'c':
4024                 {
4025                   if (LocaleCompare(keyword,"channel") == 0)
4026                     {
4027                       option=ParseChannelOption(value);
4028                       if (option < 0)
4029                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4030                           value);
4031                       channel=(ChannelType) option;
4032                       break;
4033                     }
4034                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4035                     keyword);
4036                   break;
4037                 }
4038                 case 'G':
4039                 case 'g':
4040                 {
4041                   if (LocaleCompare(keyword,"gray") == 0)
4042                     {
4043                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4044                         value);
4045                       if (option < 0)
4046                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4047                           value);
4048                       gray=(MagickBooleanType) option;
4049                       break;
4050                     }
4051                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4052                     keyword);
4053                   break;
4054                 }
4055                 default:
4056                 {
4057                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4058                     keyword);
4059                   break;
4060                 }
4061               }
4062             }
4063           (void) NegateImageChannel(msl_info->image[n],channel,gray);
4064           break;
4065         }
4066       if (LocaleCompare((const char *) tag,"normalize") == 0)
4067         {
4068           /*
4069             Normalize image.
4070           */
4071           if (msl_info->image[n] == (Image *) NULL)
4072             {
4073               ThrowMSLException(OptionError,"NoImagesDefined",
4074                 (const char *) tag);
4075               break;
4076             }
4077           if (attributes != (const xmlChar **) NULL)
4078             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4079             {
4080               keyword=(const char *) attributes[i++];
4081               attribute=InterpretImageProperties(msl_info->image_info[n],
4082                 msl_info->attributes[n],(const char *) attributes[i]);
4083               CloneString(&value,attribute);
4084               switch (*keyword)
4085               {
4086                 case 'C':
4087                 case 'c':
4088                 {
4089                   if (LocaleCompare(keyword,"channel") == 0)
4090                     {
4091                       option=ParseChannelOption(value);
4092                       if (option < 0)
4093                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4094                           value);
4095                       channel=(ChannelType) option;
4096                       break;
4097                     }
4098                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4099                     keyword);
4100                   break;
4101                 }
4102                 default:
4103                 {
4104                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4105                     keyword);
4106                   break;
4107                 }
4108               }
4109             }
4110           (void) NormalizeImageChannel(msl_info->image[n],channel);
4111           break;
4112         }
4113       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4114     }
4115     case 'O':
4116     case 'o':
4117     {
4118       if (LocaleCompare((const char *) tag,"oil-paint") == 0)
4119         {
4120           Image
4121             *paint_image;
4122
4123           /*
4124             Oil-paint image.
4125           */
4126           if (msl_info->image[n] == (Image *) NULL)
4127             {
4128               ThrowMSLException(OptionError,"NoImagesDefined",
4129                 (const char *) tag);
4130               break;
4131             }
4132           if (attributes != (const xmlChar **) NULL)
4133             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4134             {
4135               keyword=(const char *) attributes[i++];
4136               attribute=InterpretImageProperties(msl_info->image_info[n],
4137                 msl_info->attributes[n],(const char *) attributes[i]);
4138               CloneString(&value,attribute);
4139               switch (*keyword)
4140               {
4141                 case 'G':
4142                 case 'g':
4143                 {
4144                   if (LocaleCompare(keyword,"geometry") == 0)
4145                     {
4146                       flags=ParseGeometry(value,&geometry_info);
4147                       if ((flags & SigmaValue) == 0)
4148                         geometry_info.sigma=1.0;
4149                       break;
4150                     }
4151                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4152                     keyword);
4153                   break;
4154                 }
4155                 case 'R':
4156                 case 'r':
4157                 {
4158                   if (LocaleCompare(keyword,"radius") == 0)
4159                     {
4160                       geometry_info.rho=InterpretLocaleValue(value,
4161                         (char **) NULL);
4162                       break;
4163                     }
4164                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4165                     keyword);
4166                   break;
4167                 }
4168                 default:
4169                 {
4170                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4171                     keyword);
4172                   break;
4173                 }
4174               }
4175             }
4176           paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4177             &msl_info->image[n]->exception);
4178           if (paint_image == (Image *) NULL)
4179             break;
4180           msl_info->image[n]=DestroyImage(msl_info->image[n]);
4181           msl_info->image[n]=paint_image;
4182           break;
4183         }
4184       if (LocaleCompare((const char *) tag,"opaque") == 0)
4185         {
4186           PixelInfo
4187             fill_color,
4188             target;
4189
4190           /*
4191             Opaque image.
4192           */
4193           if (msl_info->image[n] == (Image *) NULL)
4194             {
4195               ThrowMSLException(OptionError,"NoImagesDefined",
4196                 (const char *) tag);
4197               break;
4198             }
4199           (void) QueryMagickColor("none",&target,&exception);
4200           (void) QueryMagickColor("none",&fill_color,&exception);
4201           if (attributes != (const xmlChar **) NULL)
4202             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4203             {
4204               keyword=(const char *) attributes[i++];
4205               attribute=InterpretImageProperties(msl_info->image_info[n],
4206                 msl_info->attributes[n],(const char *) attributes[i]);
4207               CloneString(&value,attribute);
4208               switch (*keyword)
4209               {
4210                 case 'C':
4211                 case 'c':
4212                 {
4213                   if (LocaleCompare(keyword,"channel") == 0)
4214                     {
4215                       option=ParseChannelOption(value);
4216                       if (option < 0)
4217                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4218                           value);
4219                       channel=(ChannelType) option;
4220                       break;
4221                     }
4222                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4223                     keyword);
4224                   break;
4225                 }
4226                 case 'F':
4227                 case 'f':
4228                 {
4229                   if (LocaleCompare(keyword,"fill") == 0)
4230                     {
4231                       (void) QueryMagickColor(value,&fill_color,&exception);
4232                       break;
4233                     }
4234                   if (LocaleCompare(keyword,"fuzz") == 0)
4235                     {
4236                       msl_info->image[n]->fuzz=InterpretLocaleValue(value,
4237                         (char **) NULL);
4238                       break;
4239                     }
4240                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4241                     keyword);
4242                   break;
4243                 }
4244                 default:
4245                 {
4246                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4247                     keyword);
4248                   break;
4249                 }
4250               }
4251             }
4252           (void) OpaquePaintImageChannel(msl_info->image[n],channel,
4253             &target,&fill_color,MagickFalse);
4254           break;
4255         }
4256       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4257     }
4258     case 'P':
4259     case 'p':
4260     {
4261       if (LocaleCompare((const char *) tag,"print") == 0)
4262         {
4263           if (attributes == (const xmlChar **) NULL)
4264             break;
4265           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4266           {
4267             keyword=(const char *) attributes[i++];
4268             attribute=InterpretImageProperties(msl_info->image_info[n],
4269               msl_info->attributes[n],(const char *) attributes[i]);
4270             CloneString(&value,attribute);
4271             switch (*keyword)
4272             {
4273               case 'O':
4274               case 'o':
4275               {
4276                 if (LocaleCompare(keyword,"output") == 0)
4277                   {
4278                     (void) FormatLocaleFile(stdout,"%s",value);
4279                     break;
4280                   }
4281                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4282                 break;
4283               }
4284               default:
4285               {
4286                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4287                 break;
4288               }
4289             }
4290           }
4291           break;
4292         }
4293         if (LocaleCompare((const char *) tag, "profile") == 0)
4294           {
4295             if (msl_info->image[n] == (Image *) NULL)
4296               {
4297                 ThrowMSLException(OptionError,"NoImagesDefined",
4298                   (const char *) tag);
4299                 break;
4300               }
4301             if (attributes == (const xmlChar **) NULL)
4302               break;
4303             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4304             {
4305               const char
4306                 *name;
4307
4308               const StringInfo
4309                 *profile;
4310
4311               Image
4312                 *profile_image;
4313
4314               ImageInfo
4315                 *profile_info;
4316
4317               keyword=(const char *) attributes[i++];
4318               attribute=InterpretImageProperties(msl_info->image_info[n],
4319                 msl_info->attributes[n],(const char *) attributes[i]);
4320               CloneString(&value,attribute);
4321               if (*keyword == '+')
4322                 {
4323                   /*
4324                     Remove a profile from the image.
4325                   */
4326                   (void) ProfileImage(msl_info->image[n],keyword,
4327                     (const unsigned char *) NULL,0,MagickTrue);
4328                   continue;
4329                 }
4330               /*
4331                 Associate a profile with the image.
4332               */
4333               profile_info=CloneImageInfo(msl_info->image_info[n]);
4334               profile=GetImageProfile(msl_info->image[n],"iptc");
4335               if (profile != (StringInfo *) NULL)
4336                 profile_info->profile=(void *) CloneStringInfo(profile);
4337               profile_image=GetImageCache(profile_info,keyword,&exception);
4338               profile_info=DestroyImageInfo(profile_info);
4339               if (profile_image == (Image *) NULL)
4340                 {
4341                   char
4342                     name[MaxTextExtent],
4343                     filename[MaxTextExtent];
4344
4345                   register char
4346                     *p;
4347
4348                   StringInfo
4349                     *profile;
4350
4351                   (void) CopyMagickString(filename,keyword,MaxTextExtent);
4352                   (void) CopyMagickString(name,keyword,MaxTextExtent);
4353                   for (p=filename; *p != '\0'; p++)
4354                     if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4355                         (IsPathAccessible(keyword) == MagickFalse))
4356                       {
4357                         register char
4358                           *q;
4359
4360                         /*
4361                           Look for profile name (e.g. name:profile).
4362                         */
4363                         (void) CopyMagickString(name,filename,(size_t)
4364                           (p-filename+1));
4365                         for (q=filename; *q != '\0'; q++)
4366                           *q=(*++p);
4367                         break;
4368                       }
4369                   profile=FileToStringInfo(filename,~0UL,&exception);
4370                   if (profile != (StringInfo *) NULL)
4371                     {
4372                       (void) ProfileImage(msl_info->image[n],name,
4373                         GetStringInfoDatum(profile),(size_t)
4374                         GetStringInfoLength(profile),MagickFalse);
4375                       profile=DestroyStringInfo(profile);
4376                     }
4377                   continue;
4378                 }
4379               ResetImageProfileIterator(profile_image);
4380               name=GetNextImageProfile(profile_image);
4381               while (name != (const char *) NULL)
4382               {
4383                 profile=GetImageProfile(profile_image,name);
4384                 if (profile != (StringInfo *) NULL)
4385                   (void) ProfileImage(msl_info->image[n],name,
4386                     GetStringInfoDatum(profile),(size_t)
4387                     GetStringInfoLength(profile),MagickFalse);
4388                 name=GetNextImageProfile(profile_image);
4389               }
4390               profile_image=DestroyImage(profile_image);
4391             }
4392             break;
4393           }
4394       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4395     }
4396     case 'Q':
4397     case 'q':
4398     {
4399       if (LocaleCompare((const char *) tag,"quantize") == 0)
4400         {
4401           QuantizeInfo
4402             quantize_info;
4403
4404           /*
4405             Quantize image.
4406           */
4407           if (msl_info->image[n] == (Image *) NULL)
4408             {
4409               ThrowMSLException(OptionError,"NoImagesDefined",
4410                 (const char *) tag);
4411               break;
4412             }
4413           GetQuantizeInfo(&quantize_info);
4414           if (attributes != (const xmlChar **) NULL)
4415             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4416             {
4417               keyword=(const char *) attributes[i++];
4418               attribute=InterpretImageProperties(msl_info->image_info[n],
4419                 msl_info->attributes[n],(const char *) attributes[i]);
4420               CloneString(&value,attribute);
4421               switch (*keyword)
4422               {
4423                 case 'C':
4424                 case 'c':
4425                 {
4426                   if (LocaleCompare(keyword,"colors") == 0)
4427                     {
4428                       quantize_info.number_colors=StringToLong(value);
4429                       break;
4430                     }
4431                   if (LocaleCompare(keyword,"colorspace") == 0)
4432                     {
4433                       option=ParseCommandOption(MagickColorspaceOptions,
4434                         MagickFalse,value);
4435                       if (option < 0)
4436                         ThrowMSLException(OptionError,
4437                           "UnrecognizedColorspaceType",value);
4438                       quantize_info.colorspace=(ColorspaceType) option;
4439                       break;
4440                     }
4441                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4442                     keyword);
4443                   break;
4444                 }
4445                 case 'D':
4446                 case 'd':
4447                 {
4448                   if (LocaleCompare(keyword,"dither") == 0)
4449                     {
4450                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4451                         value);
4452                       if (option < 0)
4453                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4454                           value);
4455                       quantize_info.dither=(MagickBooleanType) option;
4456                       break;
4457                     }
4458                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4459                     keyword);
4460                   break;
4461                 }
4462                 case 'M':
4463                 case 'm':
4464                 {
4465                   if (LocaleCompare(keyword,"measure") == 0)
4466                     {
4467                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4468                         value);
4469                       if (option < 0)
4470                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4471                           value);
4472                       quantize_info.measure_error=(MagickBooleanType) option;
4473                       break;
4474                     }
4475                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4476                     keyword);
4477                   break;
4478                 }
4479                 case 'T':
4480                 case 't':
4481                 {
4482                   if (LocaleCompare(keyword,"treedepth") == 0)
4483                     {
4484                       quantize_info.tree_depth=StringToLong(value);
4485                       break;
4486                     }
4487                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4488                     keyword);
4489                   break;
4490                 }
4491                 default:
4492                 {
4493                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4494                     keyword);
4495                   break;
4496                 }
4497               }
4498             }
4499           (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4500           break;
4501         }
4502       if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
4503         {
4504           char
4505             text[MaxTextExtent];
4506
4507           MagickBooleanType
4508             status;
4509
4510           TypeMetric
4511             metrics;
4512
4513           /*
4514             Query font metrics.
4515           */
4516           draw_info=CloneDrawInfo(msl_info->image_info[n],
4517             msl_info->draw_info[n]);
4518           angle=0.0;
4519           current=draw_info->affine;
4520           GetAffineMatrix(&affine);
4521           if (attributes != (const xmlChar **) NULL)
4522             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4523             {
4524               keyword=(const char *) attributes[i++];
4525               attribute=InterpretImageProperties(msl_info->image_info[n],
4526                 msl_info->attributes[n],(const char *) attributes[i]);
4527               CloneString(&value,attribute);
4528               switch (*keyword)
4529               {
4530                 case 'A':
4531                 case 'a':
4532                 {
4533                   if (LocaleCompare(keyword,"affine") == 0)
4534                     {
4535                       char
4536                         *p;
4537
4538                       p=value;
4539                       draw_info->affine.sx=InterpretLocaleValue(p,&p);
4540                       if (*p ==',')
4541                         p++;
4542                       draw_info->affine.rx=InterpretLocaleValue(p,&p);
4543                       if (*p ==',')
4544                         p++;
4545                       draw_info->affine.ry=InterpretLocaleValue(p,&p);
4546                       if (*p ==',')
4547                         p++;
4548                       draw_info->affine.sy=InterpretLocaleValue(p,&p);
4549                       if (*p ==',')
4550                         p++;
4551                       draw_info->affine.tx=InterpretLocaleValue(p,&p);
4552                       if (*p ==',')
4553                         p++;
4554                       draw_info->affine.ty=InterpretLocaleValue(p,&p);
4555                       break;
4556                     }
4557                   if (LocaleCompare(keyword,"align") == 0)
4558                     {
4559                       option=ParseCommandOption(MagickAlignOptions,MagickFalse,
4560                         value);
4561                       if (option < 0)
4562                         ThrowMSLException(OptionError,"UnrecognizedAlignType",
4563                           value);
4564                       draw_info->align=(AlignType) option;
4565                       break;
4566                     }
4567                   if (LocaleCompare(keyword,"antialias") == 0)
4568                     {
4569                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4570                         value);
4571                       if (option < 0)
4572                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4573                           value);
4574                       draw_info->stroke_antialias=(MagickBooleanType) option;
4575                       draw_info->text_antialias=(MagickBooleanType) option;
4576                       break;
4577                     }
4578                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4579                     keyword);
4580                   break;
4581                 }
4582                 case 'D':
4583                 case 'd':
4584                 {
4585                   if (LocaleCompare(keyword,"density") == 0)
4586                     {
4587                       CloneString(&draw_info->density,value);
4588                       break;
4589                     }
4590                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4591                     keyword);
4592                   break;
4593                 }
4594                 case 'E':
4595                 case 'e':
4596                 {
4597                   if (LocaleCompare(keyword,"encoding") == 0)
4598                     {
4599                       CloneString(&draw_info->encoding,value);
4600                       break;
4601                     }
4602                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4603                     keyword);
4604                   break;
4605                 }
4606                 case 'F':
4607                 case 'f':
4608                 {
4609                   if (LocaleCompare(keyword, "fill") == 0)
4610                     {
4611                       (void) QueryColorDatabase(value,&draw_info->fill,
4612                         &exception);
4613                       break;
4614                     }
4615                   if (LocaleCompare(keyword,"family") == 0)
4616                     {
4617                       CloneString(&draw_info->family,value);
4618                       break;
4619                     }
4620                   if (LocaleCompare(keyword,"font") == 0)
4621                     {
4622                       CloneString(&draw_info->font,value);
4623                       break;
4624                     }
4625                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4626                     keyword);
4627                   break;
4628                 }
4629                 case 'G':
4630                 case 'g':
4631                 {
4632                   if (LocaleCompare(keyword,"geometry") == 0)
4633                     {
4634                       flags=ParsePageGeometry(msl_info->image[n],value,
4635                         &geometry,&exception);
4636                       if ((flags & HeightValue) == 0)
4637                         geometry.height=geometry.width;
4638                       break;
4639                     }
4640                   if (LocaleCompare(keyword,"gravity") == 0)
4641                     {
4642                       option=ParseCommandOption(MagickGravityOptions,MagickFalse,
4643                         value);
4644                       if (option < 0)
4645                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
4646                           value);
4647                       draw_info->gravity=(GravityType) option;
4648                       break;
4649                     }
4650                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4651                     keyword);
4652                   break;
4653                 }
4654                 case 'P':
4655                 case 'p':
4656                 {
4657                   if (LocaleCompare(keyword,"pointsize") == 0)
4658                     {
4659                       draw_info->pointsize=InterpretLocaleValue(value,
4660                         (char **) NULL);
4661                       break;
4662                     }
4663                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4664                     keyword);
4665                   break;
4666                 }
4667                 case 'R':
4668                 case 'r':
4669                 {
4670                   if (LocaleCompare(keyword,"rotate") == 0)
4671                     {
4672                       angle=InterpretLocaleValue(value,(char **) NULL);
4673                       affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4674                       affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4675                       affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4676                       affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4677                       break;
4678                     }
4679                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4680                     keyword);
4681                   break;
4682                 }
4683                 case 'S':
4684                 case 's':
4685                 {
4686                   if (LocaleCompare(keyword,"scale") == 0)
4687                     {
4688                       flags=ParseGeometry(value,&geometry_info);
4689                       if ((flags & SigmaValue) == 0)
4690                         geometry_info.sigma=1.0;
4691                       affine.sx=geometry_info.rho;
4692                       affine.sy=geometry_info.sigma;
4693                       break;
4694                     }
4695                   if (LocaleCompare(keyword,"skewX") == 0)
4696                     {
4697                       angle=InterpretLocaleValue(value,(char **) NULL);
4698                       affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4699                       break;
4700                     }
4701                   if (LocaleCompare(keyword,"skewY") == 0)
4702                     {
4703                       angle=InterpretLocaleValue(value,(char **) NULL);
4704                       affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4705                       break;
4706                     }
4707                   if (LocaleCompare(keyword,"stretch") == 0)
4708                     {
4709                       option=ParseCommandOption(MagickStretchOptions,MagickFalse,
4710                         value);
4711                       if (option < 0)
4712                         ThrowMSLException(OptionError,"UnrecognizedStretchType",
4713                           value);
4714                       draw_info->stretch=(StretchType) option;
4715                       break;
4716                     }
4717                   if (LocaleCompare(keyword, "stroke") == 0)
4718                     {
4719                       (void) QueryColorDatabase(value,&draw_info->stroke,
4720                         &exception);
4721                       break;
4722                     }
4723                   if (LocaleCompare(keyword,"strokewidth") == 0)
4724                     {
4725                       draw_info->stroke_width=StringToLong(value);
4726                       break;
4727                     }
4728                   if (LocaleCompare(keyword,"style") == 0)
4729                     {
4730                       option=ParseCommandOption(MagickStyleOptions,MagickFalse,
4731                         value);
4732                       if (option < 0)
4733                         ThrowMSLException(OptionError,"UnrecognizedStyleType",
4734                           value);
4735                       draw_info->style=(StyleType) option;
4736                       break;
4737                     }
4738                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4739                     keyword);
4740                   break;
4741                 }
4742                 case 'T':
4743                 case 't':
4744                 {
4745                   if (LocaleCompare(keyword,"text") == 0)
4746                     {
4747                       CloneString(&draw_info->text,value);
4748                       break;
4749                     }
4750                   if (LocaleCompare(keyword,"translate") == 0)
4751                     {
4752                       flags=ParseGeometry(value,&geometry_info);
4753                       if ((flags & SigmaValue) == 0)
4754                         geometry_info.sigma=1.0;
4755                       affine.tx=geometry_info.rho;
4756                       affine.ty=geometry_info.sigma;
4757                       break;
4758                     }
4759                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4760                     keyword);
4761                   break;
4762                 }
4763                 case 'U':
4764                 case 'u':
4765                 {
4766                   if (LocaleCompare(keyword, "undercolor") == 0)
4767                     {
4768                       (void) QueryColorDatabase(value,&draw_info->undercolor,
4769                         &exception);
4770                       break;
4771                     }
4772                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4773                     keyword);
4774                   break;
4775                 }
4776                 case 'W':
4777                 case 'w':
4778                 {
4779                   if (LocaleCompare(keyword,"weight") == 0)
4780                     {
4781                       draw_info->weight=StringToLong(value);
4782                       break;
4783                     }
4784                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4785                     keyword);
4786                   break;
4787                 }
4788                 case 'X':
4789                 case 'x':
4790                 {
4791                   if (LocaleCompare(keyword,"x") == 0)
4792                     {
4793                       geometry.x=StringToLong(value);
4794                       break;
4795                     }
4796                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4797                     keyword);
4798                   break;
4799                 }
4800                 case 'Y':
4801                 case 'y':
4802                 {
4803                   if (LocaleCompare(keyword,"y") == 0)
4804                     {
4805                       geometry.y=StringToLong(value);
4806                       break;
4807                     }
4808                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4809                     keyword);
4810                   break;
4811                 }
4812                 default:
4813                 {
4814                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4815                     keyword);
4816                   break;
4817                 }
4818               }
4819             }
4820           (void) FormatLocaleString(text,MaxTextExtent,
4821             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4822             geometry.height,(double) geometry.x,(double) geometry.y);
4823           CloneString(&draw_info->geometry,text);
4824           draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4825           draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4826           draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4827           draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4828           draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4829             affine.tx;
4830           draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4831             affine.ty;
4832           status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4833           if (status != MagickFalse)
4834             {
4835               Image
4836                 *image;
4837
4838               image=msl_info->attributes[n];
4839               FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
4840                 "%g",metrics.pixels_per_em.x);
4841               FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
4842                 "%g",metrics.pixels_per_em.y);
4843               FormatImageProperty(image,"msl:font-metrics.ascent","%g",
4844                 metrics.ascent);
4845               FormatImageProperty(image,"msl:font-metrics.descent","%g",
4846                 metrics.descent);
4847               FormatImageProperty(image,"msl:font-metrics.width","%g",
4848                 metrics.width);
4849               FormatImageProperty(image,"msl:font-metrics.height","%g",
4850                 metrics.height);
4851               FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
4852                 metrics.max_advance);
4853               FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
4854                 metrics.bounds.x1);
4855               FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
4856                 metrics.bounds.y1);
4857               FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
4858                 metrics.bounds.x2);
4859               FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
4860                 metrics.bounds.y2);
4861               FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
4862                 metrics.origin.x);
4863               FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
4864                 metrics.origin.y);
4865             }
4866           draw_info=DestroyDrawInfo(draw_info);
4867           break;
4868         }
4869       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4870     }
4871     case 'R':
4872     case 'r':
4873     {
4874       if (LocaleCompare((const char *) tag,"raise") == 0)
4875         {
4876           MagickBooleanType
4877             raise;
4878
4879           /*
4880             Raise image.
4881           */
4882           if (msl_info->image[n] == (Image *) NULL)
4883             {
4884               ThrowMSLException(OptionError,"NoImagesDefined",
4885                 (const char *) tag);
4886               break;
4887             }
4888           raise=MagickFalse;
4889           SetGeometry(msl_info->image[n],&geometry);
4890           if (attributes != (const xmlChar **) NULL)
4891             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4892             {
4893               keyword=(const char *) attributes[i++];
4894               attribute=InterpretImageProperties(msl_info->image_info[n],
4895                 msl_info->attributes[n],(const char *) attributes[i]);
4896               CloneString(&value,attribute);
4897               switch (*keyword)
4898               {
4899                 case 'G':
4900                 case 'g':
4901                 {
4902                   if (LocaleCompare(keyword,"geometry") == 0)
4903                     {
4904                       flags=ParsePageGeometry(msl_info->image[n],value,
4905                         &geometry,&exception);
4906                       if ((flags & HeightValue) == 0)
4907                         geometry.height=geometry.width;
4908                       break;
4909                     }
4910                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4911                     keyword);
4912                   break;
4913                 }
4914                 case 'H':
4915                 case 'h':
4916                 {
4917                   if (LocaleCompare(keyword,"height") == 0)
4918                     {
4919                       geometry.height=StringToLong(value);
4920                       break;
4921                     }
4922                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4923                     keyword);
4924                   break;
4925                 }
4926                 case 'R':
4927                 case 'r':
4928                 {
4929                   if (LocaleCompare(keyword,"raise") == 0)
4930                     {
4931                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4932                         value);
4933                       if (option < 0)
4934                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4935                           value);
4936                       raise=(MagickBooleanType) option;
4937                       break;
4938                     }
4939                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4940                     keyword);
4941                   break;
4942                 }
4943                 case 'W':
4944                 case 'w':
4945                 {
4946                   if (LocaleCompare(keyword,"width") == 0)
4947                     {
4948                       geometry.width=StringToLong(value);
4949                       break;
4950                     }
4951                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4952                     keyword);
4953                   break;
4954                 }
4955                 default:
4956                 {
4957                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4958                     keyword);
4959                   break;
4960                 }
4961               }
4962             }
4963           (void) RaiseImage(msl_info->image[n],&geometry,raise);
4964           break;
4965         }
4966       if (LocaleCompare((const char *) tag,"read") == 0)
4967         {
4968           if (attributes == (const xmlChar **) NULL)
4969             break;
4970           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4971           {
4972             keyword=(const char *) attributes[i++];
4973             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
4974               msl_info->attributes[n],(const char *) attributes[i]));
4975             switch (*keyword)
4976             {
4977               case 'F':
4978               case 'f':
4979               {
4980                 if (LocaleCompare(keyword,"filename") == 0)
4981                   {
4982                     Image
4983                       *image;
4984
4985                     (void) CopyMagickString(msl_info->image_info[n]->filename,
4986                       value,MaxTextExtent);
4987                     image=ReadImage(msl_info->image_info[n],&exception);
4988                     CatchException(&exception);
4989                     if (image == (Image *) NULL)
4990                       continue;
4991                     AppendImageToList(&msl_info->image[n],image);
4992                     break;
4993                   }
4994                 (void) SetMSLAttributes(msl_info,keyword,value);
4995                 break;
4996               }
4997               default:
4998               {
4999                 (void) SetMSLAttributes(msl_info,keyword,value);
5000                 break;
5001               }
5002             }
5003           }
5004           break;
5005         }
5006       if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
5007         {
5008           Image
5009             *paint_image;
5010
5011           /*
5012             Reduce-noise image.
5013           */
5014           if (msl_info->image[n] == (Image *) NULL)
5015             {
5016               ThrowMSLException(OptionError,"NoImagesDefined",
5017                 (const char *) tag);
5018               break;
5019             }
5020           if (attributes != (const xmlChar **) NULL)
5021             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5022             {
5023               keyword=(const char *) attributes[i++];
5024               attribute=InterpretImageProperties(msl_info->image_info[n],
5025                 msl_info->attributes[n],(const char *) attributes[i]);
5026               CloneString(&value,attribute);
5027               switch (*keyword)
5028               {
5029                 case 'G':
5030                 case 'g':
5031                 {
5032                   if (LocaleCompare(keyword,"geometry") == 0)
5033                     {
5034                       flags=ParseGeometry(value,&geometry_info);
5035                       if ((flags & SigmaValue) == 0)
5036                         geometry_info.sigma=1.0;
5037                       break;
5038                     }
5039                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5040                     keyword);
5041                   break;
5042                 }
5043                 case 'R':
5044                 case 'r':
5045                 {
5046                   if (LocaleCompare(keyword,"radius") == 0)
5047                     {
5048                       geometry_info.rho=InterpretLocaleValue(value,
5049                         (char **) NULL);
5050                       break;
5051                     }
5052                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5053                     keyword);
5054                   break;
5055                 }
5056                 default:
5057                 {
5058                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5059                     keyword);
5060                   break;
5061                 }
5062               }
5063             }
5064           paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
5065             (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5066             &msl_info->image[n]->exception);
5067           if (paint_image == (Image *) NULL)
5068             break;
5069           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5070           msl_info->image[n]=paint_image;
5071           break;
5072         }
5073       else if (LocaleCompare((const char *) tag,"repage") == 0)
5074       {
5075         /* init the values */
5076         width=msl_info->image[n]->page.width;
5077         height=msl_info->image[n]->page.height;
5078         x=msl_info->image[n]->page.x;
5079         y=msl_info->image[n]->page.y;
5080
5081         if (msl_info->image[n] == (Image *) NULL)
5082         {
5083           ThrowMSLException(OptionError,"NoImagesDefined",
5084             (const char *) tag);
5085           break;
5086         }
5087         if (attributes == (const xmlChar **) NULL)
5088         break;
5089         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5090         {
5091         keyword=(const char *) attributes[i++];
5092         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5093           msl_info->attributes[n],(const char *) attributes[i]));
5094         switch (*keyword)
5095         {
5096           case 'G':
5097           case 'g':
5098           {
5099           if (LocaleCompare(keyword,"geometry") == 0)
5100             {
5101               int
5102                 flags;
5103
5104               RectangleInfo
5105                 geometry;
5106
5107             flags=ParseAbsoluteGeometry(value,&geometry);
5108             if ((flags & WidthValue) != 0)
5109               {
5110                 if ((flags & HeightValue) == 0)
5111                   geometry.height=geometry.width;
5112                 width=geometry.width;
5113                 height=geometry.height;
5114               }
5115             if ((flags & AspectValue) != 0)
5116               {
5117                 if ((flags & XValue) != 0)
5118                   x+=geometry.x;
5119                 if ((flags & YValue) != 0)
5120                   y+=geometry.y;
5121               }
5122             else
5123               {
5124                 if ((flags & XValue) != 0)
5125                   {
5126                     x=geometry.x;
5127                     if ((width == 0) && (geometry.x > 0))
5128                       width=msl_info->image[n]->columns+geometry.x;
5129                   }
5130                 if ((flags & YValue) != 0)
5131                   {
5132                     y=geometry.y;
5133                     if ((height == 0) && (geometry.y > 0))
5134                       height=msl_info->image[n]->rows+geometry.y;
5135                   }
5136               }
5137             break;
5138             }
5139           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5140           break;
5141           }
5142           case 'H':
5143           case 'h':
5144           {
5145           if (LocaleCompare(keyword,"height") == 0)
5146             {
5147             height = StringToLong( value );
5148             break;
5149             }
5150           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5151           break;
5152           }
5153           case 'W':
5154           case 'w':
5155           {
5156           if (LocaleCompare(keyword,"width") == 0)
5157             {
5158             width = StringToLong( value );
5159             break;
5160             }
5161           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5162           break;
5163           }
5164           case 'X':
5165           case 'x':
5166           {
5167           if (LocaleCompare(keyword,"x") == 0)
5168             {
5169             x = StringToLong( value );
5170             break;
5171             }
5172           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5173           break;
5174           }
5175           case 'Y':
5176           case 'y':
5177           {
5178           if (LocaleCompare(keyword,"y") == 0)
5179             {
5180             y = StringToLong( value );
5181             break;
5182             }
5183           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5184           break;
5185           }
5186           default:
5187           {
5188           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5189           break;
5190           }
5191         }
5192         }
5193
5194          msl_info->image[n]->page.width=width;
5195          msl_info->image[n]->page.height=height;
5196          msl_info->image[n]->page.x=x;
5197          msl_info->image[n]->page.y=y;
5198         break;
5199       }
5200     else if (LocaleCompare((const char *) tag,"resample") == 0)
5201     {
5202       double
5203         x_resolution,
5204         y_resolution;
5205
5206       if (msl_info->image[n] == (Image *) NULL)
5207         {
5208           ThrowMSLException(OptionError,"NoImagesDefined",
5209             (const char *) tag);
5210           break;
5211         }
5212       if (attributes == (const xmlChar **) NULL)
5213         break;
5214       x_resolution=DefaultResolution;
5215       y_resolution=DefaultResolution;
5216       for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5217       {
5218         keyword=(const char *) attributes[i++];
5219         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5220           msl_info->attributes[n],(const char *) attributes[i]));
5221         switch (*keyword)
5222         {
5223           case 'b':
5224           {
5225             if (LocaleCompare(keyword,"blur") == 0)
5226               {
5227                 msl_info->image[n]->blur=InterpretLocaleValue(value,
5228                         (char **) NULL);
5229                 break;
5230               }
5231             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5232             break;
5233           }
5234           case 'G':
5235           case 'g':
5236           {
5237             if (LocaleCompare(keyword,"geometry") == 0)
5238               {
5239                 ssize_t
5240                   flags;
5241
5242                 flags=ParseGeometry(value,&geometry_info);
5243                 if ((flags & SigmaValue) == 0)
5244                   geometry_info.sigma*=geometry_info.rho;
5245                 x_resolution=geometry_info.rho;
5246                 y_resolution=geometry_info.sigma;
5247                 break;
5248               }
5249             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5250             break;
5251           }
5252           case 'X':
5253           case 'x':
5254           {
5255             if (LocaleCompare(keyword,"x-resolution") == 0)
5256               {
5257                 x_resolution=InterpretLocaleValue(value,(char **) NULL);
5258                 break;
5259               }
5260             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5261             break;
5262           }
5263           case 'Y':
5264           case 'y':
5265           {
5266             if (LocaleCompare(keyword,"y-resolution") == 0)
5267               {
5268                 y_resolution=InterpretLocaleValue(value,(char **) NULL);
5269                 break;
5270               }
5271             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5272             break;
5273           }
5274           default:
5275           {
5276             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5277             break;
5278           }
5279         }
5280       }
5281       /*
5282         Resample image.
5283       */
5284       {
5285         double
5286           factor;
5287
5288         Image
5289           *resample_image;
5290
5291         factor=1.0;
5292         if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5293           factor=2.54;
5294         width=(size_t) (x_resolution*msl_info->image[n]->columns/
5295           (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5296           msl_info->image[n]->x_resolution))+0.5);
5297         height=(size_t) (y_resolution*msl_info->image[n]->rows/
5298           (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5299           msl_info->image[n]->y_resolution))+0.5);
5300         resample_image=ResizeImage(msl_info->image[n],width,height,
5301           msl_info->image[n]->filter,msl_info->image[n]->blur,
5302           &msl_info->image[n]->exception);
5303         if (resample_image == (Image *) NULL)
5304           break;
5305         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5306         msl_info->image[n]=resample_image;
5307       }
5308       break;
5309     }
5310       if (LocaleCompare((const char *) tag,"resize") == 0)
5311         {
5312           double
5313             blur;
5314
5315           FilterTypes
5316             filter;
5317
5318           Image
5319             *resize_image;
5320
5321           /*
5322             Resize image.
5323           */
5324           if (msl_info->image[n] == (Image *) NULL)
5325             {
5326               ThrowMSLException(OptionError,"NoImagesDefined",
5327                 (const char *) tag);
5328               break;
5329             }
5330           filter=UndefinedFilter;
5331           blur=1.0;
5332           if (attributes != (const xmlChar **) NULL)
5333             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5334             {
5335               keyword=(const char *) attributes[i++];
5336               attribute=InterpretImageProperties(msl_info->image_info[n],
5337                 msl_info->attributes[n],(const char *) attributes[i]);
5338               CloneString(&value,attribute);
5339               switch (*keyword)
5340               {
5341                 case 'F':
5342                 case 'f':
5343                 {
5344                   if (LocaleCompare(keyword,"filter") == 0)
5345                     {
5346                       option=ParseCommandOption(MagickFilterOptions,MagickFalse,
5347                         value);
5348                       if (option < 0)
5349                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5350                           value);
5351                       filter=(FilterTypes) option;
5352                       break;
5353                     }
5354                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5355                     keyword);
5356                   break;
5357                 }
5358                 case 'G':
5359                 case 'g':
5360                 {
5361                   if (LocaleCompare(keyword,"geometry") == 0)
5362                     {
5363                       flags=ParseRegionGeometry(msl_info->image[n],value,
5364                         &geometry,&exception);
5365                       break;
5366                     }
5367                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5368                     keyword);
5369                   break;
5370                 }
5371                 case 'H':
5372                 case 'h':
5373                 {
5374                   if (LocaleCompare(keyword,"height") == 0)
5375                     {
5376                       geometry.height=StringToUnsignedLong(value);
5377                       break;
5378                     }
5379                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5380                     keyword);
5381                   break;
5382                 }
5383                 case 'S':
5384                 case 's':
5385                 {
5386                   if (LocaleCompare(keyword,"support") == 0)
5387                     {
5388                       blur=InterpretLocaleValue(value,(char **) NULL);
5389                       break;
5390                     }
5391                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5392                     keyword);
5393                   break;
5394                 }
5395                 case 'W':
5396                 case 'w':
5397                 {
5398                   if (LocaleCompare(keyword,"width") == 0)
5399                     {
5400                       geometry.width=StringToLong(value);
5401                       break;
5402                     }
5403                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5404                     keyword);
5405                   break;
5406                 }
5407                 default:
5408                 {
5409                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5410                     keyword);
5411                   break;
5412                 }
5413               }
5414             }
5415           resize_image=ResizeImage(msl_info->image[n],geometry.width,
5416             geometry.height,filter,blur,&msl_info->image[n]->exception);
5417           if (resize_image == (Image *) NULL)
5418             break;
5419           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5420           msl_info->image[n]=resize_image;
5421           break;
5422         }
5423       if (LocaleCompare((const char *) tag,"roll") == 0)
5424         {
5425           Image
5426             *roll_image;
5427
5428           /*
5429             Roll image.
5430           */
5431           if (msl_info->image[n] == (Image *) NULL)
5432             {
5433               ThrowMSLException(OptionError,"NoImagesDefined",
5434                 (const char *) tag);
5435               break;
5436             }
5437           SetGeometry(msl_info->image[n],&geometry);
5438           if (attributes != (const xmlChar **) NULL)
5439             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5440             {
5441               keyword=(const char *) attributes[i++];
5442               attribute=InterpretImageProperties(msl_info->image_info[n],
5443                 msl_info->attributes[n],(const char *) attributes[i]);
5444               CloneString(&value,attribute);
5445               switch (*keyword)
5446               {
5447                 case 'G':
5448                 case 'g':
5449                 {
5450                   if (LocaleCompare(keyword,"geometry") == 0)
5451                     {
5452                       flags=ParsePageGeometry(msl_info->image[n],value,
5453                         &geometry,&exception);
5454                       if ((flags & HeightValue) == 0)
5455                         geometry.height=geometry.width;
5456                       break;
5457                     }
5458                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5459                     keyword);
5460                   break;
5461                 }
5462                 case 'X':
5463                 case 'x':
5464                 {
5465                   if (LocaleCompare(keyword,"x") == 0)
5466                     {
5467                       geometry.x=StringToLong(value);
5468                       break;
5469                     }
5470                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5471                     keyword);
5472                   break;
5473                 }
5474                 case 'Y':
5475                 case 'y':
5476                 {
5477                   if (LocaleCompare(keyword,"y") == 0)
5478                     {
5479                       geometry.y=StringToLong(value);
5480                       break;
5481                     }
5482                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5483                     keyword);
5484                   break;
5485                 }
5486                 default:
5487                 {
5488                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5489                     keyword);
5490                   break;
5491                 }
5492               }
5493             }
5494           roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5495             &msl_info->image[n]->exception);
5496           if (roll_image == (Image *) NULL)
5497             break;
5498           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5499           msl_info->image[n]=roll_image;
5500           break;
5501         }
5502       else if (LocaleCompare((const char *) tag,"roll") == 0)
5503       {
5504         /* init the values */
5505         width=msl_info->image[n]->columns;
5506         height=msl_info->image[n]->rows;
5507         x = y = 0;
5508
5509         if (msl_info->image[n] == (Image *) NULL)
5510         {
5511           ThrowMSLException(OptionError,"NoImagesDefined",
5512             (const char *) tag);
5513           break;
5514         }
5515         if (attributes == (const xmlChar **) NULL)
5516         break;
5517         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5518         {
5519         keyword=(const char *) attributes[i++];
5520         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5521           msl_info->attributes[n],(const char *) attributes[i]));
5522         switch (*keyword)
5523         {
5524           case 'G':
5525           case 'g':
5526           {
5527           if (LocaleCompare(keyword,"geometry") == 0)
5528             {
5529             (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5530             break;
5531             }
5532           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5533           break;
5534           }
5535           case 'X':
5536           case 'x':
5537           {
5538           if (LocaleCompare(keyword,"x") == 0)
5539             {
5540             x = StringToLong( value );
5541             break;
5542             }
5543           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5544           break;
5545           }
5546           case 'Y':
5547           case 'y':
5548           {
5549           if (LocaleCompare(keyword,"y") == 0)
5550             {
5551             y = StringToLong( value );
5552             break;
5553             }
5554           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5555           break;
5556           }
5557           default:
5558           {
5559           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5560           break;
5561           }
5562         }
5563         }
5564
5565         /*
5566           process image.
5567         */
5568         {
5569         Image
5570           *newImage;
5571
5572         newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5573         if (newImage == (Image *) NULL)
5574           break;
5575         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5576         msl_info->image[n]=newImage;
5577         }
5578
5579         break;
5580       }
5581       if (LocaleCompare((const char *) tag,"rotate") == 0)
5582         {
5583           Image
5584             *rotate_image;
5585
5586           /*
5587             Rotate image.
5588           */
5589           if (msl_info->image[n] == (Image *) NULL)
5590             {
5591               ThrowMSLException(OptionError,"NoImagesDefined",
5592                 (const char *) tag);
5593               break;
5594             }
5595           if (attributes != (const xmlChar **) NULL)
5596             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5597             {
5598               keyword=(const char *) attributes[i++];
5599               attribute=InterpretImageProperties(msl_info->image_info[n],
5600                 msl_info->attributes[n],(const char *) attributes[i]);
5601               CloneString(&value,attribute);
5602               switch (*keyword)
5603               {
5604                 case 'D':
5605                 case 'd':
5606                 {
5607                   if (LocaleCompare(keyword,"degrees") == 0)
5608                     {
5609                       geometry_info.rho=InterpretLocaleValue(value,
5610                         (char **) NULL);
5611                       break;
5612                     }
5613                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5614                     keyword);
5615                   break;
5616                 }
5617                 case 'G':
5618                 case 'g':
5619                 {
5620                   if (LocaleCompare(keyword,"geometry") == 0)
5621                     {
5622                       flags=ParseGeometry(value,&geometry_info);
5623                       if ((flags & SigmaValue) == 0)
5624                         geometry_info.sigma=1.0;
5625                       break;
5626                     }
5627                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5628                     keyword);
5629                   break;
5630                 }
5631                 default:
5632                 {
5633                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5634                     keyword);
5635                   break;
5636                 }
5637               }
5638             }
5639           rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5640             &msl_info->image[n]->exception);
5641           if (rotate_image == (Image *) NULL)
5642             break;
5643           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5644           msl_info->image[n]=rotate_image;
5645           break;
5646         }
5647       else if (LocaleCompare((const char *) tag,"rotate") == 0)
5648       {
5649         /* init the values */
5650         double  degrees = 0;
5651
5652         if (msl_info->image[n] == (Image *) NULL)
5653         {
5654           ThrowMSLException(OptionError,"NoImagesDefined",
5655             (const char *) tag);
5656           break;
5657         }
5658         if (attributes == (const xmlChar **) NULL)
5659           break;
5660         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5661         {
5662         keyword=(const char *) attributes[i++];
5663         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5664           msl_info->attributes[n],(const char *) attributes[i]));
5665         switch (*keyword)
5666         {
5667           case 'D':
5668           case 'd':
5669           {
5670           if (LocaleCompare(keyword,"degrees") == 0)
5671             {
5672             degrees = InterpretLocaleValue(value,(char **) NULL);
5673             break;
5674             }
5675           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5676           break;
5677           }
5678           default:
5679           {
5680           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5681           break;
5682           }
5683         }
5684         }
5685
5686         /*
5687           process image.
5688         */
5689         {
5690         Image
5691           *newImage;
5692
5693         newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5694         if (newImage == (Image *) NULL)
5695           break;
5696         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5697         msl_info->image[n]=newImage;
5698         }
5699
5700         break;
5701       }
5702       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5703     }
5704     case 'S':
5705     case 's':
5706     {
5707       if (LocaleCompare((const char *) tag,"sample") == 0)
5708         {
5709           Image
5710             *sample_image;
5711
5712           /*
5713             Sample image.
5714           */
5715           if (msl_info->image[n] == (Image *) NULL)
5716             {
5717               ThrowMSLException(OptionError,"NoImagesDefined",
5718                 (const char *) tag);
5719               break;
5720             }
5721           if (attributes != (const xmlChar **) NULL)
5722             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5723             {
5724               keyword=(const char *) attributes[i++];
5725               attribute=InterpretImageProperties(msl_info->image_info[n],
5726                 msl_info->attributes[n],(const char *) attributes[i]);
5727               CloneString(&value,attribute);
5728               switch (*keyword)
5729               {
5730                 case 'G':
5731                 case 'g':
5732                 {
5733                   if (LocaleCompare(keyword,"geometry") == 0)
5734                     {
5735                       flags=ParseRegionGeometry(msl_info->image[n],value,
5736                         &geometry,&exception);
5737                       break;
5738                     }
5739                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5740                     keyword);
5741                   break;
5742                 }
5743                 case 'H':
5744                 case 'h':
5745                 {
5746                   if (LocaleCompare(keyword,"height") == 0)
5747                     {
5748                       geometry.height=StringToUnsignedLong(value);
5749                       break;
5750                     }
5751                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5752                     keyword);
5753                   break;
5754                 }
5755                 case 'W':
5756                 case 'w':
5757                 {
5758                   if (LocaleCompare(keyword,"width") == 0)
5759                     {
5760                       geometry.width=StringToLong(value);
5761                       break;
5762                     }
5763                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5764                     keyword);
5765                   break;
5766                 }
5767                 default:
5768                 {
5769                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5770                     keyword);
5771                   break;
5772                 }
5773               }
5774             }
5775           sample_image=SampleImage(msl_info->image[n],geometry.width,
5776             geometry.height,&msl_info->image[n]->exception);
5777           if (sample_image == (Image *) NULL)
5778             break;
5779           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5780           msl_info->image[n]=sample_image;
5781           break;
5782         }
5783       if (LocaleCompare((const char *) tag,"scale") == 0)
5784         {
5785           Image
5786             *scale_image;
5787
5788           /*
5789             Scale image.
5790           */
5791           if (msl_info->image[n] == (Image *) NULL)
5792             {
5793               ThrowMSLException(OptionError,"NoImagesDefined",
5794                 (const char *) tag);
5795               break;
5796             }
5797           if (attributes != (const xmlChar **) NULL)
5798             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5799             {
5800               keyword=(const char *) attributes[i++];
5801               attribute=InterpretImageProperties(msl_info->image_info[n],
5802                 msl_info->attributes[n],(const char *) attributes[i]);
5803               CloneString(&value,attribute);
5804               switch (*keyword)
5805               {
5806                 case 'G':
5807                 case 'g':
5808                 {
5809                   if (LocaleCompare(keyword,"geometry") == 0)
5810                     {
5811                       flags=ParseRegionGeometry(msl_info->image[n],value,
5812                         &geometry,&exception);
5813                       break;
5814                     }
5815                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5816                     keyword);
5817                   break;
5818                 }
5819                 case 'H':
5820                 case 'h':
5821                 {
5822                   if (LocaleCompare(keyword,"height") == 0)
5823                     {
5824                       geometry.height=StringToUnsignedLong(value);
5825                       break;
5826                     }
5827                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5828                     keyword);
5829                   break;
5830                 }
5831                 case 'W':
5832                 case 'w':
5833                 {
5834                   if (LocaleCompare(keyword,"width") == 0)
5835                     {
5836                       geometry.width=StringToLong(value);
5837                       break;
5838                     }
5839                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5840                     keyword);
5841                   break;
5842                 }
5843                 default:
5844                 {
5845                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5846                     keyword);
5847                   break;
5848                 }
5849               }
5850             }
5851           scale_image=ScaleImage(msl_info->image[n],geometry.width,
5852             geometry.height,&msl_info->image[n]->exception);
5853           if (scale_image == (Image *) NULL)
5854             break;
5855           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5856           msl_info->image[n]=scale_image;
5857           break;
5858         }
5859       if (LocaleCompare((const char *) tag,"segment") == 0)
5860         {
5861           ColorspaceType
5862             colorspace;
5863
5864           MagickBooleanType
5865             verbose;
5866
5867           /*
5868             Segment image.
5869           */
5870           if (msl_info->image[n] == (Image *) NULL)
5871             {
5872               ThrowMSLException(OptionError,"NoImagesDefined",
5873                 (const char *) tag);
5874               break;
5875             }
5876           geometry_info.rho=1.0;
5877           geometry_info.sigma=1.5;
5878           colorspace=RGBColorspace;
5879           verbose=MagickFalse;
5880           if (attributes != (const xmlChar **) NULL)
5881             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5882             {
5883               keyword=(const char *) attributes[i++];
5884               attribute=InterpretImageProperties(msl_info->image_info[n],
5885                 msl_info->attributes[n],(const char *) attributes[i]);
5886               CloneString(&value,attribute);
5887               switch (*keyword)
5888               {
5889                 case 'C':
5890                 case 'c':
5891                 {
5892                   if (LocaleCompare(keyword,"cluster-threshold") == 0)
5893                     {
5894                       geometry_info.rho=InterpretLocaleValue(value,
5895                         (char **) NULL);
5896                       break;
5897                     }
5898                   if (LocaleCompare(keyword,"colorspace") == 0)
5899                     {
5900                       option=ParseCommandOption(MagickColorspaceOptions,
5901                         MagickFalse,value);
5902                       if (option < 0)
5903                         ThrowMSLException(OptionError,
5904                           "UnrecognizedColorspaceType",value);
5905                       colorspace=(ColorspaceType) option;
5906                       break;
5907                     }
5908                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5909                     keyword);
5910                   break;
5911                 }
5912                 case 'G':
5913                 case 'g':
5914                 {
5915                   if (LocaleCompare(keyword,"geometry") == 0)
5916                     {
5917                       flags=ParseGeometry(value,&geometry_info);
5918                       if ((flags & SigmaValue) == 0)
5919                         geometry_info.sigma=1.5;
5920                       break;
5921                     }
5922                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5923                     keyword);
5924                   break;
5925                 }
5926                 case 'S':
5927                 case 's':
5928                 {
5929                   if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5930                     {
5931                       geometry_info.sigma=InterpretLocaleValue(value,
5932                         (char **) NULL);
5933                       break;
5934                     }
5935                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5936                     keyword);
5937                   break;
5938                 }
5939                 default:
5940                 {
5941                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5942                     keyword);
5943                   break;
5944                 }
5945               }
5946             }
5947           (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5948             geometry_info.rho,geometry_info.sigma);
5949           break;
5950         }
5951       else if (LocaleCompare((const char *) tag, "set") == 0)
5952       {
5953         if (msl_info->image[n] == (Image *) NULL)
5954         {
5955           ThrowMSLException(OptionError,"NoImagesDefined",
5956             (const char *) tag);
5957           break;
5958         }
5959
5960         if (attributes == (const xmlChar **) NULL)
5961           break;
5962         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5963         {
5964           keyword=(const char *) attributes[i++];
5965           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5966             msl_info->attributes[n],(const char *) attributes[i]));
5967           switch (*keyword)
5968           {
5969             case 'C':
5970             case 'c':
5971             {
5972               if (LocaleCompare(keyword,"clip-mask") == 0)
5973                 {
5974                   for (j=0; j < msl_info->n; j++)
5975                   {
5976                     const char
5977                       *property;
5978
5979                     property=GetImageProperty(msl_info->attributes[j],"id");
5980                     if (LocaleCompare(property,value) == 0)
5981                       {
5982                         SetImageMask(msl_info->image[n],msl_info->image[j]);
5983                         break;
5984                       }
5985                   }
5986                   break;
5987                 }
5988               if (LocaleCompare(keyword,"clip-path") == 0)
5989                 {
5990                   for (j=0; j < msl_info->n; j++)
5991                   {
5992                     const char
5993                       *property;
5994
5995                     property=GetImageProperty(msl_info->attributes[j],"id");
5996                     if (LocaleCompare(property,value) == 0)
5997                       {
5998                         SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5999                         break;
6000                       }
6001                   }
6002                   break;
6003                 }
6004               if (LocaleCompare(keyword,"colorspace") == 0)
6005                 {
6006                   ssize_t
6007                     colorspace;
6008
6009                   colorspace=(ColorspaceType) ParseCommandOption(
6010                     MagickColorspaceOptions,MagickFalse,value);
6011                   if (colorspace < 0)
6012                     ThrowMSLException(OptionError,"UnrecognizedColorspace",
6013                       value);
6014                   (void) TransformImageColorspace(msl_info->image[n],
6015                     (ColorspaceType) colorspace);
6016                   break;
6017                 }
6018               (void) SetMSLAttributes(msl_info,keyword,value);
6019               break;
6020             }
6021             case 'D':
6022             case 'd':
6023             {
6024               if (LocaleCompare(keyword,"density") == 0)
6025                 {
6026                   flags=ParseGeometry(value,&geometry_info);
6027                   msl_info->image[n]->x_resolution=geometry_info.rho;
6028                   msl_info->image[n]->y_resolution=geometry_info.sigma;
6029                   if ((flags & SigmaValue) == 0)
6030                     msl_info->image[n]->y_resolution=
6031                       msl_info->image[n]->x_resolution;
6032                   break;
6033                 }
6034               (void) SetMSLAttributes(msl_info,keyword,value);
6035               break;
6036             }
6037             case 'O':
6038             case 'o':
6039             {
6040               if (LocaleCompare(keyword, "opacity") == 0)
6041                 {
6042                   ssize_t  opac = OpaqueAlpha,
6043                   len = (ssize_t) strlen( value );
6044
6045                   if (value[len-1] == '%') {
6046                     char  tmp[100];
6047                     (void) CopyMagickString(tmp,value,len);
6048                     opac = StringToLong( tmp );
6049                     opac = (int)(QuantumRange * ((float)opac/100));
6050                   } else
6051                     opac = StringToLong( value );
6052                   (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6053                   break;
6054               }
6055               (void) SetMSLAttributes(msl_info,keyword,value);
6056               break;
6057             }
6058             case 'P':
6059             case 'p':
6060             {
6061               if (LocaleCompare(keyword, "page") == 0)
6062               {
6063                 char
6064                   page[MaxTextExtent];
6065
6066                 const char
6067                   *image_option;
6068
6069                 MagickStatusType
6070                   flags;
6071
6072                 RectangleInfo
6073                   geometry;
6074
6075                 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6076                 image_option=GetImageOption(msl_info->image_info[n],"page");
6077                 if (image_option != (const char *) NULL)
6078                   flags=ParseAbsoluteGeometry(image_option,&geometry);
6079                 flags=ParseAbsoluteGeometry(value,&geometry);
6080                 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
6081                   (double) geometry.width,(double) geometry.height);
6082                 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
6083                   (void) FormatLocaleString(page,MaxTextExtent,
6084                     "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6085                     (double) geometry.height,(double) geometry.x,(double)
6086                     geometry.y);
6087                 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6088                 msl_info->image_info[n]->page=GetPageGeometry(page);
6089                 break;
6090               }
6091               (void) SetMSLAttributes(msl_info,keyword,value);
6092               break;
6093             }
6094             default:
6095             {
6096               (void) SetMSLAttributes(msl_info,keyword,value);
6097               break;
6098             }
6099           }
6100         }
6101         break;
6102       }
6103       if (LocaleCompare((const char *) tag,"shade") == 0)
6104         {
6105           Image
6106             *shade_image;
6107
6108           MagickBooleanType
6109             gray;
6110
6111           /*
6112             Shade image.
6113           */
6114           if (msl_info->image[n] == (Image *) NULL)
6115             {
6116               ThrowMSLException(OptionError,"NoImagesDefined",
6117                 (const char *) tag);
6118               break;
6119             }
6120           gray=MagickFalse;
6121           if (attributes != (const xmlChar **) NULL)
6122             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6123             {
6124               keyword=(const char *) attributes[i++];
6125               attribute=InterpretImageProperties(msl_info->image_info[n],
6126                 msl_info->attributes[n],(const char *) attributes[i]);
6127               CloneString(&value,attribute);
6128               switch (*keyword)
6129               {
6130                 case 'A':
6131                 case 'a':
6132                 {
6133                   if (LocaleCompare(keyword,"azimuth") == 0)
6134                     {
6135                       geometry_info.rho=InterpretLocaleValue(value,
6136                         (char **) NULL);
6137                       break;
6138                     }
6139                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6140                     keyword);
6141                   break;
6142                 }
6143                 case 'E':
6144                 case 'e':
6145                 {
6146                   if (LocaleCompare(keyword,"elevation") == 0)
6147                     {
6148                       geometry_info.sigma=InterpretLocaleValue(value,
6149                         (char **) NULL);
6150                       break;
6151                     }
6152                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6153                     keyword);
6154                   break;
6155                 }
6156                 case 'G':
6157                 case 'g':
6158                 {
6159                   if (LocaleCompare(keyword,"geometry") == 0)
6160                     {
6161                       flags=ParseGeometry(value,&geometry_info);
6162                       if ((flags & SigmaValue) == 0)
6163                         geometry_info.sigma=1.0;
6164                       break;
6165                     }
6166                   if (LocaleCompare(keyword,"gray") == 0)
6167                     {
6168                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6169                         value);
6170                       if (option < 0)
6171                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6172                           value);
6173                       gray=(MagickBooleanType) option;
6174                       break;
6175                     }
6176                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6177                     keyword);
6178                   break;
6179                 }
6180                 default:
6181                 {
6182                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6183                     keyword);
6184                   break;
6185                 }
6186               }
6187             }
6188           shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6189             geometry_info.sigma,&msl_info->image[n]->exception);
6190           if (shade_image == (Image *) NULL)
6191             break;
6192           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6193           msl_info->image[n]=shade_image;
6194           break;
6195         }
6196       if (LocaleCompare((const char *) tag,"shadow") == 0)
6197         {
6198           Image
6199             *shadow_image;
6200
6201           /*
6202             Shear image.
6203           */
6204           if (msl_info->image[n] == (Image *) NULL)
6205             {
6206               ThrowMSLException(OptionError,"NoImagesDefined",
6207                 (const char *) tag);
6208               break;
6209             }
6210           if (attributes != (const xmlChar **) NULL)
6211             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6212             {
6213               keyword=(const char *) attributes[i++];
6214               attribute=InterpretImageProperties(msl_info->image_info[n],
6215                 msl_info->attributes[n],(const char *) attributes[i]);
6216               CloneString(&value,attribute);
6217               switch (*keyword)
6218               {
6219                 case 'G':
6220                 case 'g':
6221                 {
6222                   if (LocaleCompare(keyword,"geometry") == 0)
6223                     {
6224                       flags=ParseGeometry(value,&geometry_info);
6225                       if ((flags & SigmaValue) == 0)
6226                         geometry_info.sigma=1.0;
6227                       break;
6228                     }
6229                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6230                     keyword);
6231                   break;
6232                 }
6233                 case 'O':
6234                 case 'o':
6235                 {
6236                   if (LocaleCompare(keyword,"opacity") == 0)
6237                     {
6238                       geometry_info.rho=StringToLong(value);
6239                       break;
6240                     }
6241                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6242                     keyword);
6243                   break;
6244                 }
6245                 case 'S':
6246                 case 's':
6247                 {
6248                   if (LocaleCompare(keyword,"sigma") == 0)
6249                     {
6250                       geometry_info.sigma=StringToLong(value);
6251                       break;
6252                     }
6253                   break;
6254                 }
6255                 case 'X':
6256                 case 'x':
6257                 {
6258                   if (LocaleCompare(keyword,"x") == 0)
6259                     {
6260                       geometry_info.xi=InterpretLocaleValue(value,
6261                         (char **) NULL);
6262                       break;
6263                     }
6264                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6265                     keyword);
6266                   break;
6267                 }
6268                 case 'Y':
6269                 case 'y':
6270                 {
6271                   if (LocaleCompare(keyword,"y") == 0)
6272                     {
6273                       geometry_info.psi=StringToLong(value);
6274                       break;
6275                     }
6276                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6277                     keyword);
6278                   break;
6279                 }
6280                 default:
6281                 {
6282                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6283                     keyword);
6284                   break;
6285                 }
6286               }
6287             }
6288           shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
6289             geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
6290             ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
6291           if (shadow_image == (Image *) NULL)
6292             break;
6293           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6294           msl_info->image[n]=shadow_image;
6295           break;
6296         }
6297       if (LocaleCompare((const char *) tag,"sharpen") == 0)
6298       {
6299         double  radius = 0.0,
6300             sigma = 1.0;
6301
6302         if (msl_info->image[n] == (Image *) NULL)
6303           {
6304             ThrowMSLException(OptionError,"NoImagesDefined",
6305               (const char *) tag);
6306             break;
6307           }
6308         /*
6309         NOTE: sharpen can have no attributes, since we use all the defaults!
6310         */
6311         if (attributes != (const xmlChar **) NULL)
6312         {
6313           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6314           {
6315           keyword=(const char *) attributes[i++];
6316           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6317             msl_info->attributes[n],(const char *) attributes[i]));
6318           switch (*keyword)
6319           {
6320             case 'R':
6321             case 'r':
6322             {
6323               if (LocaleCompare(keyword, "radius") == 0)
6324               {
6325                 radius = InterpretLocaleValue(value,(char **) NULL);
6326                 break;
6327               }
6328               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6329               break;
6330             }
6331             case 'S':
6332             case 's':
6333             {
6334               if (LocaleCompare(keyword,"sigma") == 0)
6335               {
6336                 sigma = StringToLong( value );
6337                 break;
6338               }
6339               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6340               break;
6341             }
6342             default:
6343             {
6344               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6345               break;
6346             }
6347           }
6348           }
6349         }
6350
6351         /*
6352           sharpen image.
6353         */
6354         {
6355         Image
6356           *newImage;
6357
6358         newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6359         if (newImage == (Image *) NULL)
6360           break;
6361         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6362         msl_info->image[n]=newImage;
6363         break;
6364         }
6365       }
6366       else if (LocaleCompare((const char *) tag,"shave") == 0)
6367       {
6368         /* init the values */
6369         width = height = 0;
6370         x = y = 0;
6371
6372         if (msl_info->image[n] == (Image *) NULL)
6373         {
6374           ThrowMSLException(OptionError,"NoImagesDefined",
6375             (const char *) tag);
6376           break;
6377         }
6378         if (attributes == (const xmlChar **) NULL)
6379         break;
6380         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6381         {
6382         keyword=(const char *) attributes[i++];
6383         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6384           msl_info->attributes[n],(const char *) attributes[i]));
6385         switch (*keyword)
6386         {
6387           case 'G':
6388           case 'g':
6389           {
6390           if (LocaleCompare(keyword,"geometry") == 0)
6391             {
6392             (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6393             break;
6394             }
6395           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6396           break;
6397           }
6398           case 'H':
6399           case 'h':
6400           {
6401           if (LocaleCompare(keyword,"height") == 0)
6402             {
6403             height = StringToLong( value );
6404             break;
6405             }
6406           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6407           break;
6408           }
6409           case 'W':
6410           case 'w':
6411           {
6412           if (LocaleCompare(keyword,"width") == 0)
6413             {
6414             width = StringToLong( value );
6415             break;
6416             }
6417           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6418           break;
6419           }
6420           default:
6421           {
6422           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6423           break;
6424           }
6425         }
6426         }
6427
6428         /*
6429           process image.
6430         */
6431         {
6432         Image
6433           *newImage;
6434         RectangleInfo
6435           rectInfo;
6436
6437         rectInfo.height = height;
6438         rectInfo.width = width;
6439         rectInfo.x = x;
6440         rectInfo.y = y;
6441
6442
6443         newImage=ShaveImage(msl_info->image[n], &rectInfo,
6444           &msl_info->image[n]->exception);
6445         if (newImage == (Image *) NULL)
6446           break;
6447         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6448         msl_info->image[n]=newImage;
6449         }
6450
6451         break;
6452       }
6453       if (LocaleCompare((const char *) tag,"shear") == 0)
6454         {
6455           Image
6456             *shear_image;
6457
6458           /*
6459             Shear image.
6460           */
6461           if (msl_info->image[n] == (Image *) NULL)
6462             {
6463               ThrowMSLException(OptionError,"NoImagesDefined",
6464                 (const char *) tag);
6465               break;
6466             }
6467           if (attributes != (const xmlChar **) NULL)
6468             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6469             {
6470               keyword=(const char *) attributes[i++];
6471               attribute=InterpretImageProperties(msl_info->image_info[n],
6472                 msl_info->attributes[n],(const char *) attributes[i]);
6473               CloneString(&value,attribute);
6474               switch (*keyword)
6475               {
6476                 case 'F':
6477                 case 'f':
6478                 {
6479                   if (LocaleCompare(keyword, "fill") == 0)
6480                     {
6481                       (void) QueryColorDatabase(value,
6482                         &msl_info->image[n]->background_color,&exception);
6483                       break;
6484                     }
6485                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6486                     keyword);
6487                   break;
6488                 }
6489                 case 'G':
6490                 case 'g':
6491                 {
6492                   if (LocaleCompare(keyword,"geometry") == 0)
6493                     {
6494                       flags=ParseGeometry(value,&geometry_info);
6495                       if ((flags & SigmaValue) == 0)
6496                         geometry_info.sigma=1.0;
6497                       break;
6498                     }
6499                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6500                     keyword);
6501                   break;
6502                 }
6503                 case 'X':
6504                 case 'x':
6505                 {
6506                   if (LocaleCompare(keyword,"x") == 0)
6507                     {
6508                       geometry_info.rho=InterpretLocaleValue(value,
6509                         (char **) NULL);
6510                       break;
6511                     }
6512                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6513                     keyword);
6514                   break;
6515                 }
6516                 case 'Y':
6517                 case 'y':
6518                 {
6519                   if (LocaleCompare(keyword,"y") == 0)
6520                     {
6521                       geometry_info.sigma=StringToLong(value);
6522                       break;
6523                     }
6524                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6525                     keyword);
6526                   break;
6527                 }
6528                 default:
6529                 {
6530                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6531                     keyword);
6532                   break;
6533                 }
6534               }
6535             }
6536           shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6537             geometry_info.sigma,&msl_info->image[n]->exception);
6538           if (shear_image == (Image *) NULL)
6539             break;
6540           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6541           msl_info->image[n]=shear_image;
6542           break;
6543         }
6544       if (LocaleCompare((const char *) tag,"signature") == 0)
6545         {
6546           /*
6547             Signature image.
6548           */
6549           if (msl_info->image[n] == (Image *) NULL)
6550             {
6551               ThrowMSLException(OptionError,"NoImagesDefined",
6552                 (const char *) tag);
6553               break;
6554             }
6555           if (attributes != (const xmlChar **) NULL)
6556             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6557             {
6558               keyword=(const char *) attributes[i++];
6559               attribute=InterpretImageProperties(msl_info->image_info[n],
6560                 msl_info->attributes[n],(const char *) attributes[i]);
6561               CloneString(&value,attribute);
6562               switch (*keyword)
6563               {
6564                 default:
6565                 {
6566                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6567                     keyword);
6568                   break;
6569                 }
6570               }
6571             }
6572           (void) SignatureImage(msl_info->image[n]);
6573           break;
6574         }
6575       if (LocaleCompare((const char *) tag,"solarize") == 0)
6576         {
6577           /*
6578             Solarize image.
6579           */
6580           if (msl_info->image[n] == (Image *) NULL)
6581             {
6582               ThrowMSLException(OptionError,"NoImagesDefined",
6583                 (const char *) tag);
6584               break;
6585             }
6586           geometry_info.rho=QuantumRange/2.0;
6587           if (attributes != (const xmlChar **) NULL)
6588             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6589             {
6590               keyword=(const char *) attributes[i++];
6591               attribute=InterpretImageProperties(msl_info->image_info[n],
6592                 msl_info->attributes[n],(const char *) attributes[i]);
6593               CloneString(&value,attribute);
6594               switch (*keyword)
6595               {
6596                 case 'G':
6597                 case 'g':
6598                 {
6599                   if (LocaleCompare(keyword,"geometry") == 0)
6600                     {
6601                       flags=ParseGeometry(value,&geometry_info);
6602                       break;
6603                     }
6604                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6605                     keyword);
6606                   break;
6607                 }
6608                 case 'T':
6609                 case 't':
6610                 {
6611                   if (LocaleCompare(keyword,"threshold") == 0)
6612                     {
6613                       geometry_info.rho=InterpretLocaleValue(value,
6614                         (char **) NULL);
6615                       break;
6616                     }
6617                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6618                     keyword);
6619                   break;
6620                 }
6621                 default:
6622                 {
6623                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6624                     keyword);
6625                   break;
6626                 }
6627               }
6628             }
6629           (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6630           break;
6631         }
6632       if (LocaleCompare((const char *) tag,"spread") == 0)
6633         {
6634           Image
6635             *spread_image;
6636
6637           /*
6638             Spread image.
6639           */
6640           if (msl_info->image[n] == (Image *) NULL)
6641             {
6642               ThrowMSLException(OptionError,"NoImagesDefined",
6643                 (const char *) tag);
6644               break;
6645             }
6646           if (attributes != (const xmlChar **) NULL)
6647             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6648             {
6649               keyword=(const char *) attributes[i++];
6650               attribute=InterpretImageProperties(msl_info->image_info[n],
6651                 msl_info->attributes[n],(const char *) attributes[i]);
6652               CloneString(&value,attribute);
6653               switch (*keyword)
6654               {
6655                 case 'G':
6656                 case 'g':
6657                 {
6658                   if (LocaleCompare(keyword,"geometry") == 0)
6659                     {
6660                       flags=ParseGeometry(value,&geometry_info);
6661                       if ((flags & SigmaValue) == 0)
6662                         geometry_info.sigma=1.0;
6663                       break;
6664                     }
6665                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6666                     keyword);
6667                   break;
6668                 }
6669                 case 'R':
6670                 case 'r':
6671                 {
6672                   if (LocaleCompare(keyword,"radius") == 0)
6673                     {
6674                       geometry_info.rho=InterpretLocaleValue(value,
6675                         (char **) NULL);
6676                       break;
6677                     }
6678                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6679                     keyword);
6680                   break;
6681                 }
6682                 default:
6683                 {
6684                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6685                     keyword);
6686                   break;
6687                 }
6688               }
6689             }
6690           spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6691             &msl_info->image[n]->exception);
6692           if (spread_image == (Image *) NULL)
6693             break;
6694           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6695           msl_info->image[n]=spread_image;
6696           break;
6697         }
6698       else if (LocaleCompare((const char *) tag,"stegano") == 0)
6699       {
6700         Image *
6701           watermark = (Image*)NULL;
6702
6703         if (msl_info->image[n] == (Image *) NULL)
6704           {
6705             ThrowMSLException(OptionError,"NoImagesDefined",
6706               (const char *) tag);
6707             break;
6708           }
6709         if (attributes == (const xmlChar **) NULL)
6710         break;
6711         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6712         {
6713         keyword=(const char *) attributes[i++];
6714         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6715           msl_info->attributes[n],(const char *) attributes[i]));
6716         switch (*keyword)
6717         {
6718           case 'I':
6719           case 'i':
6720           {
6721           if (LocaleCompare(keyword,"image") == 0)
6722             {
6723             for (j=0; j<msl_info->n;j++)
6724             {
6725               const char *
6726                 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6727               if (theAttr && LocaleCompare(theAttr, value) == 0)
6728               {
6729                 watermark = msl_info->image[j];
6730                 break;
6731               }
6732             }
6733             break;
6734             }
6735           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6736           break;
6737           }
6738           default:
6739           {
6740           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6741           break;
6742           }
6743         }
6744         }
6745
6746         /*
6747           process image.
6748         */
6749         if ( watermark != (Image*) NULL )
6750         {
6751         Image
6752           *newImage;
6753
6754         newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6755         if (newImage == (Image *) NULL)
6756           break;
6757         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6758         msl_info->image[n]=newImage;
6759         break;
6760         } else
6761           ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6762       }
6763       else if (LocaleCompare((const char *) tag,"stereo") == 0)
6764       {
6765         Image *
6766           stereoImage = (Image*)NULL;
6767
6768         if (msl_info->image[n] == (Image *) NULL)
6769           {
6770             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6771             break;
6772           }
6773         if (attributes == (const xmlChar **) NULL)
6774         break;
6775         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6776         {
6777         keyword=(const char *) attributes[i++];
6778         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6779           msl_info->attributes[n],(const char *) attributes[i]));
6780         switch (*keyword)
6781         {
6782           case 'I':
6783           case 'i':
6784           {
6785           if (LocaleCompare(keyword,"image") == 0)
6786             {
6787             for (j=0; j<msl_info->n;j++)
6788             {
6789               const char *
6790                 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6791               if (theAttr && LocaleCompare(theAttr, value) == 0)
6792               {
6793                 stereoImage = msl_info->image[j];
6794                 break;
6795               }
6796             }
6797             break;
6798             }
6799           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6800           break;
6801           }
6802           default:
6803           {
6804           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6805           break;
6806           }
6807         }
6808         }
6809
6810         /*
6811           process image.
6812         */
6813         if ( stereoImage != (Image*) NULL )
6814         {
6815         Image
6816           *newImage;
6817
6818         newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6819         if (newImage == (Image *) NULL)
6820           break;
6821         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6822         msl_info->image[n]=newImage;
6823         break;
6824         } else
6825           ThrowMSLException(OptionError,"Missing stereo image",keyword);
6826       }
6827       if (LocaleCompare((const char *) tag,"swap") == 0)
6828         {
6829           Image
6830             *p,
6831             *q,
6832             *swap;
6833
6834           ssize_t
6835             index,
6836             swap_index;
6837
6838           if (msl_info->image[n] == (Image *) NULL)
6839             {
6840               ThrowMSLException(OptionError,"NoImagesDefined",
6841                 (const char *) tag);
6842               break;
6843             }
6844           index=(-1);
6845           swap_index=(-2);
6846           if (attributes != (const xmlChar **) NULL)
6847             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6848             {
6849               keyword=(const char *) attributes[i++];
6850               attribute=InterpretImageProperties(msl_info->image_info[n],
6851                 msl_info->attributes[n],(const char *) attributes[i]);
6852               CloneString(&value,attribute);
6853               switch (*keyword)
6854               {
6855                 case 'G':
6856                 case 'g':
6857                 {
6858                   if (LocaleCompare(keyword,"indexes") == 0)
6859                     {
6860                       flags=ParseGeometry(value,&geometry_info);
6861                       index=(ssize_t) geometry_info.rho;
6862                       if ((flags & SigmaValue) == 0)
6863                         swap_index=(ssize_t) geometry_info.sigma;
6864                       break;
6865                     }
6866                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6867                     keyword);
6868                   break;
6869                 }
6870                 default:
6871                 {
6872                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6873                     keyword);
6874                   break;
6875                 }
6876               }
6877             }
6878           /*
6879             Swap images.
6880           */
6881           p=GetImageFromList(msl_info->image[n],index);
6882           q=GetImageFromList(msl_info->image[n],swap_index);
6883           if ((p == (Image *) NULL) || (q == (Image *) NULL))
6884             {
6885               ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
6886               break;
6887             }
6888           swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6889           ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6890           ReplaceImageInList(&q,swap);
6891           msl_info->image[n]=GetFirstImageInList(q);
6892           break;
6893         }
6894       if (LocaleCompare((const char *) tag,"swirl") == 0)
6895         {
6896           Image
6897             *swirl_image;
6898
6899           /*
6900             Swirl image.
6901           */
6902           if (msl_info->image[n] == (Image *) NULL)
6903             {
6904               ThrowMSLException(OptionError,"NoImagesDefined",
6905                 (const char *) tag);
6906               break;
6907             }
6908           if (attributes != (const xmlChar **) NULL)
6909             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6910             {
6911               keyword=(const char *) attributes[i++];
6912               attribute=InterpretImageProperties(msl_info->image_info[n],
6913                 msl_info->attributes[n],(const char *) attributes[i]);
6914               CloneString(&value,attribute);
6915               switch (*keyword)
6916               {
6917                 case 'D':
6918                 case 'd':
6919                 {
6920                   if (LocaleCompare(keyword,"degrees") == 0)
6921                     {
6922                       geometry_info.rho=InterpretLocaleValue(value,
6923                         (char **) NULL);
6924                       break;
6925                     }
6926                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6927                     keyword);
6928                   break;
6929                 }
6930                 case 'G':
6931                 case 'g':
6932                 {
6933                   if (LocaleCompare(keyword,"geometry") == 0)
6934                     {
6935                       flags=ParseGeometry(value,&geometry_info);
6936                       if ((flags & SigmaValue) == 0)
6937                         geometry_info.sigma=1.0;
6938                       break;
6939                     }
6940                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6941                     keyword);
6942                   break;
6943                 }
6944                 default:
6945                 {
6946                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6947                     keyword);
6948                   break;
6949                 }
6950               }
6951             }
6952           swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6953             &msl_info->image[n]->exception);
6954           if (swirl_image == (Image *) NULL)
6955             break;
6956           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6957           msl_info->image[n]=swirl_image;
6958           break;
6959         }
6960       if (LocaleCompare((const char *) tag,"sync") == 0)
6961         {
6962           /*
6963             Sync image.
6964           */
6965           if (msl_info->image[n] == (Image *) NULL)
6966             {
6967               ThrowMSLException(OptionError,"NoImagesDefined",
6968                 (const char *) tag);
6969               break;
6970             }
6971           if (attributes != (const xmlChar **) NULL)
6972             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6973             {
6974               keyword=(const char *) attributes[i++];
6975               attribute=InterpretImageProperties(msl_info->image_info[n],
6976                 msl_info->attributes[n],(const char *) attributes[i]);
6977               CloneString(&value,attribute);
6978               switch (*keyword)
6979               {
6980                 default:
6981                 {
6982                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6983                     keyword);
6984                   break;
6985                 }
6986               }
6987             }
6988           (void) SyncImage(msl_info->image[n]);
6989           break;
6990         }
6991       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6992     }
6993     case 'T':
6994     case 't':
6995     {
6996       if (LocaleCompare((const char *) tag,"map") == 0)
6997         {
6998           Image
6999             *texture_image;
7000
7001           /*
7002             Texture image.
7003           */
7004           if (msl_info->image[n] == (Image *) NULL)
7005             {
7006               ThrowMSLException(OptionError,"NoImagesDefined",
7007                 (const char *) tag);
7008               break;
7009             }
7010           texture_image=NewImageList();
7011           if (attributes != (const xmlChar **) NULL)
7012             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7013             {
7014               keyword=(const char *) attributes[i++];
7015               attribute=InterpretImageProperties(msl_info->image_info[n],
7016                 msl_info->attributes[n],(const char *) attributes[i]);
7017               CloneString(&value,attribute);
7018               switch (*keyword)
7019               {
7020                 case 'I':
7021                 case 'i':
7022                 {
7023                   if (LocaleCompare(keyword,"image") == 0)
7024                     for (j=0; j < msl_info->n; j++)
7025                     {
7026                       const char
7027                         *attribute;
7028
7029                       attribute=GetImageProperty(msl_info->attributes[j],"id");
7030                       if ((attribute != (const char *) NULL)  &&
7031                           (LocaleCompare(attribute,value) == 0))
7032                         {
7033                           texture_image=CloneImage(msl_info->image[j],0,0,
7034                             MagickFalse,&exception);
7035                           break;
7036                         }
7037                     }
7038                   break;
7039                 }
7040                 default:
7041                 {
7042                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
7043                     keyword);
7044                   break;
7045                 }
7046               }
7047             }
7048           (void) TextureImage(msl_info->image[n],texture_image);
7049           texture_image=DestroyImage(texture_image);
7050           break;
7051         }
7052       else if (LocaleCompare((const char *) tag,"threshold") == 0)
7053       {
7054         /* init the values */
7055         double  threshold = 0;
7056
7057         if (msl_info->image[n] == (Image *) NULL)
7058           {
7059             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7060             break;
7061           }
7062         if (attributes == (const xmlChar **) NULL)
7063         break;
7064         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7065         {
7066         keyword=(const char *) attributes[i++];
7067         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7068           msl_info->attributes[n],(const char *) attributes[i]));
7069         switch (*keyword)
7070         {
7071           case 'T':
7072           case 't':
7073           {
7074           if (LocaleCompare(keyword,"threshold") == 0)
7075             {
7076             threshold = InterpretLocaleValue(value,(char **) NULL);
7077             break;
7078             }
7079           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7080           break;
7081           }
7082           default:
7083           {
7084           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7085           break;
7086           }
7087         }
7088         }
7089
7090         /*
7091           process image.
7092         */
7093         {
7094         BilevelImageChannel(msl_info->image[n],
7095           (ChannelType) ((ssize_t) (CompositeChannels &~ (ssize_t) OpacityChannel)),
7096           threshold);
7097         break;
7098         }
7099       }
7100       else if (LocaleCompare((const char *) tag, "transparent") == 0)
7101       {
7102         if (msl_info->image[n] == (Image *) NULL)
7103           {
7104             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7105             break;
7106           }
7107         if (attributes == (const xmlChar **) NULL)
7108           break;
7109         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7110         {
7111           keyword=(const char *) attributes[i++];
7112           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7113             msl_info->attributes[n],(const char *) attributes[i]));
7114           switch (*keyword)
7115           {
7116             case 'C':
7117             case 'c':
7118             {
7119               if (LocaleCompare(keyword,"color") == 0)
7120               {
7121                 PixelInfo
7122                   target;
7123
7124                 (void) QueryMagickColor(value,&target,&exception);
7125                 (void) TransparentPaintImage(msl_info->image[n],&target,
7126                   TransparentAlpha,MagickFalse);
7127                 break;
7128               }
7129               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7130               break;
7131             }
7132             default:
7133             {
7134               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7135             break;
7136             }
7137           }
7138         }
7139         break;
7140       }
7141       else if (LocaleCompare((const char *) tag, "trim") == 0)
7142       {
7143         if (msl_info->image[n] == (Image *) NULL)
7144           {
7145             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7146             break;
7147           }
7148
7149         /* no attributes here */
7150
7151         /* process the image */
7152         {
7153           Image
7154             *newImage;
7155           RectangleInfo
7156             rectInfo;
7157
7158           /* all zeros on a crop == trim edges! */
7159           rectInfo.height = rectInfo.width = 0;
7160           rectInfo.x =  rectInfo.y = 0;
7161
7162           newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7163           if (newImage == (Image *) NULL)
7164             break;
7165           msl_info->image[n]=DestroyImage(msl_info->image[n]);
7166           msl_info->image[n]=newImage;
7167           break;
7168         }
7169       }
7170       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7171     }
7172     case 'W':
7173     case 'w':
7174     {
7175       if (LocaleCompare((const char *) tag,"write") == 0)
7176         {
7177           if (msl_info->image[n] == (Image *) NULL)
7178             {
7179               ThrowMSLException(OptionError,"NoImagesDefined",
7180                 (const char *) tag);
7181               break;
7182             }
7183           if (attributes == (const xmlChar **) NULL)
7184             break;
7185           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7186           {
7187             keyword=(const char *) attributes[i++];
7188             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7189               msl_info->attributes[n],(const char *) attributes[i]));
7190             switch (*keyword)
7191             {
7192               case 'F':
7193               case 'f':
7194               {
7195                 if (LocaleCompare(keyword,"filename") == 0)
7196                   {
7197                     (void) CopyMagickString(msl_info->image[n]->filename,value,
7198                       MaxTextExtent);
7199                     break;
7200                   }
7201                 (void) SetMSLAttributes(msl_info,keyword,value);
7202               }
7203               default:
7204               {
7205                 (void) SetMSLAttributes(msl_info,keyword,value);
7206                 break;
7207               }
7208             }
7209           }
7210
7211           /* process */
7212           {
7213             (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7214             break;
7215           }
7216         }
7217       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7218     }
7219     default:
7220     {
7221       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7222       break;
7223     }
7224   }
7225   if ( value != NULL )
7226     value=DestroyString(value);
7227   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  )");
7228 }
7229
7230 static void MSLEndElement(void *context,const xmlChar *tag)
7231 {
7232   ssize_t
7233     n;
7234
7235   MSLInfo
7236     *msl_info;
7237
7238   /*
7239     Called when the end of an element has been detected.
7240   */
7241   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.endElement(%s)",
7242     tag);
7243   msl_info=(MSLInfo *) context;
7244   n=msl_info->n;
7245   switch (*tag)
7246   {
7247     case 'C':
7248     case 'c':
7249     {
7250       if (LocaleCompare((const char *) tag,"comment") == 0 )
7251         {
7252           (void) DeleteImageProperty(msl_info->image[n],"comment");
7253           if (msl_info->content == (char *) NULL)
7254             break;
7255           StripString(msl_info->content);
7256           (void) SetImageProperty(msl_info->image[n],"comment",
7257             msl_info->content);
7258           break;
7259         }
7260       break;
7261     }
7262     case 'G':
7263     case 'g':
7264     {
7265       if (LocaleCompare((const char *) tag, "group") == 0 )
7266       {
7267         if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7268         {
7269           ssize_t  i = (ssize_t)
7270             (msl_info->group_info[msl_info->number_groups-1].numImages);
7271           while ( i-- )
7272           {
7273             if (msl_info->image[msl_info->n] != (Image *) NULL)
7274               msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7275             msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7276             msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7277             msl_info->n--;
7278           }
7279         }
7280         msl_info->number_groups--;
7281       }
7282       break;
7283     }
7284     case 'I':
7285     case 'i':
7286     {
7287       if (LocaleCompare((const char *) tag, "image") == 0)
7288         MSLPopImage(msl_info);
7289        break;
7290     }
7291     case 'L':
7292     case 'l':
7293     {
7294       if (LocaleCompare((const char *) tag,"label") == 0 )
7295         {
7296           (void) DeleteImageProperty(msl_info->image[n],"label");
7297           if (msl_info->content == (char *) NULL)
7298             break;
7299           StripString(msl_info->content);
7300           (void) SetImageProperty(msl_info->image[n],"label",
7301             msl_info->content);
7302           break;
7303         }
7304       break;
7305     }
7306     case 'M':
7307     case 'm':
7308     {
7309       if (LocaleCompare((const char *) tag, "msl") == 0 )
7310       {
7311         /*
7312           This our base element.
7313             at the moment we don't do anything special
7314             but someday we might!
7315         */
7316       }
7317       break;
7318     }
7319     default:
7320       break;
7321   }
7322   if (msl_info->content != (char *) NULL)
7323     msl_info->content=DestroyString(msl_info->content);
7324 }
7325
7326 static void MSLCharacters(void *context,const xmlChar *c,int length)
7327 {
7328   MSLInfo
7329     *msl_info;
7330
7331   register char
7332     *p;
7333
7334   register ssize_t
7335     i;
7336
7337   /*
7338     Receiving some characters from the parser.
7339   */
7340   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7341     "  SAX.characters(%s,%d)",c,length);
7342   msl_info=(MSLInfo *) context;
7343   if (msl_info->content != (char *) NULL)
7344     msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7345       strlen(msl_info->content)+length+MaxTextExtent,
7346       sizeof(*msl_info->content));
7347   else
7348     {
7349       msl_info->content=(char *) NULL;
7350       if (~length >= (MaxTextExtent-1))
7351         msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7352           sizeof(*msl_info->content));
7353       if (msl_info->content != (char *) NULL)
7354         *msl_info->content='\0';
7355     }
7356   if (msl_info->content == (char *) NULL)
7357     return;
7358   p=msl_info->content+strlen(msl_info->content);
7359   for (i=0; i < length; i++)
7360     *p++=c[i];
7361   *p='\0';
7362 }
7363
7364 static void MSLReference(void *context,const xmlChar *name)
7365 {
7366   MSLInfo
7367     *msl_info;
7368
7369   xmlParserCtxtPtr
7370     parser;
7371
7372   /*
7373     Called when an entity reference is detected.
7374   */
7375   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7376     "  SAX.reference(%s)",name);
7377   msl_info=(MSLInfo *) context;
7378   parser=msl_info->parser;
7379   if (*name == '#')
7380     (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7381   else
7382     (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7383 }
7384
7385 static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7386 {
7387   MSLInfo
7388     *msl_info;
7389
7390   /*
7391     Receiving some ignorable whitespaces from the parser.
7392   */
7393   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7394     "  SAX.ignorableWhitespace(%.30s, %d)",c,length);
7395   msl_info=(MSLInfo *) context;
7396   (void) msl_info;
7397 }
7398
7399 static void MSLProcessingInstructions(void *context,const xmlChar *target,
7400   const xmlChar *data)
7401 {
7402   MSLInfo
7403     *msl_info;
7404
7405   /*
7406     A processing instruction has been parsed.
7407   */
7408   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7409     "  SAX.processingInstruction(%s, %s)",
7410     target,data);
7411   msl_info=(MSLInfo *) context;
7412   (void) msl_info;
7413 }
7414
7415 static void MSLComment(void *context,const xmlChar *value)
7416 {
7417   MSLInfo
7418     *msl_info;
7419
7420   /*
7421     A comment has been parsed.
7422   */
7423   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7424     "  SAX.comment(%s)",value);
7425   msl_info=(MSLInfo *) context;
7426   (void) msl_info;
7427 }
7428
7429 static void MSLWarning(void *context,const char *format,...)
7430 {
7431   char
7432     *message,
7433     reason[MaxTextExtent];
7434
7435   MSLInfo
7436     *msl_info;
7437
7438   va_list
7439     operands;
7440
7441   /**
7442     Display and format a warning messages, gives file, line, position and
7443     extra parameters.
7444   */
7445   va_start(operands,format);
7446   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.warning: ");
7447   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7448   msl_info=(MSLInfo *) context;
7449   (void) msl_info;
7450 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7451   (void) vsprintf(reason,format,operands);
7452 #else
7453   (void) vsnprintf(reason,MaxTextExtent,format,operands);
7454 #endif
7455   message=GetExceptionMessage(errno);
7456   ThrowMSLException(CoderError,reason,message);
7457   message=DestroyString(message);
7458   va_end(operands);
7459 }
7460
7461 static void MSLError(void *context,const char *format,...)
7462 {
7463   char
7464     reason[MaxTextExtent];
7465
7466   MSLInfo
7467     *msl_info;
7468
7469   va_list
7470     operands;
7471
7472   /*
7473     Display and format a error formats, gives file, line, position and
7474     extra parameters.
7475   */
7476   va_start(operands,format);
7477   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.error: ");
7478   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7479   msl_info=(MSLInfo *) context;
7480   (void) msl_info;
7481 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7482   (void) vsprintf(reason,format,operands);
7483 #else
7484   (void) vsnprintf(reason,MaxTextExtent,format,operands);
7485 #endif
7486   ThrowMSLException(DelegateFatalError,reason,"SAX error");
7487   va_end(operands);
7488 }
7489
7490 static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7491 {
7492   MSLInfo
7493     *msl_info;
7494
7495    xmlNodePtr
7496      child;
7497
7498   xmlParserCtxtPtr
7499     parser;
7500
7501   /*
7502     Called when a pcdata block has been parsed.
7503   */
7504   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7505     "  SAX.pcdata(%s, %d)",value,length);
7506   msl_info=(MSLInfo *) context;
7507   (void) msl_info;
7508   parser=msl_info->parser;
7509   child=xmlGetLastChild(parser->node);
7510   if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7511     {
7512       xmlTextConcat(child,value,length);
7513       return;
7514     }
7515   (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7516 }
7517
7518 static void MSLExternalSubset(void *context,const xmlChar *name,
7519   const xmlChar *external_id,const xmlChar *system_id)
7520 {
7521   MSLInfo
7522     *msl_info;
7523
7524   xmlParserCtxt
7525     parser_context;
7526
7527   xmlParserCtxtPtr
7528     parser;
7529
7530   xmlParserInputPtr
7531     input;
7532
7533   /*
7534     Does this document has an external subset?
7535   */
7536   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7537     "  SAX.externalSubset(%s %s %s)",name,
7538     (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7539     (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
7540   msl_info=(MSLInfo *) context;
7541   (void) msl_info;
7542   parser=msl_info->parser;
7543   if (((external_id == NULL) && (system_id == NULL)) ||
7544       ((parser->validate == 0) || (parser->wellFormed == 0) ||
7545       (msl_info->document == 0)))
7546     return;
7547   input=MSLResolveEntity(context,external_id,system_id);
7548   if (input == NULL)
7549     return;
7550   (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7551   parser_context=(*parser);
7552   parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7553   if (parser->inputTab == (xmlParserInputPtr *) NULL)
7554     {
7555       parser->errNo=XML_ERR_NO_MEMORY;
7556       parser->input=parser_context.input;
7557       parser->inputNr=parser_context.inputNr;
7558       parser->inputMax=parser_context.inputMax;
7559       parser->inputTab=parser_context.inputTab;
7560       return;
7561   }
7562   parser->inputNr=0;
7563   parser->inputMax=5;
7564   parser->input=NULL;
7565   xmlPushInput(parser,input);
7566   (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7567   if (input->filename == (char *) NULL)
7568     input->filename=(char *) xmlStrdup(system_id);
7569   input->line=1;
7570   input->col=1;
7571   input->base=parser->input->cur;
7572   input->cur=parser->input->cur;
7573   input->free=NULL;
7574   xmlParseExternalSubset(parser,external_id,system_id);
7575   while (parser->inputNr > 1)
7576     (void) xmlPopInput(parser);
7577   xmlFreeInputStream(parser->input);
7578   xmlFree(parser->inputTab);
7579   parser->input=parser_context.input;
7580   parser->inputNr=parser_context.inputNr;
7581   parser->inputMax=parser_context.inputMax;
7582   parser->inputTab=parser_context.inputTab;
7583 }
7584
7585 #if defined(__cplusplus) || defined(c_plusplus)
7586 }
7587 #endif
7588
7589 static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7590   ExceptionInfo *exception)
7591 {
7592   char
7593     message[MaxTextExtent];
7594
7595   Image
7596     *msl_image;
7597
7598   int
7599     status;
7600
7601   ssize_t
7602     n;
7603
7604   MSLInfo
7605     msl_info;
7606
7607   xmlSAXHandler
7608     sax_modules;
7609
7610   xmlSAXHandlerPtr
7611     sax_handler;
7612
7613   /*
7614     Open image file.
7615   */
7616   assert(image_info != (const ImageInfo *) NULL);
7617   assert(image_info->signature == MagickSignature);
7618   if (image_info->debug != MagickFalse)
7619     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7620       image_info->filename);
7621   assert(image != (Image **) NULL);
7622   msl_image=AcquireImage(image_info);
7623   status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7624   if (status == MagickFalse)
7625     {
7626       ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7627         msl_image->filename);
7628       msl_image=DestroyImageList(msl_image);
7629       return(MagickFalse);
7630     }
7631   msl_image->columns=1;
7632   msl_image->rows=1;
7633   /*
7634     Parse MSL file.
7635   */
7636   (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7637   msl_info.exception=exception;
7638   msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7639     sizeof(*msl_info.image_info));
7640   msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7641     sizeof(*msl_info.draw_info));
7642   /* top of the stack is the MSL file itself */
7643   msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
7644   msl_info.attributes=(Image **) AcquireMagickMemory(
7645     sizeof(*msl_info.attributes));
7646   msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7647     sizeof(*msl_info.group_info));
7648   if ((msl_info.image_info == (ImageInfo **) NULL) ||
7649       (msl_info.image == (Image **) NULL) ||
7650       (msl_info.attributes == (Image **) NULL) ||
7651       (msl_info.group_info == (MSLGroupInfo *) NULL))
7652     ThrowFatalException(ResourceLimitFatalError,
7653       "UnableToInterpretMSLImage");
7654   *msl_info.image_info=CloneImageInfo(image_info);
7655   *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7656   *msl_info.attributes=AcquireImage(image_info);
7657   msl_info.group_info[0].numImages=0;
7658   /* the first slot is used to point to the MSL file image */
7659   *msl_info.image=msl_image;
7660   if (*image != (Image *) NULL)
7661     MSLPushImage(&msl_info,*image);
7662   (void) xmlSubstituteEntitiesDefault(1);
7663   (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7664   sax_modules.internalSubset=MSLInternalSubset;
7665   sax_modules.isStandalone=MSLIsStandalone;
7666   sax_modules.hasInternalSubset=MSLHasInternalSubset;
7667   sax_modules.hasExternalSubset=MSLHasExternalSubset;
7668   sax_modules.resolveEntity=MSLResolveEntity;
7669   sax_modules.getEntity=MSLGetEntity;
7670   sax_modules.entityDecl=MSLEntityDeclaration;
7671   sax_modules.notationDecl=MSLNotationDeclaration;
7672   sax_modules.attributeDecl=MSLAttributeDeclaration;
7673   sax_modules.elementDecl=MSLElementDeclaration;
7674   sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7675   sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7676   sax_modules.startDocument=MSLStartDocument;
7677   sax_modules.endDocument=MSLEndDocument;
7678   sax_modules.startElement=MSLStartElement;
7679   sax_modules.endElement=MSLEndElement;
7680   sax_modules.reference=MSLReference;
7681   sax_modules.characters=MSLCharacters;
7682   sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7683   sax_modules.processingInstruction=MSLProcessingInstructions;
7684   sax_modules.comment=MSLComment;
7685   sax_modules.warning=MSLWarning;
7686   sax_modules.error=MSLError;
7687   sax_modules.fatalError=MSLError;
7688   sax_modules.getParameterEntity=MSLGetParameterEntity;
7689   sax_modules.cdataBlock=MSLCDataBlock;
7690   sax_modules.externalSubset=MSLExternalSubset;
7691   sax_handler=(&sax_modules);
7692   msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
7693     msl_image->filename);
7694   while (ReadBlobString(msl_image,message) != (char *) NULL)
7695   {
7696     n=(ssize_t) strlen(message);
7697     if (n == 0)
7698       continue;
7699     status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7700     if (status != 0)
7701       break;
7702     (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7703     if (msl_info.exception->severity >= ErrorException)
7704       break;
7705   }
7706   if (msl_info.exception->severity == UndefinedException)
7707     (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7708   xmlFreeParserCtxt(msl_info.parser);
7709   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7710   xmlCleanupParser();
7711   msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7712     msl_info.group_info);
7713   if (*image == (Image *) NULL)
7714     *image=(*msl_info.image);
7715   if ((*msl_info.image)->exception.severity != UndefinedException)
7716     return(MagickFalse);
7717   return(MagickTrue);
7718 }
7719
7720 static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7721 {
7722   Image
7723     *image;
7724
7725   /*
7726     Open image file.
7727   */
7728   assert(image_info != (const ImageInfo *) NULL);
7729   assert(image_info->signature == MagickSignature);
7730   if (image_info->debug != MagickFalse)
7731     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7732       image_info->filename);
7733   assert(exception != (ExceptionInfo *) NULL);
7734   assert(exception->signature == MagickSignature);
7735   image=(Image *) NULL;
7736   (void) ProcessMSLScript(image_info,&image,exception);
7737   return(GetFirstImageInList(image));
7738 }
7739 #endif
7740 \f
7741 /*
7742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7743 %                                                                             %
7744 %                                                                             %
7745 %                                                                             %
7746 %   R e g i s t e r M S L I m a g e                                           %
7747 %                                                                             %
7748 %                                                                             %
7749 %                                                                             %
7750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7751 %
7752 %  RegisterMSLImage() adds attributes for the MSL image format to
7753 %  the list of supported formats.  The attributes include the image format
7754 %  tag, a method to read and/or write the format, whether the format
7755 %  supports the saving of more than one frame to the same file or blob,
7756 %  whether the format supports native in-memory I/O, and a brief
7757 %  description of the format.
7758 %
7759 %  The format of the RegisterMSLImage method is:
7760 %
7761 %      size_t RegisterMSLImage(void)
7762 %
7763 */
7764 ModuleExport size_t RegisterMSLImage(void)
7765 {
7766   MagickInfo
7767     *entry;
7768
7769   entry=SetMagickInfo("MSL");
7770 #if defined(MAGICKCORE_XML_DELEGATE)
7771   entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7772   entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7773 #endif
7774   entry->description=ConstantString("Magick Scripting Language");
7775   entry->module=ConstantString("MSL");
7776   (void) RegisterMagickInfo(entry);
7777   return(MagickImageCoderSignature);
7778 }
7779 \f
7780 #if defined(MAGICKCORE_XML_DELEGATE)
7781 /*
7782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7783 %                                                                             %
7784 %                                                                             %
7785 %                                                                             %
7786 %   S e t M S L A t t r i b u t e s                                           %
7787 %                                                                             %
7788 %                                                                             %
7789 %                                                                             %
7790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7791 %
7792 %  SetMSLAttributes() ...
7793 %
7794 %  The format of the SetMSLAttributes method is:
7795 %
7796 %      MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
7797 %        const char *keyword,const char *value)
7798 %
7799 %  A description of each parameter follows:
7800 %
7801 %    o msl_info: the MSL info.
7802 %
7803 %    o keyword: the keyword.
7804 %
7805 %    o value: the value.
7806 %
7807 */
7808 static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7809   const char *value)
7810 {
7811   Image
7812     *attributes;
7813
7814   DrawInfo
7815     *draw_info;
7816
7817   ExceptionInfo
7818     *exception;
7819
7820   GeometryInfo
7821     geometry_info;
7822
7823   Image
7824     *image;
7825
7826   ImageInfo
7827     *image_info;
7828
7829   int
7830     flags;
7831
7832   ssize_t
7833     n;
7834
7835   assert(msl_info != (MSLInfo *) NULL);
7836   if (keyword == (const char *) NULL)
7837     return(MagickTrue);
7838   if (value == (const char *) NULL)
7839     return(MagickTrue);
7840   exception=msl_info->exception;
7841   n=msl_info->n;
7842   attributes=msl_info->attributes[n];
7843   image_info=msl_info->image_info[n];
7844   draw_info=msl_info->draw_info[n];
7845   image=msl_info->image[n];
7846   switch (*keyword)
7847   {
7848     case 'A':
7849     case 'a':
7850     {
7851       if (LocaleCompare(keyword,"adjoin") == 0)
7852         {
7853           ssize_t
7854             adjoin;
7855
7856           adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
7857           if (adjoin < 0)
7858             ThrowMSLException(OptionError,"UnrecognizedType",value);
7859           image_info->adjoin=(MagickBooleanType) adjoin;
7860           break;
7861         }
7862       if (LocaleCompare(keyword,"alpha") == 0)
7863         {
7864           ssize_t
7865             alpha;
7866
7867           alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
7868           if (alpha < 0)
7869             ThrowMSLException(OptionError,"UnrecognizedType",value);
7870           if (image != (Image *) NULL)
7871             (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha);
7872           break;
7873         }
7874       if (LocaleCompare(keyword,"antialias") == 0)
7875         {
7876           ssize_t
7877             antialias;
7878
7879           antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
7880           if (antialias < 0)
7881             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7882           image_info->antialias=(MagickBooleanType) antialias;
7883           break;
7884         }
7885       if (LocaleCompare(keyword,"area-limit") == 0)
7886         {
7887           MagickSizeType
7888             limit;
7889
7890           limit=MagickResourceInfinity;
7891           if (LocaleCompare(value,"unlimited") != 0)
7892             limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
7893           (void) SetMagickResourceLimit(AreaResource,limit);
7894           break;
7895         }
7896       if (LocaleCompare(keyword,"attenuate") == 0)
7897         {
7898           (void) SetImageOption(image_info,keyword,value);
7899           break;
7900         }
7901       if (LocaleCompare(keyword,"authenticate") == 0)
7902         {
7903           (void) CloneString(&image_info->density,value);
7904           break;
7905         }
7906       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7907       break;
7908     }
7909     case 'B':
7910     case 'b':
7911     {
7912       if (LocaleCompare(keyword,"background") == 0)
7913         {
7914           (void) QueryColorDatabase(value,&image_info->background_color,
7915             exception);
7916           break;
7917         }
7918       if (LocaleCompare(keyword,"bias") == 0)
7919         {
7920           if (image == (Image *) NULL)
7921             break;
7922           image->bias=SiPrefixToDouble(value,QuantumRange);
7923           break;
7924         }
7925       if (LocaleCompare(keyword,"blue-primary") == 0)
7926         {
7927           if (image == (Image *) NULL)
7928             break;
7929           flags=ParseGeometry(value,&geometry_info);
7930           image->chromaticity.blue_primary.x=geometry_info.rho;
7931           image->chromaticity.blue_primary.y=geometry_info.sigma;
7932           if ((flags & SigmaValue) == 0)
7933             image->chromaticity.blue_primary.y=
7934               image->chromaticity.blue_primary.x;
7935           break;
7936         }
7937       if (LocaleCompare(keyword,"bordercolor") == 0)
7938         {
7939           (void) QueryColorDatabase(value,&image_info->border_color,
7940             exception);
7941           break;
7942         }
7943       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7944       break;
7945     }
7946     case 'D':
7947     case 'd':
7948     {
7949       if (LocaleCompare(keyword,"density") == 0)
7950         {
7951           (void) CloneString(&image_info->density,value);
7952           (void) CloneString(&draw_info->density,value);
7953           break;
7954         }
7955       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7956       break;
7957     }
7958     case 'F':
7959     case 'f':
7960     {
7961       if (LocaleCompare(keyword,"fill") == 0)
7962         {
7963           (void) QueryColorDatabase(value,&draw_info->fill,exception);
7964           (void) SetImageOption(image_info,keyword,value);
7965           break;
7966         }
7967       if (LocaleCompare(keyword,"filename") == 0)
7968         {
7969           (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7970           break;
7971         }
7972       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7973       break;
7974     }
7975     case 'G':
7976     case 'g':
7977     {
7978       if (LocaleCompare(keyword,"gravity") == 0)
7979         {
7980           ssize_t
7981             gravity;
7982
7983           gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
7984           if (gravity < 0)
7985             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7986           (void) SetImageOption(image_info,keyword,value);
7987           break;
7988         }
7989       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7990       break;
7991     }
7992     case 'I':
7993     case 'i':
7994     {
7995       if (LocaleCompare(keyword,"id") == 0)
7996         {
7997           (void) SetImageProperty(attributes,keyword,value);
7998           break;
7999         }
8000       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8001       break;
8002     }
8003     case 'M':
8004     case 'm':
8005     {
8006       if (LocaleCompare(keyword,"magick") == 0)
8007         {
8008           (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
8009           break;
8010         }
8011       if (LocaleCompare(keyword,"mattecolor") == 0)
8012         {
8013           (void) QueryColorDatabase(value,&image_info->matte_color,
8014             exception);
8015           break;
8016         }
8017       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8018       break;
8019     }
8020     case 'P':
8021     case 'p':
8022     {
8023       if (LocaleCompare(keyword,"pointsize") == 0)
8024         {
8025           image_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8026           draw_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8027           break;
8028         }
8029       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8030       break;
8031     }
8032     case 'Q':
8033     case 'q':
8034     {
8035       if (LocaleCompare(keyword,"quality") == 0)
8036         {
8037           image_info->quality=StringToLong(value);
8038           if (image == (Image *) NULL)
8039             break;
8040           image->quality=StringToLong(value);
8041           break;
8042         }
8043       break;
8044     }
8045     case 'S':
8046     case 's':
8047     {
8048       if (LocaleCompare(keyword,"size") == 0)
8049         {
8050           (void) CloneString(&image_info->size,value);
8051           break;
8052         }
8053       if (LocaleCompare(keyword,"stroke") == 0)
8054         {
8055           (void) QueryColorDatabase(value,&draw_info->stroke,exception);
8056           (void) SetImageOption(image_info,keyword,value);
8057           break;
8058         }
8059       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8060       break;
8061     }
8062     default:
8063     {
8064       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8065       break;
8066     }
8067   }
8068   return(MagickTrue);
8069 }
8070 #endif
8071 \f
8072 /*
8073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8074 %                                                                             %
8075 %                                                                             %
8076 %                                                                             %
8077 %   U n r e g i s t e r M S L I m a g e                                       %
8078 %                                                                             %
8079 %                                                                             %
8080 %                                                                             %
8081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8082 %
8083 %  UnregisterMSLImage() removes format registrations made by the
8084 %  MSL module from the list of supported formats.
8085 %
8086 %  The format of the UnregisterMSLImage method is:
8087 %
8088 %      UnregisterMSLImage(void)
8089 %
8090 */
8091 ModuleExport void UnregisterMSLImage(void)
8092 {
8093   (void) UnregisterMagickInfo("MSL");
8094 }
8095 \f
8096 #if defined(MAGICKCORE_XML_DELEGATE)
8097 /*
8098 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8099 %                                                                             %
8100 %                                                                             %
8101 %                                                                             %
8102 %   W r i t e M S L I m a g e                                                 %
8103 %                                                                             %
8104 %                                                                             %
8105 %                                                                             %
8106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8107 %
8108 %  WriteMSLImage() writes an image to a file in MVG image format.
8109 %
8110 %  The format of the WriteMSLImage method is:
8111 %
8112 %      MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8113 %
8114 %  A description of each parameter follows.
8115 %
8116 %    o image_info: the image info.
8117 %
8118 %    o image:  The image.
8119 %
8120 */
8121 static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8122 {
8123   assert(image_info != (const ImageInfo *) NULL);
8124   assert(image_info->signature == MagickSignature);
8125   assert(image != (Image *) NULL);
8126   assert(image->signature == MagickSignature);
8127   if (image->debug != MagickFalse)
8128     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8129   (void) ReferenceImage(image);
8130   (void) ProcessMSLScript(image_info,&image,&image->exception);
8131   return(MagickTrue);
8132 }
8133 #endif