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