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