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