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