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