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