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