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