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