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