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