Coverage Report

Created: 2026-02-14 07:11

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