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