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