blob: 11b8a0bea8fe3ca0dac6938fe1d98b6708a8e3d7 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% M M SSSSS L %
7% MM MM SS L %
8% M M M SSS L %
9% M M SS L %
10% M M SSSSS LLLLL %
11% %
12% %
13% Execute Magick Scripting Language Scripts. %
14% %
15% Software Design %
16% John Cristy %
17% Leonard Rosenthol %
18% William Radcliffe %
19% December 2001 %
20% %
21% %
cristy7e41fe82010-12-04 23:12:08 +000022% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000023% 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 "magick/studio.h"
45#include "magick/annotate.h"
46#include "magick/artifact.h"
47#include "magick/blob.h"
48#include "magick/blob-private.h"
49#include "magick/cache.h"
50#include "magick/cache-view.h"
51#include "magick/color.h"
cristy316d5172009-09-17 19:31:25 +000052#include "magick/colormap.h"
cristy3ed852e2009-09-05 21:47:34 +000053#include "magick/color-private.h"
54#include "magick/composite.h"
55#include "magick/constitute.h"
56#include "magick/decorate.h"
57#include "magick/display.h"
58#include "magick/draw.h"
59#include "magick/effect.h"
60#include "magick/enhance.h"
61#include "magick/exception.h"
62#include "magick/exception-private.h"
63#include "magick/fx.h"
64#include "magick/geometry.h"
65#include "magick/image.h"
66#include "magick/image-private.h"
67#include "magick/list.h"
68#include "magick/log.h"
69#include "magick/magick.h"
70#include "magick/memory_.h"
cristyf2f27272009-12-17 14:48:46 +000071#include "magick/module.h"
cristy3ed852e2009-09-05 21:47:34 +000072#include "magick/option.h"
73#include "magick/paint.h"
cristy4fa36e42009-09-18 14:24:06 +000074#include "magick/profile.h"
cristy3ed852e2009-09-05 21:47:34 +000075#include "magick/property.h"
76#include "magick/quantize.h"
77#include "magick/quantum-private.h"
cristy4fa36e42009-09-18 14:24:06 +000078#include "magick/registry.h"
cristy3ed852e2009-09-05 21:47:34 +000079#include "magick/resize.h"
cristy4582cbb2009-09-23 00:35:43 +000080#include "magick/resource_.h"
cristy3ed852e2009-09-05 21:47:34 +000081#include "magick/segment.h"
82#include "magick/shear.h"
83#include "magick/signature.h"
84#include "magick/static.h"
85#include "magick/string_.h"
cristyf2f27272009-12-17 14:48:46 +000086#include "magick/string-private.h"
cristy3ed852e2009-09-05 21:47:34 +000087#include "magick/transform.h"
88#include "magick/threshold.h"
89#include "magick/utility.h"
90#if defined(MAGICKCORE_XML_DELEGATE)
cristy0157aea2010-04-24 21:12:18 +000091# if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000092# if defined(__MINGW32__)
93# define _MSC_VER
94# else
95# include <win32config.h>
96# endif
97# endif
98# include <libxml/parser.h>
99# include <libxml/xmlmemory.h>
100# include <libxml/parserInternals.h>
101# include <libxml/xmlerror.h>
102#endif
103
104/*
105 Define Declatations.
106*/
107#define ThrowMSLException(severity,tag,reason) \
108 (void) ThrowMagickException(msl_info->exception,GetMagickModule(),severity, \
109 tag,"`%s'",reason);
110
111/*
112 Typedef declaractions.
113*/
114typedef struct _MSLGroupInfo
115{
cristybb503372010-05-27 20:51:26 +0000116 size_t
cristy3ed852e2009-09-05 21:47:34 +0000117 numImages; /* how many images are in this group */
118} MSLGroupInfo;
119
120typedef struct _MSLInfo
121{
122 ExceptionInfo
123 *exception;
124
cristybb503372010-05-27 20:51:26 +0000125 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000126 n,
127 number_groups;
128
129 ImageInfo
130 **image_info;
131
132 DrawInfo
133 **draw_info;
134
135 Image
136 **attributes,
137 **image;
138
139 char
140 *content;
141
142 MSLGroupInfo
143 *group_info;
144
145#if defined(MAGICKCORE_XML_DELEGATE)
146 xmlParserCtxtPtr
147 parser;
148
149 xmlDocPtr
150 document;
151#endif
152} MSLInfo;
153
154/*
155 Forward declarations.
156*/
157#if defined(MAGICKCORE_XML_DELEGATE)
158static MagickBooleanType
159 WriteMSLImage(const ImageInfo *,Image *);
cristyb988fe72009-09-16 01:01:10 +0000160
161static MagickBooleanType
cristyb20775d2009-09-16 01:51:41 +0000162 SetMSLAttributes(MSLInfo *,const char *,const char *);
cristy3ed852e2009-09-05 21:47:34 +0000163#endif
164
165#if defined(MAGICKCORE_XML_DELEGATE)
cristyb988fe72009-09-16 01:01:10 +0000166
cristy3ed852e2009-09-05 21:47:34 +0000167/*
168%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169% %
170% %
171% %
172% R e a d M S L I m a g e %
173% %
174% %
175% %
176%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177%
178% ReadMSLImage() reads a Magick Scripting Language file and returns it.
179% It allocates the memory necessary for the new Image structure and returns a
180% pointer to the new image.
181%
182% The format of the ReadMSLImage method is:
183%
184% Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
185%
186% A description of each parameter follows:
187%
188% o image_info: the image info.
189%
190% o exception: return any errors or warnings in this structure.
191%
cristy3ed852e2009-09-05 21:47:34 +0000192*/
193
194#if defined(__cplusplus) || defined(c_plusplus)
195extern "C" {
196#endif
197
cristy4fa36e42009-09-18 14:24:06 +0000198static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
199 ExceptionInfo *exception)
200{
201 char
202 key[MaxTextExtent];
203
204 ExceptionInfo
205 *sans_exception;
206
207 Image
208 *image;
209
210 ImageInfo
211 *read_info;
212
213 (void) FormatMagickString(key,MaxTextExtent,"cache:%s",path);
214 sans_exception=AcquireExceptionInfo();
215 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
216 sans_exception=DestroyExceptionInfo(sans_exception);
217 if (image != (Image *) NULL)
218 return(image);
219 read_info=CloneImageInfo(image_info);
220 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
221 image=ReadImage(read_info,exception);
222 read_info=DestroyImageInfo(read_info);
223 if (image != (Image *) NULL)
224 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
225 return(image);
226}
227
228static int IsPathDirectory(const char *path)
229{
230 MagickBooleanType
231 status;
232
233 struct stat
234 attributes;
235
236 if ((path == (const char *) NULL) || (*path == '\0'))
237 return(MagickFalse);
238 status=GetPathAttributes(path,&attributes);
239 if (status == MagickFalse)
240 return(-1);
241 if (S_ISDIR(attributes.st_mode) == 0)
242 return(0);
243 return(1);
244}
245
cristy3ed852e2009-09-05 21:47:34 +0000246static int MSLIsStandalone(void *context)
247{
248 MSLInfo
249 *msl_info;
250
251 /*
252 Is this document tagged standalone?
253 */
254 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.MSLIsStandalone()");
255 msl_info=(MSLInfo *) context;
256 return(msl_info->document->standalone == 1);
257}
258
259static int MSLHasInternalSubset(void *context)
260{
261 MSLInfo
262 *msl_info;
263
264 /*
265 Does this document has an internal subset?
266 */
267 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
268 " SAX.MSLHasInternalSubset()");
269 msl_info=(MSLInfo *) context;
270 return(msl_info->document->intSubset != NULL);
271}
272
273static int MSLHasExternalSubset(void *context)
274{
275 MSLInfo
276 *msl_info;
277
278 /*
279 Does this document has an external subset?
280 */
281 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
282 " SAX.MSLHasExternalSubset()");
283 msl_info=(MSLInfo *) context;
284 return(msl_info->document->extSubset != NULL);
285}
286
287static void MSLInternalSubset(void *context,const xmlChar *name,
288 const xmlChar *external_id,const xmlChar *system_id)
289{
290 MSLInfo
291 *msl_info;
292
293 /*
294 Does this document has an internal subset?
295 */
296 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
297 " SAX.internalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000298 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
299 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +0000300 msl_info=(MSLInfo *) context;
301 (void) xmlCreateIntSubset(msl_info->document,name,external_id,system_id);
302}
303
304static xmlParserInputPtr MSLResolveEntity(void *context,
305 const xmlChar *public_id,const xmlChar *system_id)
306{
307 MSLInfo
308 *msl_info;
309
310 xmlParserInputPtr
311 stream;
312
313 /*
314 Special entity resolver, better left to the parser, it has more
315 context than the application layer. The default behaviour is to
316 not resolve the entities, in that case the ENTITY_REF nodes are
317 built in the structure (and the parameter values).
318 */
319 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
320 " SAX.resolveEntity(%s, %s)",
cristyb988fe72009-09-16 01:01:10 +0000321 (public_id != (const xmlChar *) NULL ? (const char *) public_id : "none"),
322 (system_id != (const xmlChar *) NULL ? (const char *) system_id : "none"));
cristy3ed852e2009-09-05 21:47:34 +0000323 msl_info=(MSLInfo *) context;
324 stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
325 public_id,msl_info->parser);
326 return(stream);
327}
328
329static xmlEntityPtr MSLGetEntity(void *context,const xmlChar *name)
330{
331 MSLInfo
332 *msl_info;
333
334 /*
335 Get an entity by name.
336 */
337 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000338 " SAX.MSLGetEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000339 msl_info=(MSLInfo *) context;
340 return(xmlGetDocEntity(msl_info->document,name));
341}
342
343static xmlEntityPtr MSLGetParameterEntity(void *context,const xmlChar *name)
344{
345 MSLInfo
346 *msl_info;
347
348 /*
349 Get a parameter entity by name.
350 */
351 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000352 " SAX.getParameterEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000353 msl_info=(MSLInfo *) context;
354 return(xmlGetParameterEntity(msl_info->document,name));
355}
356
357static void MSLEntityDeclaration(void *context,const xmlChar *name,int type,
358 const xmlChar *public_id,const xmlChar *system_id,xmlChar *content)
359{
360 MSLInfo
361 *msl_info;
362
363 /*
364 An entity definition has been parsed.
365 */
366 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
367 " SAX.entityDecl(%s, %d, %s, %s, %s)",name,type,
cristyb988fe72009-09-16 01:01:10 +0000368 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
369 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
370 content);
cristy3ed852e2009-09-05 21:47:34 +0000371 msl_info=(MSLInfo *) context;
372 if (msl_info->parser->inSubset == 1)
373 (void) xmlAddDocEntity(msl_info->document,name,type,public_id,system_id,
374 content);
375 else
376 if (msl_info->parser->inSubset == 2)
377 (void) xmlAddDtdEntity(msl_info->document,name,type,public_id,system_id,
378 content);
379}
380
381static void MSLAttributeDeclaration(void *context,const xmlChar *element,
382 const xmlChar *name,int type,int value,const xmlChar *default_value,
383 xmlEnumerationPtr tree)
384{
385 MSLInfo
386 *msl_info;
387
388 xmlChar
389 *fullname,
390 *prefix;
391
392 xmlParserCtxtPtr
393 parser;
394
395 /*
396 An attribute definition has been parsed.
397 */
398 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
399 " SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",element,name,type,value,
400 default_value);
401 msl_info=(MSLInfo *) context;
402 fullname=(xmlChar *) NULL;
403 prefix=(xmlChar *) NULL;
404 parser=msl_info->parser;
405 fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
406 if (parser->inSubset == 1)
407 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->intSubset,
408 element,fullname,prefix,(xmlAttributeType) type,
409 (xmlAttributeDefault) value,default_value,tree);
410 else
411 if (parser->inSubset == 2)
412 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->extSubset,
413 element,fullname,prefix,(xmlAttributeType) type,
414 (xmlAttributeDefault) value,default_value,tree);
415 if (prefix != (xmlChar *) NULL)
416 xmlFree(prefix);
417 if (fullname != (xmlChar *) NULL)
418 xmlFree(fullname);
419}
420
421static void MSLElementDeclaration(void *context,const xmlChar *name,int type,
422 xmlElementContentPtr content)
423{
424 MSLInfo
425 *msl_info;
426
427 xmlParserCtxtPtr
428 parser;
429
430 /*
431 An element definition has been parsed.
432 */
433 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
434 " SAX.elementDecl(%s, %d, ...)",name,type);
435 msl_info=(MSLInfo *) context;
436 parser=msl_info->parser;
437 if (parser->inSubset == 1)
438 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->intSubset,
439 name,(xmlElementTypeVal) type,content);
440 else
441 if (parser->inSubset == 2)
442 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->extSubset,
443 name,(xmlElementTypeVal) type,content);
444}
445
446static void MSLNotationDeclaration(void *context,const xmlChar *name,
447 const xmlChar *public_id,const xmlChar *system_id)
448{
449 MSLInfo
450 *msl_info;
451
452 xmlParserCtxtPtr
453 parser;
454
455 /*
456 What to do when a notation declaration has been parsed.
457 */
458 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
459 " SAX.notationDecl(%s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000460 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
461 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none");
cristy3ed852e2009-09-05 21:47:34 +0000462 msl_info=(MSLInfo *) context;
463 parser=msl_info->parser;
464 if (parser->inSubset == 1)
465 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
466 name,public_id,system_id);
467 else
468 if (parser->inSubset == 2)
469 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
470 name,public_id,system_id);
471}
472
473static void MSLUnparsedEntityDeclaration(void *context,const xmlChar *name,
474 const xmlChar *public_id,const xmlChar *system_id,const xmlChar *notation)
475{
476 MSLInfo
477 *msl_info;
478
479 /*
480 What to do when an unparsed entity declaration is parsed.
481 */
482 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
483 " SAX.unparsedEntityDecl(%s, %s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000484 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
485 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
486 notation);
cristy3ed852e2009-09-05 21:47:34 +0000487 msl_info=(MSLInfo *) context;
488 (void) xmlAddDocEntity(msl_info->document,name,
489 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,public_id,system_id,notation);
490
491}
492
493static void MSLSetDocumentLocator(void *context,xmlSAXLocatorPtr location)
494{
495 MSLInfo
496 *msl_info;
497
498 /*
499 Receive the document locator at startup, actually xmlDefaultSAXLocator.
500 */
501 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
502 " SAX.setDocumentLocator()\n");
503 (void) location;
504 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +0000505 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +0000506}
507
508static void MSLStartDocument(void *context)
509{
510 MSLInfo
511 *msl_info;
512
513 xmlParserCtxtPtr
514 parser;
515
516 /*
517 Called when the document start being processed.
518 */
519 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
520 " SAX.startDocument()");
521 msl_info=(MSLInfo *) context;
522 parser=msl_info->parser;
523 msl_info->document=xmlNewDoc(parser->version);
524 if (msl_info->document == (xmlDocPtr) NULL)
525 return;
526 if (parser->encoding == NULL)
527 msl_info->document->encoding=NULL;
528 else
529 msl_info->document->encoding=xmlStrdup(parser->encoding);
530 msl_info->document->standalone=parser->standalone;
531}
532
533static void MSLEndDocument(void *context)
534{
535 MSLInfo
536 *msl_info;
537
538 /*
539 Called when the document end has been detected.
540 */
541 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endDocument()");
542 msl_info=(MSLInfo *) context;
543 if (msl_info->content != (char *) NULL)
544 msl_info->content=DestroyString(msl_info->content);
545}
546
547static void MSLPushImage(MSLInfo *msl_info,Image *image)
548{
cristybb503372010-05-27 20:51:26 +0000549 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000550 n;
551
552 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
553 assert(msl_info != (MSLInfo *) NULL);
554 msl_info->n++;
555 n=msl_info->n;
556 msl_info->image_info=(ImageInfo **) ResizeQuantumMemory(msl_info->image_info,
557 (n+1),sizeof(*msl_info->image_info));
558 msl_info->draw_info=(DrawInfo **) ResizeQuantumMemory(msl_info->draw_info,
559 (n+1),sizeof(*msl_info->draw_info));
560 msl_info->attributes=(Image **) ResizeQuantumMemory(msl_info->attributes,
561 (n+1),sizeof(*msl_info->attributes));
562 msl_info->image=(Image **) ResizeQuantumMemory(msl_info->image,(n+1),
563 sizeof(*msl_info->image));
564 if ((msl_info->image_info == (ImageInfo **) NULL) ||
565 (msl_info->draw_info == (DrawInfo **) NULL) ||
566 (msl_info->attributes == (Image **) NULL) ||
567 (msl_info->image == (Image **) NULL))
568 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
569 msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
570 msl_info->draw_info[n]=CloneDrawInfo(msl_info->image_info[n-1],
571 msl_info->draw_info[n-1]);
572 if (image == (Image *) NULL)
573 msl_info->attributes[n]=AcquireImage(msl_info->image_info[n]);
574 else
575 msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,&image->exception);
576 msl_info->image[n]=(Image *) image;
577 if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
578 (msl_info->attributes[n] == (Image *) NULL))
579 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
580 if (msl_info->number_groups != 0)
581 msl_info->group_info[msl_info->number_groups-1].numImages++;
582}
583
584static void MSLPopImage(MSLInfo *msl_info)
585{
586 if (msl_info->number_groups != 0)
587 return;
588 if (msl_info->image[msl_info->n] != (Image *) NULL)
589 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
590 msl_info->attributes[msl_info->n]=DestroyImage(
591 msl_info->attributes[msl_info->n]);
592 msl_info->image_info[msl_info->n]=DestroyImageInfo(
593 msl_info->image_info[msl_info->n]);
594 msl_info->n--;
595}
596
597static void MSLStartElement(void *context,const xmlChar *tag,
598 const xmlChar **attributes)
599{
600 AffineMatrix
601 affine,
602 current;
603
604 ChannelType
605 channel;
606
607 char
608 key[MaxTextExtent],
609 *value;
610
611 const char
612 *attribute,
613 *keyword;
614
615 double
616 angle;
617
618 DrawInfo
619 *draw_info;
620
621 ExceptionInfo
622 exception;
623
624 GeometryInfo
625 geometry_info;
626
627 Image
628 *image;
629
630 int
631 flags;
632
cristybb503372010-05-27 20:51:26 +0000633 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000634 option,
635 j,
636 n,
637 x,
638 y;
639
640 MSLInfo
641 *msl_info;
642
643 RectangleInfo
644 geometry;
645
cristybb503372010-05-27 20:51:26 +0000646 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000647 i;
648
cristybb503372010-05-27 20:51:26 +0000649 size_t
cristy3ed852e2009-09-05 21:47:34 +0000650 height,
651 width;
652
653 /*
654 Called when an opening tag has been processed.
655 */
656 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
657 " SAX.startElement(%s",tag);
658 GetExceptionInfo(&exception);
659 msl_info=(MSLInfo *) context;
660 n=msl_info->n;
661 keyword=(const char *) NULL;
662 value=(char *) NULL;
663 SetGeometryInfo(&geometry_info);
664 channel=DefaultChannels;
665 switch (*tag)
666 {
667 case 'A':
668 case 'a':
669 {
cristyb988fe72009-09-16 01:01:10 +0000670 if (LocaleCompare((const char *) tag,"add-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000671 {
672 Image
673 *noise_image;
674
675 NoiseType
676 noise;
677
678 /*
679 Add noise image.
680 */
681 if (msl_info->image[n] == (Image *) NULL)
682 {
cristyb988fe72009-09-16 01:01:10 +0000683 ThrowMSLException(OptionError,"NoImagesDefined",
684 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000685 break;
686 }
687 noise=UniformNoise;
688 if (attributes != (const xmlChar **) NULL)
689 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
690 {
691 keyword=(const char *) attributes[i++];
692 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +0000693 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +0000694 CloneString(&value,attribute);
695 switch (*keyword)
696 {
697 case 'C':
698 case 'c':
699 {
700 if (LocaleCompare(keyword,"channel") == 0)
701 {
702 option=ParseChannelOption(value);
703 if (option < 0)
704 ThrowMSLException(OptionError,"UnrecognizedChannelType",
705 value);
706 channel=(ChannelType) option;
707 break;
708 }
709 ThrowMSLException(OptionError,"UnrecognizedAttribute",
710 keyword);
711 break;
712 }
713 case 'N':
714 case 'n':
715 {
716 if (LocaleCompare(keyword,"noise") == 0)
717 {
cristy042ee782011-04-22 18:48:30 +0000718 option=ParseCommandOption(MagickNoiseOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000719 value);
720 if (option < 0)
721 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
722 value);
723 noise=(NoiseType) option;
724 break;
725 }
726 ThrowMSLException(OptionError,"UnrecognizedAttribute",
727 keyword);
728 break;
729 }
730 default:
731 {
732 ThrowMSLException(OptionError,"UnrecognizedAttribute",
733 keyword);
734 break;
735 }
736 }
737 }
738 noise_image=AddNoiseImageChannel(msl_info->image[n],channel,noise,
739 &msl_info->image[n]->exception);
740 if (noise_image == (Image *) NULL)
741 break;
742 msl_info->image[n]=DestroyImage(msl_info->image[n]);
743 msl_info->image[n]=noise_image;
744 break;
745 }
cristyb988fe72009-09-16 01:01:10 +0000746 if (LocaleCompare((const char *) tag,"annotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000747 {
748 char
749 text[MaxTextExtent];
750
751 /*
752 Annotate image.
753 */
754 if (msl_info->image[n] == (Image *) NULL)
755 {
cristyb988fe72009-09-16 01:01:10 +0000756 ThrowMSLException(OptionError,"NoImagesDefined",
757 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000758 break;
759 }
760 draw_info=CloneDrawInfo(msl_info->image_info[n],
761 msl_info->draw_info[n]);
762 angle=0.0;
763 current=draw_info->affine;
764 GetAffineMatrix(&affine);
765 if (attributes != (const xmlChar **) NULL)
766 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
767 {
768 keyword=(const char *) attributes[i++];
769 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +0000770 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +0000771 CloneString(&value,attribute);
772 switch (*keyword)
773 {
774 case 'A':
775 case 'a':
776 {
777 if (LocaleCompare(keyword,"affine") == 0)
778 {
779 char
780 *p;
781
782 p=value;
783 draw_info->affine.sx=strtod(p,&p);
784 if (*p ==',')
785 p++;
786 draw_info->affine.rx=strtod(p,&p);
787 if (*p ==',')
788 p++;
789 draw_info->affine.ry=strtod(p,&p);
790 if (*p ==',')
791 p++;
792 draw_info->affine.sy=strtod(p,&p);
793 if (*p ==',')
794 p++;
795 draw_info->affine.tx=strtod(p,&p);
796 if (*p ==',')
797 p++;
798 draw_info->affine.ty=strtod(p,&p);
799 break;
800 }
801 if (LocaleCompare(keyword,"align") == 0)
802 {
cristy042ee782011-04-22 18:48:30 +0000803 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000804 value);
805 if (option < 0)
806 ThrowMSLException(OptionError,"UnrecognizedAlignType",
807 value);
808 draw_info->align=(AlignType) option;
809 break;
810 }
811 if (LocaleCompare(keyword,"antialias") == 0)
812 {
cristy042ee782011-04-22 18:48:30 +0000813 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000814 value);
815 if (option < 0)
816 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
817 value);
818 draw_info->stroke_antialias=(MagickBooleanType) option;
819 draw_info->text_antialias=(MagickBooleanType) option;
820 break;
821 }
822 ThrowMSLException(OptionError,"UnrecognizedAttribute",
823 keyword);
824 break;
825 }
826 case 'D':
827 case 'd':
828 {
829 if (LocaleCompare(keyword,"density") == 0)
830 {
831 CloneString(&draw_info->density,value);
832 break;
833 }
834 ThrowMSLException(OptionError,"UnrecognizedAttribute",
835 keyword);
836 break;
837 }
838 case 'E':
839 case 'e':
840 {
841 if (LocaleCompare(keyword,"encoding") == 0)
842 {
843 CloneString(&draw_info->encoding,value);
844 break;
845 }
846 ThrowMSLException(OptionError,"UnrecognizedAttribute",
847 keyword);
848 break;
849 }
850 case 'F':
851 case 'f':
852 {
853 if (LocaleCompare(keyword, "fill") == 0)
854 {
855 (void) QueryColorDatabase(value,&draw_info->fill,
856 &exception);
857 break;
858 }
859 if (LocaleCompare(keyword,"family") == 0)
860 {
861 CloneString(&draw_info->family,value);
862 break;
863 }
864 if (LocaleCompare(keyword,"font") == 0)
865 {
866 CloneString(&draw_info->font,value);
867 break;
868 }
869 ThrowMSLException(OptionError,"UnrecognizedAttribute",
870 keyword);
871 break;
872 }
873 case 'G':
874 case 'g':
875 {
876 if (LocaleCompare(keyword,"geometry") == 0)
877 {
878 flags=ParsePageGeometry(msl_info->image[n],value,
879 &geometry,&exception);
880 if ((flags & HeightValue) == 0)
881 geometry.height=geometry.width;
882 break;
883 }
884 if (LocaleCompare(keyword,"gravity") == 0)
885 {
cristy042ee782011-04-22 18:48:30 +0000886 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000887 value);
888 if (option < 0)
889 ThrowMSLException(OptionError,"UnrecognizedGravityType",
890 value);
891 draw_info->gravity=(GravityType) option;
892 break;
893 }
894 ThrowMSLException(OptionError,"UnrecognizedAttribute",
895 keyword);
896 break;
897 }
898 case 'P':
899 case 'p':
900 {
901 if (LocaleCompare(keyword,"pointsize") == 0)
902 {
cristyf2f27272009-12-17 14:48:46 +0000903 draw_info->pointsize=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +0000904 break;
905 }
906 ThrowMSLException(OptionError,"UnrecognizedAttribute",
907 keyword);
908 break;
909 }
910 case 'R':
911 case 'r':
912 {
913 if (LocaleCompare(keyword,"rotate") == 0)
914 {
cristyf2f27272009-12-17 14:48:46 +0000915 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +0000916 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
917 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
918 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
919 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
920 break;
921 }
922 ThrowMSLException(OptionError,"UnrecognizedAttribute",
923 keyword);
924 break;
925 }
926 case 'S':
927 case 's':
928 {
929 if (LocaleCompare(keyword,"scale") == 0)
930 {
931 flags=ParseGeometry(value,&geometry_info);
932 if ((flags & SigmaValue) == 0)
933 geometry_info.sigma=1.0;
934 affine.sx=geometry_info.rho;
935 affine.sy=geometry_info.sigma;
936 break;
937 }
938 if (LocaleCompare(keyword,"skewX") == 0)
939 {
cristyf2f27272009-12-17 14:48:46 +0000940 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +0000941 affine.ry=tan(DegreesToRadians(fmod((double) angle,
942 360.0)));
943 break;
944 }
945 if (LocaleCompare(keyword,"skewY") == 0)
946 {
cristyf2f27272009-12-17 14:48:46 +0000947 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +0000948 affine.rx=tan(DegreesToRadians(fmod((double) angle,
949 360.0)));
950 break;
951 }
952 if (LocaleCompare(keyword,"stretch") == 0)
953 {
cristy042ee782011-04-22 18:48:30 +0000954 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000955 value);
956 if (option < 0)
957 ThrowMSLException(OptionError,"UnrecognizedStretchType",
958 value);
959 draw_info->stretch=(StretchType) option;
960 break;
961 }
962 if (LocaleCompare(keyword, "stroke") == 0)
963 {
964 (void) QueryColorDatabase(value,&draw_info->stroke,
965 &exception);
966 break;
967 }
968 if (LocaleCompare(keyword,"strokewidth") == 0)
969 {
cristyf2f27272009-12-17 14:48:46 +0000970 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000971 break;
972 }
973 if (LocaleCompare(keyword,"style") == 0)
974 {
cristy042ee782011-04-22 18:48:30 +0000975 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000976 value);
977 if (option < 0)
978 ThrowMSLException(OptionError,"UnrecognizedStyleType",
979 value);
980 draw_info->style=(StyleType) option;
981 break;
982 }
983 ThrowMSLException(OptionError,"UnrecognizedAttribute",
984 keyword);
985 break;
986 }
987 case 'T':
988 case 't':
989 {
990 if (LocaleCompare(keyword,"text") == 0)
991 {
992 CloneString(&draw_info->text,value);
993 break;
994 }
995 if (LocaleCompare(keyword,"translate") == 0)
996 {
997 flags=ParseGeometry(value,&geometry_info);
998 if ((flags & SigmaValue) == 0)
999 geometry_info.sigma=1.0;
1000 affine.tx=geometry_info.rho;
1001 affine.ty=geometry_info.sigma;
1002 break;
1003 }
1004 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1005 keyword);
1006 break;
1007 }
1008 case 'U':
1009 case 'u':
1010 {
1011 if (LocaleCompare(keyword, "undercolor") == 0)
1012 {
1013 (void) QueryColorDatabase(value,&draw_info->undercolor,
1014 &exception);
1015 break;
1016 }
1017 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1018 keyword);
1019 break;
1020 }
1021 case 'W':
1022 case 'w':
1023 {
1024 if (LocaleCompare(keyword,"weight") == 0)
1025 {
cristyf2f27272009-12-17 14:48:46 +00001026 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001027 break;
1028 }
1029 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1030 keyword);
1031 break;
1032 }
1033 case 'X':
1034 case 'x':
1035 {
1036 if (LocaleCompare(keyword,"x") == 0)
1037 {
cristyf2f27272009-12-17 14:48:46 +00001038 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001039 break;
1040 }
1041 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1042 keyword);
1043 break;
1044 }
1045 case 'Y':
1046 case 'y':
1047 {
1048 if (LocaleCompare(keyword,"y") == 0)
1049 {
cristyf2f27272009-12-17 14:48:46 +00001050 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001051 break;
1052 }
1053 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1054 keyword);
1055 break;
1056 }
1057 default:
1058 {
1059 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1060 keyword);
1061 break;
1062 }
1063 }
1064 }
cristye8c25f92010-06-03 00:53:06 +00001065 (void) FormatMagickString(text,MaxTextExtent,
1066 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
1067 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00001068 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00001069 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
1070 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
1071 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
1072 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
1073 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
1074 affine.tx;
1075 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
1076 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00001077 (void) AnnotateImage(msl_info->image[n],draw_info);
1078 draw_info=DestroyDrawInfo(draw_info);
1079 break;
1080 }
cristyb988fe72009-09-16 01:01:10 +00001081 if (LocaleCompare((const char *) tag,"append") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001082 {
1083 Image
1084 *append_image;
1085
1086 MagickBooleanType
1087 stack;
cristyb988fe72009-09-16 01:01:10 +00001088
cristy3ed852e2009-09-05 21:47:34 +00001089 if (msl_info->image[n] == (Image *) NULL)
1090 {
cristyb988fe72009-09-16 01:01:10 +00001091 ThrowMSLException(OptionError,"NoImagesDefined",
1092 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001093 break;
1094 }
1095 stack=MagickFalse;
1096 if (attributes != (const xmlChar **) NULL)
1097 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1098 {
1099 keyword=(const char *) attributes[i++];
1100 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001101 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001102 CloneString(&value,attribute);
1103 switch (*keyword)
1104 {
1105 case 'S':
1106 case 's':
1107 {
1108 if (LocaleCompare(keyword,"stack") == 0)
1109 {
cristy042ee782011-04-22 18:48:30 +00001110 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001111 value);
1112 if (option < 0)
1113 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1114 value);
1115 stack=(MagickBooleanType) option;
1116 break;
1117 }
1118 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1119 keyword);
1120 break;
1121 }
1122 default:
1123 {
1124 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1125 keyword);
1126 break;
1127 }
1128 }
1129 }
1130 append_image=AppendImages(msl_info->image[n],stack,
1131 &msl_info->image[n]->exception);
1132 if (append_image == (Image *) NULL)
1133 break;
1134 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1135 msl_info->image[n]=append_image;
1136 break;
1137 }
1138 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1139 break;
1140 }
1141 case 'B':
1142 case 'b':
1143 {
cristyb988fe72009-09-16 01:01:10 +00001144 if (LocaleCompare((const char *) tag,"blur") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001145 {
1146 Image
1147 *blur_image;
1148
1149 /*
1150 Blur image.
1151 */
1152 if (msl_info->image[n] == (Image *) NULL)
1153 {
cristyb988fe72009-09-16 01:01:10 +00001154 ThrowMSLException(OptionError,"NoImagesDefined",
1155 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001156 break;
1157 }
1158 if (attributes != (const xmlChar **) NULL)
1159 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1160 {
1161 keyword=(const char *) attributes[i++];
1162 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001163 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001164 CloneString(&value,attribute);
1165 switch (*keyword)
1166 {
1167 case 'C':
1168 case 'c':
1169 {
1170 if (LocaleCompare(keyword,"channel") == 0)
1171 {
1172 option=ParseChannelOption(value);
1173 if (option < 0)
1174 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1175 value);
1176 channel=(ChannelType) option;
1177 break;
1178 }
1179 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1180 keyword);
1181 break;
1182 }
1183 case 'G':
1184 case 'g':
1185 {
1186 if (LocaleCompare(keyword,"geometry") == 0)
1187 {
1188 flags=ParseGeometry(value,&geometry_info);
1189 if ((flags & SigmaValue) == 0)
1190 geometry_info.sigma=1.0;
1191 break;
1192 }
1193 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1194 keyword);
1195 break;
1196 }
1197 case 'R':
1198 case 'r':
1199 {
1200 if (LocaleCompare(keyword,"radius") == 0)
1201 {
cristyf2f27272009-12-17 14:48:46 +00001202 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00001203 break;
1204 }
1205 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1206 keyword);
1207 break;
1208 }
1209 case 'S':
1210 case 's':
1211 {
1212 if (LocaleCompare(keyword,"sigma") == 0)
1213 {
cristyf2f27272009-12-17 14:48:46 +00001214 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001215 break;
1216 }
1217 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1218 keyword);
1219 break;
1220 }
1221 default:
1222 {
1223 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1224 keyword);
1225 break;
1226 }
1227 }
1228 }
1229 blur_image=BlurImageChannel(msl_info->image[n],channel,
1230 geometry_info.rho,geometry_info.sigma,
1231 &msl_info->image[n]->exception);
1232 if (blur_image == (Image *) NULL)
1233 break;
1234 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1235 msl_info->image[n]=blur_image;
1236 break;
1237 }
cristyb988fe72009-09-16 01:01:10 +00001238 if (LocaleCompare((const char *) tag,"border") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001239 {
1240 Image
1241 *border_image;
1242
1243 /*
1244 Border image.
1245 */
1246 if (msl_info->image[n] == (Image *) NULL)
1247 {
cristyb988fe72009-09-16 01:01:10 +00001248 ThrowMSLException(OptionError,"NoImagesDefined",
1249 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001250 break;
1251 }
1252 SetGeometry(msl_info->image[n],&geometry);
1253 if (attributes != (const xmlChar **) NULL)
1254 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1255 {
1256 keyword=(const char *) attributes[i++];
1257 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001258 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001259 CloneString(&value,attribute);
1260 switch (*keyword)
1261 {
1262 case 'C':
1263 case 'c':
1264 {
1265 if (LocaleCompare(keyword,"compose") == 0)
1266 {
cristy042ee782011-04-22 18:48:30 +00001267 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001268 value);
1269 if (option < 0)
1270 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1271 value);
1272 msl_info->image[n]->compose=(CompositeOperator) option;
1273 break;
1274 }
1275 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1276 keyword);
1277 break;
1278 }
1279 case 'F':
1280 case 'f':
1281 {
1282 if (LocaleCompare(keyword, "fill") == 0)
1283 {
1284 (void) QueryColorDatabase(value,
1285 &msl_info->image[n]->border_color,&exception);
1286 break;
1287 }
1288 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1289 keyword);
1290 break;
1291 }
1292 case 'G':
1293 case 'g':
1294 {
1295 if (LocaleCompare(keyword,"geometry") == 0)
1296 {
1297 flags=ParsePageGeometry(msl_info->image[n],value,
1298 &geometry,&exception);
1299 if ((flags & HeightValue) == 0)
1300 geometry.height=geometry.width;
1301 break;
1302 }
1303 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1304 keyword);
1305 break;
1306 }
1307 case 'H':
1308 case 'h':
1309 {
1310 if (LocaleCompare(keyword,"height") == 0)
1311 {
cristyf2f27272009-12-17 14:48:46 +00001312 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001313 break;
1314 }
1315 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1316 keyword);
1317 break;
1318 }
1319 case 'W':
1320 case 'w':
1321 {
1322 if (LocaleCompare(keyword,"width") == 0)
1323 {
cristyf2f27272009-12-17 14:48:46 +00001324 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001325 break;
1326 }
1327 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1328 keyword);
1329 break;
1330 }
1331 default:
1332 {
1333 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1334 keyword);
1335 break;
1336 }
1337 }
1338 }
1339 border_image=BorderImage(msl_info->image[n],&geometry,
1340 &msl_info->image[n]->exception);
1341 if (border_image == (Image *) NULL)
1342 break;
1343 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1344 msl_info->image[n]=border_image;
1345 break;
1346 }
1347 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1348 }
1349 case 'C':
1350 case 'c':
1351 {
cristyb988fe72009-09-16 01:01:10 +00001352 if (LocaleCompare((const char *) tag,"colorize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001353 {
1354 char
1355 opacity[MaxTextExtent];
1356
1357 Image
1358 *colorize_image;
1359
1360 PixelPacket
1361 target;
1362
1363 /*
1364 Add noise image.
1365 */
1366 if (msl_info->image[n] == (Image *) NULL)
1367 {
cristyb988fe72009-09-16 01:01:10 +00001368 ThrowMSLException(OptionError,"NoImagesDefined",
1369 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001370 break;
1371 }
1372 target=msl_info->image[n]->background_color;
1373 (void) CopyMagickString(opacity,"100",MaxTextExtent);
1374 if (attributes != (const xmlChar **) NULL)
1375 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1376 {
1377 keyword=(const char *) attributes[i++];
1378 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001379 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001380 CloneString(&value,attribute);
1381 switch (*keyword)
1382 {
1383 case 'F':
1384 case 'f':
1385 {
1386 if (LocaleCompare(keyword,"fill") == 0)
1387 {
1388 (void) QueryColorDatabase(value,&target,
1389 &msl_info->image[n]->exception);
1390 break;
1391 }
1392 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1393 keyword);
1394 break;
1395 }
1396 case 'O':
1397 case 'o':
1398 {
1399 if (LocaleCompare(keyword,"opacity") == 0)
1400 {
1401 (void) CopyMagickString(opacity,value,MaxTextExtent);
1402 break;
1403 }
1404 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1405 keyword);
1406 break;
1407 }
1408 default:
1409 {
1410 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1411 keyword);
1412 break;
1413 }
1414 }
1415 }
1416 colorize_image=ColorizeImage(msl_info->image[n],opacity,target,
1417 &msl_info->image[n]->exception);
1418 if (colorize_image == (Image *) NULL)
1419 break;
1420 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1421 msl_info->image[n]=colorize_image;
1422 break;
1423 }
cristyb988fe72009-09-16 01:01:10 +00001424 if (LocaleCompare((const char *) tag, "charcoal") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001425 {
1426 double radius = 0.0,
1427 sigma = 1.0;
1428
1429 if (msl_info->image[n] == (Image *) NULL)
1430 {
cristyb988fe72009-09-16 01:01:10 +00001431 ThrowMSLException(OptionError,"NoImagesDefined",
1432 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001433 break;
1434 }
1435 /*
1436 NOTE: charcoal can have no attributes, since we use all the defaults!
1437 */
1438 if (attributes != (const xmlChar **) NULL)
1439 {
1440 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1441 {
1442 keyword=(const char *) attributes[i++];
1443 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001444 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00001445 switch (*keyword)
1446 {
1447 case 'R':
1448 case 'r':
1449 {
1450 if (LocaleCompare(keyword, "radius") == 0)
1451 {
cristyf2f27272009-12-17 14:48:46 +00001452 radius = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00001453 break;
1454 }
1455 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1456 break;
1457 }
1458 case 'S':
1459 case 's':
1460 {
1461 if (LocaleCompare(keyword,"sigma") == 0)
1462 {
cristyf2f27272009-12-17 14:48:46 +00001463 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00001464 break;
1465 }
1466 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1467 break;
1468 }
1469 default:
1470 {
1471 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1472 break;
1473 }
1474 }
1475 }
1476 }
1477
1478 /*
1479 charcoal image.
1480 */
1481 {
1482 Image
1483 *newImage;
1484
1485 newImage=CharcoalImage(msl_info->image[n],radius,sigma,
1486 &msl_info->image[n]->exception);
1487 if (newImage == (Image *) NULL)
1488 break;
1489 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1490 msl_info->image[n]=newImage;
1491 break;
1492 }
1493 }
cristyb988fe72009-09-16 01:01:10 +00001494 if (LocaleCompare((const char *) tag,"chop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001495 {
1496 Image
1497 *chop_image;
1498
1499 /*
1500 Chop image.
1501 */
1502 if (msl_info->image[n] == (Image *) NULL)
1503 {
cristyb988fe72009-09-16 01:01:10 +00001504 ThrowMSLException(OptionError,"NoImagesDefined",
1505 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001506 break;
1507 }
1508 SetGeometry(msl_info->image[n],&geometry);
1509 if (attributes != (const xmlChar **) NULL)
1510 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1511 {
1512 keyword=(const char *) attributes[i++];
1513 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001514 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001515 CloneString(&value,attribute);
1516 switch (*keyword)
1517 {
1518 case 'G':
1519 case 'g':
1520 {
1521 if (LocaleCompare(keyword,"geometry") == 0)
1522 {
1523 flags=ParsePageGeometry(msl_info->image[n],value,
1524 &geometry,&exception);
1525 if ((flags & HeightValue) == 0)
1526 geometry.height=geometry.width;
1527 break;
1528 }
1529 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1530 keyword);
1531 break;
1532 }
1533 case 'H':
1534 case 'h':
1535 {
1536 if (LocaleCompare(keyword,"height") == 0)
1537 {
cristyf2f27272009-12-17 14:48:46 +00001538 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001539 break;
1540 }
1541 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1542 keyword);
1543 break;
1544 }
1545 case 'W':
1546 case 'w':
1547 {
1548 if (LocaleCompare(keyword,"width") == 0)
1549 {
cristyf2f27272009-12-17 14:48:46 +00001550 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001551 break;
1552 }
1553 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1554 keyword);
1555 break;
1556 }
1557 case 'X':
1558 case 'x':
1559 {
1560 if (LocaleCompare(keyword,"x") == 0)
1561 {
cristyf2f27272009-12-17 14:48:46 +00001562 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001563 break;
1564 }
1565 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1566 keyword);
1567 break;
1568 }
1569 case 'Y':
1570 case 'y':
1571 {
1572 if (LocaleCompare(keyword,"y") == 0)
1573 {
cristyf2f27272009-12-17 14:48:46 +00001574 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001575 break;
1576 }
1577 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1578 keyword);
1579 break;
1580 }
1581 default:
1582 {
1583 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1584 keyword);
1585 break;
1586 }
1587 }
1588 }
1589 chop_image=ChopImage(msl_info->image[n],&geometry,
1590 &msl_info->image[n]->exception);
1591 if (chop_image == (Image *) NULL)
1592 break;
1593 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1594 msl_info->image[n]=chop_image;
1595 break;
1596 }
cristyb988fe72009-09-16 01:01:10 +00001597 if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001598 {
1599 PaintMethod
1600 paint_method;
1601
1602 MagickPixelPacket
1603 target;
1604
1605 /*
1606 Color floodfill image.
1607 */
1608 if (msl_info->image[n] == (Image *) NULL)
1609 {
cristyb988fe72009-09-16 01:01:10 +00001610 ThrowMSLException(OptionError,"NoImagesDefined",
1611 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001612 break;
1613 }
1614 draw_info=CloneDrawInfo(msl_info->image_info[n],
1615 msl_info->draw_info[n]);
1616 SetGeometry(msl_info->image[n],&geometry);
1617 paint_method=FloodfillMethod;
1618 if (attributes != (const xmlChar **) NULL)
1619 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1620 {
1621 keyword=(const char *) attributes[i++];
1622 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001623 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001624 CloneString(&value,attribute);
1625 switch (*keyword)
1626 {
1627 case 'B':
1628 case 'b':
1629 {
1630 if (LocaleCompare(keyword,"bordercolor") == 0)
1631 {
1632 (void) QueryMagickColor(value,&target,&exception);
1633 paint_method=FillToBorderMethod;
1634 break;
1635 }
1636 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1637 keyword);
1638 break;
1639 }
1640 case 'F':
1641 case 'f':
1642 {
1643 if (LocaleCompare(keyword,"fill") == 0)
1644 {
1645 (void) QueryColorDatabase(value,&draw_info->fill,
1646 &exception);
1647 break;
1648 }
1649 if (LocaleCompare(keyword,"fuzz") == 0)
1650 {
cristyf2f27272009-12-17 14:48:46 +00001651 msl_info->image[n]->fuzz=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00001652 break;
1653 }
1654 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1655 keyword);
1656 break;
1657 }
1658 case 'G':
1659 case 'g':
1660 {
1661 if (LocaleCompare(keyword,"geometry") == 0)
1662 {
1663 flags=ParsePageGeometry(msl_info->image[n],value,
1664 &geometry,&exception);
1665 if ((flags & HeightValue) == 0)
1666 geometry.height=geometry.width;
1667 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1668 geometry.x,geometry.y,&target,&exception);
1669 break;
1670 }
1671 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1672 keyword);
1673 break;
1674 }
1675 case 'X':
1676 case 'x':
1677 {
1678 if (LocaleCompare(keyword,"x") == 0)
1679 {
cristyf2f27272009-12-17 14:48:46 +00001680 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001681 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1682 geometry.x,geometry.y,&target,&exception);
1683 break;
1684 }
1685 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1686 keyword);
1687 break;
1688 }
1689 case 'Y':
1690 case 'y':
1691 {
1692 if (LocaleCompare(keyword,"y") == 0)
1693 {
cristyf2f27272009-12-17 14:48:46 +00001694 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001695 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1696 geometry.x,geometry.y,&target,&exception);
1697 break;
1698 }
1699 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1700 keyword);
1701 break;
1702 }
1703 default:
1704 {
1705 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1706 keyword);
1707 break;
1708 }
1709 }
1710 }
1711 (void) FloodfillPaintImage(msl_info->image[n],DefaultChannels,
1712 draw_info,&target,geometry.x,geometry.y,
1713 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
1714 draw_info=DestroyDrawInfo(draw_info);
1715 break;
1716 }
cristyb988fe72009-09-16 01:01:10 +00001717 if (LocaleCompare((const char *) tag,"comment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001718 break;
cristyb988fe72009-09-16 01:01:10 +00001719 if (LocaleCompare((const char *) tag,"composite") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001720 {
1721 char
1722 composite_geometry[MaxTextExtent];
1723
1724 CompositeOperator
1725 compose;
1726
1727 Image
1728 *composite_image,
1729 *rotate_image;
1730
1731 PixelPacket
1732 target;
1733
1734 /*
1735 Composite image.
1736 */
1737 if (msl_info->image[n] == (Image *) NULL)
1738 {
cristyb988fe72009-09-16 01:01:10 +00001739 ThrowMSLException(OptionError,"NoImagesDefined",
1740 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001741 break;
1742 }
1743 composite_image=NewImageList();
1744 compose=OverCompositeOp;
1745 if (attributes != (const xmlChar **) NULL)
1746 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1747 {
1748 keyword=(const char *) attributes[i++];
1749 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001750 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001751 CloneString(&value,attribute);
1752 switch (*keyword)
1753 {
1754 case 'C':
1755 case 'c':
1756 {
1757 if (LocaleCompare(keyword,"compose") == 0)
1758 {
cristy042ee782011-04-22 18:48:30 +00001759 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001760 value);
1761 if (option < 0)
1762 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1763 value);
1764 compose=(CompositeOperator) option;
1765 break;
1766 }
1767 break;
1768 }
1769 case 'I':
1770 case 'i':
1771 {
1772 if (LocaleCompare(keyword,"image") == 0)
1773 for (j=0; j < msl_info->n; j++)
1774 {
1775 const char
1776 *attribute;
cristyb988fe72009-09-16 01:01:10 +00001777
cristy3ed852e2009-09-05 21:47:34 +00001778 attribute=GetImageProperty(msl_info->attributes[j],"id");
1779 if ((attribute != (const char *) NULL) &&
1780 (LocaleCompare(attribute,value) == 0))
1781 {
1782 composite_image=CloneImage(msl_info->image[j],0,0,
1783 MagickFalse,&exception);
1784 break;
1785 }
1786 }
1787 break;
1788 }
1789 default:
1790 break;
1791 }
1792 }
1793 if (composite_image == (Image *) NULL)
1794 break;
1795 rotate_image=NewImageList();
1796 SetGeometry(msl_info->image[n],&geometry);
1797 if (attributes != (const xmlChar **) NULL)
1798 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1799 {
1800 keyword=(const char *) attributes[i++];
1801 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001802 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001803 CloneString(&value,attribute);
1804 switch (*keyword)
1805 {
1806 case 'B':
1807 case 'b':
1808 {
1809 if (LocaleCompare(keyword,"blend") == 0)
1810 {
1811 (void) SetImageArtifact(composite_image,
1812 "compose:args",value);
1813 break;
1814 }
1815 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1816 keyword);
1817 break;
1818 }
1819 case 'C':
1820 case 'c':
1821 {
1822 if (LocaleCompare(keyword,"channel") == 0)
1823 {
1824 option=ParseChannelOption(value);
1825 if (option < 0)
1826 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1827 value);
1828 channel=(ChannelType) option;
1829 break;
1830 }
1831 if (LocaleCompare(keyword, "color") == 0)
1832 {
1833 (void) QueryColorDatabase(value,
1834 &composite_image->background_color,&exception);
1835 break;
1836 }
1837 if (LocaleCompare(keyword,"compose") == 0)
1838 break;
1839 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1840 keyword);
1841 break;
1842 }
1843 case 'G':
1844 case 'g':
1845 {
1846 if (LocaleCompare(keyword,"geometry") == 0)
1847 {
1848 flags=ParsePageGeometry(msl_info->image[n],value,
1849 &geometry,&exception);
1850 if ((flags & HeightValue) == 0)
1851 geometry.height=geometry.width;
1852 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
1853 geometry.y,&target,&exception);
1854 break;
1855 }
1856 if (LocaleCompare(keyword,"gravity") == 0)
1857 {
cristy042ee782011-04-22 18:48:30 +00001858 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001859 value);
1860 if (option < 0)
1861 ThrowMSLException(OptionError,"UnrecognizedGravityType",
1862 value);
1863 msl_info->image[n]->gravity=(GravityType) option;
1864 break;
1865 }
1866 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1867 keyword);
1868 break;
1869 }
1870 case 'I':
1871 case 'i':
1872 {
1873 if (LocaleCompare(keyword,"image") == 0)
1874 break;
1875 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1876 keyword);
1877 break;
1878 }
1879 case 'M':
1880 case 'm':
1881 {
1882 if (LocaleCompare(keyword,"mask") == 0)
1883 for (j=0; j < msl_info->n; j++)
1884 {
1885 const char
1886 *attribute;
1887
1888 attribute=GetImageProperty(msl_info->attributes[j],"id");
1889 if ((attribute != (const char *) NULL) &&
1890 (LocaleCompare(value,value) == 0))
1891 {
1892 SetImageType(composite_image,TrueColorMatteType);
1893 (void) CompositeImage(composite_image,
1894 CopyOpacityCompositeOp,msl_info->image[j],0,0);
1895 break;
1896 }
1897 }
1898 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1899 keyword);
1900 break;
1901 }
1902 case 'O':
1903 case 'o':
1904 {
1905 if (LocaleCompare(keyword,"opacity") == 0)
1906 {
cristybb503372010-05-27 20:51:26 +00001907 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001908 opacity,
1909 y;
cristyb988fe72009-09-16 01:01:10 +00001910
cristybb503372010-05-27 20:51:26 +00001911 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001912 x;
cristyb988fe72009-09-16 01:01:10 +00001913
cristy3ed852e2009-09-05 21:47:34 +00001914 register PixelPacket
1915 *q;
cristyb988fe72009-09-16 01:01:10 +00001916
cristy3ed852e2009-09-05 21:47:34 +00001917 CacheView
1918 *composite_view;
1919
cristyf2f27272009-12-17 14:48:46 +00001920 opacity=QuantumRange-StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001921 if (compose != DissolveCompositeOp)
1922 {
cristyb988fe72009-09-16 01:01:10 +00001923 (void) SetImageOpacity(composite_image,(Quantum)
1924 opacity);
cristy3ed852e2009-09-05 21:47:34 +00001925 break;
1926 }
1927 (void) SetImageArtifact(msl_info->image[n],
1928 "compose:args",value);
1929 if (composite_image->matte != MagickTrue)
1930 (void) SetImageOpacity(composite_image,OpaqueOpacity);
1931 composite_view=AcquireCacheView(composite_image);
cristybb503372010-05-27 20:51:26 +00001932 for (y=0; y < (ssize_t) composite_image->rows ; y++)
cristyb988fe72009-09-16 01:01:10 +00001933 {
cristybb503372010-05-27 20:51:26 +00001934 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00001935 composite_image->columns,1,&exception);
cristybb503372010-05-27 20:51:26 +00001936 for (x=0; x < (ssize_t) composite_image->columns; x++)
cristyb988fe72009-09-16 01:01:10 +00001937 {
cristy3ed852e2009-09-05 21:47:34 +00001938 if (q->opacity == OpaqueOpacity)
cristyce70c172010-01-07 17:15:30 +00001939 q->opacity=ClampToQuantum(opacity);
cristy3ed852e2009-09-05 21:47:34 +00001940 q++;
1941 }
1942 if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1943 break;
1944 }
1945 composite_view=DestroyCacheView(composite_view);
1946 break;
1947 }
1948 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1949 keyword);
1950 break;
1951 }
1952 case 'R':
1953 case 'r':
1954 {
1955 if (LocaleCompare(keyword,"rotate") == 0)
1956 {
cristyf2f27272009-12-17 14:48:46 +00001957 rotate_image=RotateImage(composite_image,StringToDouble(value),
cristy3ed852e2009-09-05 21:47:34 +00001958 &exception);
1959 break;
1960 }
1961 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1962 keyword);
1963 break;
1964 }
1965 case 'T':
1966 case 't':
1967 {
1968 if (LocaleCompare(keyword,"tile") == 0)
1969 {
1970 MagickBooleanType
1971 tile;
1972
cristy042ee782011-04-22 18:48:30 +00001973 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001974 value);
1975 if (option < 0)
1976 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1977 value);
1978 tile=(MagickBooleanType) option;
cristyda16f162011-02-19 23:52:17 +00001979 (void) tile;
cristy3ed852e2009-09-05 21:47:34 +00001980 if (rotate_image != (Image *) NULL)
1981 (void) SetImageArtifact(rotate_image,
1982 "compose:outside-overlay","false");
1983 else
1984 (void) SetImageArtifact(composite_image,
1985 "compose:outside-overlay","false");
1986 image=msl_info->image[n];
1987 height=composite_image->rows;
1988 width=composite_image->columns;
cristyeaedf062010-05-29 22:36:02 +00001989 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
1990 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
cristy3ed852e2009-09-05 21:47:34 +00001991 {
1992 if (rotate_image != (Image *) NULL)
1993 (void) CompositeImage(image,compose,rotate_image,
1994 x,y);
1995 else
1996 (void) CompositeImage(image,compose,
1997 composite_image,x,y);
1998 }
1999 if (rotate_image != (Image *) NULL)
2000 rotate_image=DestroyImage(rotate_image);
2001 break;
2002 }
2003 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2004 keyword);
2005 break;
2006 }
2007 case 'X':
2008 case 'x':
2009 {
2010 if (LocaleCompare(keyword,"x") == 0)
2011 {
cristyf2f27272009-12-17 14:48:46 +00002012 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002013 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2014 geometry.y,&target,&exception);
2015 break;
2016 }
2017 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2018 keyword);
2019 break;
2020 }
2021 case 'Y':
2022 case 'y':
2023 {
2024 if (LocaleCompare(keyword,"y") == 0)
2025 {
cristyf2f27272009-12-17 14:48:46 +00002026 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002027 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2028 geometry.y,&target,&exception);
2029 break;
2030 }
2031 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2032 keyword);
2033 break;
2034 }
2035 default:
2036 {
2037 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2038 keyword);
2039 break;
2040 }
2041 }
2042 }
2043 image=msl_info->image[n];
2044 (void) FormatMagickString(composite_geometry,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002045 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2046 (double) composite_image->rows,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00002047 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002048 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2049 &exception);
2050 if (rotate_image == (Image *) NULL)
2051 CompositeImageChannel(image,channel,compose,composite_image,
2052 geometry.x,geometry.y);
2053 else
2054 {
2055 /*
2056 Rotate image.
2057 */
cristybb503372010-05-27 20:51:26 +00002058 geometry.x-=(ssize_t) (rotate_image->columns-
cristy3ed852e2009-09-05 21:47:34 +00002059 composite_image->columns)/2;
cristybb503372010-05-27 20:51:26 +00002060 geometry.y-=(ssize_t) (rotate_image->rows-composite_image->rows)/2;
cristy3ed852e2009-09-05 21:47:34 +00002061 CompositeImageChannel(image,channel,compose,rotate_image,
2062 geometry.x,geometry.y);
2063 rotate_image=DestroyImage(rotate_image);
2064 }
2065 composite_image=DestroyImage(composite_image);
2066 break;
2067 }
cristyb988fe72009-09-16 01:01:10 +00002068 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002069 {
2070 MagickBooleanType
2071 sharpen;
2072
2073 /*
2074 Contrast image.
2075 */
2076 if (msl_info->image[n] == (Image *) NULL)
2077 {
cristyb988fe72009-09-16 01:01:10 +00002078 ThrowMSLException(OptionError,"NoImagesDefined",
2079 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002080 break;
2081 }
2082 sharpen=MagickFalse;
2083 if (attributes != (const xmlChar **) NULL)
2084 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2085 {
2086 keyword=(const char *) attributes[i++];
2087 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002088 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002089 CloneString(&value,attribute);
2090 switch (*keyword)
2091 {
2092 case 'S':
2093 case 's':
2094 {
2095 if (LocaleCompare(keyword,"sharpen") == 0)
2096 {
cristy042ee782011-04-22 18:48:30 +00002097 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002098 value);
2099 if (option < 0)
2100 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2101 value);
2102 sharpen=(MagickBooleanType) option;
2103 break;
2104 }
2105 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2106 keyword);
2107 break;
2108 }
2109 default:
2110 {
2111 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2112 keyword);
2113 break;
2114 }
2115 }
2116 }
2117 (void) ContrastImage(msl_info->image[n],sharpen);
2118 break;
2119 }
cristyb988fe72009-09-16 01:01:10 +00002120 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002121 {
2122 Image
2123 *crop_image;
2124
2125 /*
2126 Crop image.
2127 */
2128 if (msl_info->image[n] == (Image *) NULL)
2129 {
cristyb988fe72009-09-16 01:01:10 +00002130 ThrowMSLException(OptionError,"NoImagesDefined",
2131 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002132 break;
2133 }
2134 SetGeometry(msl_info->image[n],&geometry);
2135 if (attributes != (const xmlChar **) NULL)
2136 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2137 {
2138 keyword=(const char *) attributes[i++];
2139 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002140 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002141 CloneString(&value,attribute);
2142 switch (*keyword)
2143 {
2144 case 'G':
2145 case 'g':
2146 {
2147 if (LocaleCompare(keyword,"geometry") == 0)
2148 {
2149 flags=ParsePageGeometry(msl_info->image[n],value,
2150 &geometry,&exception);
2151 if ((flags & HeightValue) == 0)
2152 geometry.height=geometry.width;
2153 break;
2154 }
2155 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2156 keyword);
2157 break;
2158 }
2159 case 'H':
2160 case 'h':
2161 {
2162 if (LocaleCompare(keyword,"height") == 0)
2163 {
cristyf2f27272009-12-17 14:48:46 +00002164 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002165 break;
2166 }
2167 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2168 keyword);
2169 break;
2170 }
2171 case 'W':
2172 case 'w':
2173 {
2174 if (LocaleCompare(keyword,"width") == 0)
2175 {
cristyf2f27272009-12-17 14:48:46 +00002176 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002177 break;
2178 }
2179 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2180 keyword);
2181 break;
2182 }
2183 case 'X':
2184 case 'x':
2185 {
2186 if (LocaleCompare(keyword,"x") == 0)
2187 {
cristyf2f27272009-12-17 14:48:46 +00002188 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002189 break;
2190 }
2191 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2192 keyword);
2193 break;
2194 }
2195 case 'Y':
2196 case 'y':
2197 {
2198 if (LocaleCompare(keyword,"y") == 0)
2199 {
cristyf2f27272009-12-17 14:48:46 +00002200 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002201 break;
2202 }
2203 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2204 keyword);
2205 break;
2206 }
2207 default:
2208 {
2209 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2210 keyword);
2211 break;
2212 }
2213 }
2214 }
2215 crop_image=CropImage(msl_info->image[n],&geometry,
2216 &msl_info->image[n]->exception);
2217 if (crop_image == (Image *) NULL)
2218 break;
2219 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2220 msl_info->image[n]=crop_image;
2221 break;
2222 }
cristyb988fe72009-09-16 01:01:10 +00002223 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002224 {
cristybb503372010-05-27 20:51:26 +00002225 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002226 display;
2227
2228 /*
2229 Cycle-colormap image.
2230 */
2231 if (msl_info->image[n] == (Image *) NULL)
2232 {
cristyb988fe72009-09-16 01:01:10 +00002233 ThrowMSLException(OptionError,"NoImagesDefined",
2234 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002235 break;
2236 }
2237 display=0;
2238 if (attributes != (const xmlChar **) NULL)
2239 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2240 {
2241 keyword=(const char *) attributes[i++];
2242 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002243 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002244 CloneString(&value,attribute);
2245 switch (*keyword)
2246 {
2247 case 'D':
2248 case 'd':
2249 {
2250 if (LocaleCompare(keyword,"display") == 0)
2251 {
cristyf2f27272009-12-17 14:48:46 +00002252 display=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002253 break;
2254 }
2255 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2256 keyword);
2257 break;
2258 }
2259 default:
2260 {
2261 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2262 keyword);
2263 break;
2264 }
2265 }
2266 }
2267 (void) CycleColormapImage(msl_info->image[n],display);
2268 break;
2269 }
2270 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2271 }
2272 case 'D':
2273 case 'd':
2274 {
cristyb988fe72009-09-16 01:01:10 +00002275 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002276 {
2277 Image
2278 *despeckle_image;
2279
2280 /*
2281 Despeckle image.
2282 */
2283 if (msl_info->image[n] == (Image *) NULL)
2284 {
cristyb988fe72009-09-16 01:01:10 +00002285 ThrowMSLException(OptionError,"NoImagesDefined",
2286 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002287 break;
2288 }
2289 if (attributes != (const xmlChar **) NULL)
2290 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2291 {
2292 keyword=(const char *) attributes[i++];
2293 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002294 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002295 CloneString(&value,attribute);
2296 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2297 }
2298 despeckle_image=DespeckleImage(msl_info->image[n],
2299 &msl_info->image[n]->exception);
2300 if (despeckle_image == (Image *) NULL)
2301 break;
2302 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2303 msl_info->image[n]=despeckle_image;
2304 break;
2305 }
cristyb988fe72009-09-16 01:01:10 +00002306 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002307 {
2308 if (msl_info->image[n] == (Image *) NULL)
2309 {
cristyb988fe72009-09-16 01:01:10 +00002310 ThrowMSLException(OptionError,"NoImagesDefined",
2311 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002312 break;
2313 }
2314 if (attributes != (const xmlChar **) NULL)
2315 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2316 {
2317 keyword=(const char *) attributes[i++];
2318 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002319 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002320 CloneString(&value,attribute);
2321 switch (*keyword)
2322 {
2323 default:
2324 {
2325 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2326 keyword);
2327 break;
2328 }
2329 }
2330 }
2331 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n]);
2332 break;
2333 }
cristyb988fe72009-09-16 01:01:10 +00002334 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002335 {
2336 char
2337 text[MaxTextExtent];
2338
2339 /*
2340 Annotate image.
2341 */
2342 if (msl_info->image[n] == (Image *) NULL)
2343 {
cristyb988fe72009-09-16 01:01:10 +00002344 ThrowMSLException(OptionError,"NoImagesDefined",
2345 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002346 break;
2347 }
2348 draw_info=CloneDrawInfo(msl_info->image_info[n],
2349 msl_info->draw_info[n]);
2350 angle=0.0;
2351 current=draw_info->affine;
2352 GetAffineMatrix(&affine);
2353 if (attributes != (const xmlChar **) NULL)
2354 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2355 {
2356 keyword=(const char *) attributes[i++];
2357 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002358 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002359 CloneString(&value,attribute);
2360 switch (*keyword)
2361 {
2362 case 'A':
2363 case 'a':
2364 {
2365 if (LocaleCompare(keyword,"affine") == 0)
2366 {
2367 char
2368 *p;
2369
2370 p=value;
2371 draw_info->affine.sx=strtod(p,&p);
2372 if (*p ==',')
2373 p++;
2374 draw_info->affine.rx=strtod(p,&p);
2375 if (*p ==',')
2376 p++;
2377 draw_info->affine.ry=strtod(p,&p);
2378 if (*p ==',')
2379 p++;
2380 draw_info->affine.sy=strtod(p,&p);
2381 if (*p ==',')
2382 p++;
2383 draw_info->affine.tx=strtod(p,&p);
2384 if (*p ==',')
2385 p++;
2386 draw_info->affine.ty=strtod(p,&p);
2387 break;
2388 }
2389 if (LocaleCompare(keyword,"align") == 0)
2390 {
cristy042ee782011-04-22 18:48:30 +00002391 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002392 value);
2393 if (option < 0)
2394 ThrowMSLException(OptionError,"UnrecognizedAlignType",
2395 value);
2396 draw_info->align=(AlignType) option;
2397 break;
2398 }
2399 if (LocaleCompare(keyword,"antialias") == 0)
2400 {
cristy042ee782011-04-22 18:48:30 +00002401 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002402 value);
2403 if (option < 0)
2404 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2405 value);
2406 draw_info->stroke_antialias=(MagickBooleanType) option;
2407 draw_info->text_antialias=(MagickBooleanType) option;
2408 break;
2409 }
2410 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2411 keyword);
2412 break;
2413 }
2414 case 'D':
2415 case 'd':
2416 {
2417 if (LocaleCompare(keyword,"density") == 0)
2418 {
2419 CloneString(&draw_info->density,value);
2420 break;
2421 }
2422 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2423 keyword);
2424 break;
2425 }
2426 case 'E':
2427 case 'e':
2428 {
2429 if (LocaleCompare(keyword,"encoding") == 0)
2430 {
2431 CloneString(&draw_info->encoding,value);
2432 break;
2433 }
2434 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2435 keyword);
2436 break;
2437 }
2438 case 'F':
2439 case 'f':
2440 {
2441 if (LocaleCompare(keyword, "fill") == 0)
2442 {
2443 (void) QueryColorDatabase(value,&draw_info->fill,
2444 &exception);
2445 break;
2446 }
2447 if (LocaleCompare(keyword,"family") == 0)
2448 {
2449 CloneString(&draw_info->family,value);
2450 break;
2451 }
2452 if (LocaleCompare(keyword,"font") == 0)
2453 {
2454 CloneString(&draw_info->font,value);
2455 break;
2456 }
2457 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2458 keyword);
2459 break;
2460 }
2461 case 'G':
2462 case 'g':
2463 {
2464 if (LocaleCompare(keyword,"geometry") == 0)
2465 {
2466 flags=ParsePageGeometry(msl_info->image[n],value,
2467 &geometry,&exception);
2468 if ((flags & HeightValue) == 0)
2469 geometry.height=geometry.width;
2470 break;
2471 }
2472 if (LocaleCompare(keyword,"gravity") == 0)
2473 {
cristy042ee782011-04-22 18:48:30 +00002474 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002475 value);
2476 if (option < 0)
2477 ThrowMSLException(OptionError,"UnrecognizedGravityType",
2478 value);
2479 draw_info->gravity=(GravityType) option;
2480 break;
2481 }
2482 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2483 keyword);
2484 break;
2485 }
2486 case 'P':
2487 case 'p':
2488 {
2489 if (LocaleCompare(keyword,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002490 {
cristy3ed852e2009-09-05 21:47:34 +00002491 CloneString(&draw_info->primitive,value);
2492 break;
2493 }
2494 if (LocaleCompare(keyword,"pointsize") == 0)
2495 {
cristyf2f27272009-12-17 14:48:46 +00002496 draw_info->pointsize=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002497 break;
2498 }
2499 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2500 keyword);
2501 break;
2502 }
2503 case 'R':
2504 case 'r':
2505 {
2506 if (LocaleCompare(keyword,"rotate") == 0)
2507 {
cristyf2f27272009-12-17 14:48:46 +00002508 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002509 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2510 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2511 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2512 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2513 break;
2514 }
2515 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2516 keyword);
2517 break;
2518 }
2519 case 'S':
2520 case 's':
2521 {
2522 if (LocaleCompare(keyword,"scale") == 0)
2523 {
2524 flags=ParseGeometry(value,&geometry_info);
2525 if ((flags & SigmaValue) == 0)
2526 geometry_info.sigma=1.0;
2527 affine.sx=geometry_info.rho;
2528 affine.sy=geometry_info.sigma;
2529 break;
2530 }
2531 if (LocaleCompare(keyword,"skewX") == 0)
2532 {
cristyf2f27272009-12-17 14:48:46 +00002533 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002534 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2535 break;
2536 }
2537 if (LocaleCompare(keyword,"skewY") == 0)
2538 {
cristyf2f27272009-12-17 14:48:46 +00002539 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002540 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2541 break;
2542 }
2543 if (LocaleCompare(keyword,"stretch") == 0)
2544 {
cristy042ee782011-04-22 18:48:30 +00002545 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002546 value);
2547 if (option < 0)
2548 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2549 value);
2550 draw_info->stretch=(StretchType) option;
2551 break;
2552 }
2553 if (LocaleCompare(keyword, "stroke") == 0)
2554 {
2555 (void) QueryColorDatabase(value,&draw_info->stroke,
2556 &exception);
2557 break;
2558 }
2559 if (LocaleCompare(keyword,"strokewidth") == 0)
2560 {
cristyf2f27272009-12-17 14:48:46 +00002561 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002562 break;
2563 }
2564 if (LocaleCompare(keyword,"style") == 0)
2565 {
cristy042ee782011-04-22 18:48:30 +00002566 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002567 value);
2568 if (option < 0)
2569 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2570 value);
2571 draw_info->style=(StyleType) option;
2572 break;
2573 }
2574 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2575 keyword);
2576 break;
2577 }
2578 case 'T':
2579 case 't':
2580 {
2581 if (LocaleCompare(keyword,"text") == 0)
2582 {
2583 CloneString(&draw_info->text,value);
2584 break;
2585 }
2586 if (LocaleCompare(keyword,"translate") == 0)
2587 {
2588 flags=ParseGeometry(value,&geometry_info);
2589 if ((flags & SigmaValue) == 0)
2590 geometry_info.sigma=1.0;
2591 affine.tx=geometry_info.rho;
2592 affine.ty=geometry_info.sigma;
2593 break;
2594 }
2595 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2596 keyword);
2597 break;
2598 }
2599 case 'U':
2600 case 'u':
2601 {
2602 if (LocaleCompare(keyword, "undercolor") == 0)
2603 {
2604 (void) QueryColorDatabase(value,&draw_info->undercolor,
2605 &exception);
2606 break;
2607 }
2608 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2609 keyword);
2610 break;
2611 }
2612 case 'W':
2613 case 'w':
2614 {
2615 if (LocaleCompare(keyword,"weight") == 0)
2616 {
cristyf2f27272009-12-17 14:48:46 +00002617 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002618 break;
2619 }
2620 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2621 keyword);
2622 break;
2623 }
2624 case 'X':
2625 case 'x':
2626 {
2627 if (LocaleCompare(keyword,"x") == 0)
2628 {
cristyf2f27272009-12-17 14:48:46 +00002629 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002630 break;
2631 }
2632 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2633 keyword);
2634 break;
2635 }
2636 case 'Y':
2637 case 'y':
2638 {
2639 if (LocaleCompare(keyword,"y") == 0)
2640 {
cristyf2f27272009-12-17 14:48:46 +00002641 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002642 break;
2643 }
2644 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2645 keyword);
2646 break;
2647 }
2648 default:
2649 {
2650 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2651 keyword);
2652 break;
2653 }
2654 }
2655 }
cristye8c25f92010-06-03 00:53:06 +00002656 (void) FormatMagickString(text,MaxTextExtent,
2657 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2658 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002659 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002660 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2661 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2662 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2663 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2664 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2665 affine.tx;
2666 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2667 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00002668 (void) DrawImage(msl_info->image[n],draw_info);
2669 draw_info=DestroyDrawInfo(draw_info);
2670 break;
2671 }
2672 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2673 }
2674 case 'E':
2675 case 'e':
2676 {
cristyb988fe72009-09-16 01:01:10 +00002677 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002678 {
2679 Image
2680 *edge_image;
2681
2682 /*
2683 Edge image.
2684 */
2685 if (msl_info->image[n] == (Image *) NULL)
2686 {
cristyb988fe72009-09-16 01:01:10 +00002687 ThrowMSLException(OptionError,"NoImagesDefined",
2688 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002689 break;
2690 }
2691 if (attributes != (const xmlChar **) NULL)
2692 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2693 {
2694 keyword=(const char *) attributes[i++];
2695 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002696 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002697 CloneString(&value,attribute);
2698 switch (*keyword)
2699 {
2700 case 'G':
2701 case 'g':
2702 {
2703 if (LocaleCompare(keyword,"geometry") == 0)
2704 {
2705 flags=ParseGeometry(value,&geometry_info);
2706 if ((flags & SigmaValue) == 0)
2707 geometry_info.sigma=1.0;
2708 break;
2709 }
2710 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2711 keyword);
2712 break;
2713 }
2714 case 'R':
2715 case 'r':
2716 {
2717 if (LocaleCompare(keyword,"radius") == 0)
2718 {
cristyf2f27272009-12-17 14:48:46 +00002719 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002720 break;
2721 }
2722 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2723 keyword);
2724 break;
2725 }
2726 default:
2727 {
2728 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2729 keyword);
2730 break;
2731 }
2732 }
2733 }
2734 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
2735 &msl_info->image[n]->exception);
2736 if (edge_image == (Image *) NULL)
2737 break;
2738 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2739 msl_info->image[n]=edge_image;
2740 break;
2741 }
cristyb988fe72009-09-16 01:01:10 +00002742 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002743 {
2744 Image
2745 *emboss_image;
2746
2747 /*
2748 Emboss image.
2749 */
2750 if (msl_info->image[n] == (Image *) NULL)
2751 {
cristyb988fe72009-09-16 01:01:10 +00002752 ThrowMSLException(OptionError,"NoImagesDefined",
2753 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002754 break;
2755 }
2756 if (attributes != (const xmlChar **) NULL)
2757 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2758 {
2759 keyword=(const char *) attributes[i++];
2760 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002761 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002762 CloneString(&value,attribute);
2763 switch (*keyword)
2764 {
2765 case 'G':
2766 case 'g':
2767 {
2768 if (LocaleCompare(keyword,"geometry") == 0)
2769 {
2770 flags=ParseGeometry(value,&geometry_info);
2771 if ((flags & SigmaValue) == 0)
2772 geometry_info.sigma=1.0;
2773 break;
2774 }
2775 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2776 keyword);
2777 break;
2778 }
2779 case 'R':
2780 case 'r':
2781 {
2782 if (LocaleCompare(keyword,"radius") == 0)
2783 {
cristyf2f27272009-12-17 14:48:46 +00002784 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002785 break;
2786 }
2787 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2788 keyword);
2789 break;
2790 }
2791 case 'S':
2792 case 's':
2793 {
2794 if (LocaleCompare(keyword,"sigma") == 0)
2795 {
cristyf2f27272009-12-17 14:48:46 +00002796 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002797 break;
2798 }
2799 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2800 keyword);
2801 break;
2802 }
2803 default:
2804 {
2805 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2806 keyword);
2807 break;
2808 }
2809 }
2810 }
2811 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2812 geometry_info.sigma,&msl_info->image[n]->exception);
2813 if (emboss_image == (Image *) NULL)
2814 break;
2815 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2816 msl_info->image[n]=emboss_image;
2817 break;
2818 }
cristyb988fe72009-09-16 01:01:10 +00002819 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002820 {
2821 Image
2822 *enhance_image;
2823
2824 /*
2825 Enhance image.
2826 */
2827 if (msl_info->image[n] == (Image *) NULL)
2828 {
cristyb988fe72009-09-16 01:01:10 +00002829 ThrowMSLException(OptionError,"NoImagesDefined",
2830 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002831 break;
2832 }
2833 if (attributes != (const xmlChar **) NULL)
2834 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2835 {
2836 keyword=(const char *) attributes[i++];
2837 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002838 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002839 CloneString(&value,attribute);
2840 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2841 }
2842 enhance_image=EnhanceImage(msl_info->image[n],
2843 &msl_info->image[n]->exception);
2844 if (enhance_image == (Image *) NULL)
2845 break;
2846 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2847 msl_info->image[n]=enhance_image;
2848 break;
2849 }
cristyb988fe72009-09-16 01:01:10 +00002850 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002851 {
2852 /*
2853 Equalize image.
2854 */
2855 if (msl_info->image[n] == (Image *) NULL)
2856 {
cristyb988fe72009-09-16 01:01:10 +00002857 ThrowMSLException(OptionError,"NoImagesDefined",
2858 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002859 break;
2860 }
2861 if (attributes != (const xmlChar **) NULL)
2862 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2863 {
2864 keyword=(const char *) attributes[i++];
2865 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002866 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002867 CloneString(&value,attribute);
2868 switch (*keyword)
2869 {
2870 default:
2871 {
2872 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2873 keyword);
2874 break;
2875 }
2876 }
2877 }
2878 (void) EqualizeImage(msl_info->image[n]);
2879 break;
2880 }
2881 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2882 }
2883 case 'F':
2884 case 'f':
2885 {
cristyb988fe72009-09-16 01:01:10 +00002886 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002887 {
2888 if (msl_info->image[n] == (Image *) NULL)
2889 {
cristyb988fe72009-09-16 01:01:10 +00002890 ThrowMSLException(OptionError,"NoImagesDefined",
2891 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002892 break;
2893 }
2894
2895 /* no attributes here */
2896
2897 /* process the image */
2898 {
2899 Image
2900 *newImage;
2901
2902 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2903 &msl_info->image[n]->exception);
2904 if (newImage == (Image *) NULL)
2905 break;
2906 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2907 msl_info->image[n]=newImage;
2908 break;
2909 }
2910 }
cristyb988fe72009-09-16 01:01:10 +00002911 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002912 {
2913 Image
2914 *flip_image;
2915
2916 /*
2917 Flip image.
2918 */
2919 if (msl_info->image[n] == (Image *) NULL)
2920 {
cristyb988fe72009-09-16 01:01:10 +00002921 ThrowMSLException(OptionError,"NoImagesDefined",
2922 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002923 break;
2924 }
2925 if (attributes != (const xmlChar **) NULL)
2926 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2927 {
2928 keyword=(const char *) attributes[i++];
2929 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002930 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002931 CloneString(&value,attribute);
2932 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2933 }
2934 flip_image=FlipImage(msl_info->image[n],
2935 &msl_info->image[n]->exception);
2936 if (flip_image == (Image *) NULL)
2937 break;
2938 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2939 msl_info->image[n]=flip_image;
2940 break;
2941 }
cristyb988fe72009-09-16 01:01:10 +00002942 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002943 {
2944 Image
2945 *flop_image;
2946
2947 /*
2948 Flop image.
2949 */
2950 if (msl_info->image[n] == (Image *) NULL)
2951 {
cristyb988fe72009-09-16 01:01:10 +00002952 ThrowMSLException(OptionError,"NoImagesDefined",
2953 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002954 break;
2955 }
2956 if (attributes != (const xmlChar **) NULL)
2957 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2958 {
2959 keyword=(const char *) attributes[i++];
2960 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002961 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002962 CloneString(&value,attribute);
2963 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2964 }
2965 flop_image=FlopImage(msl_info->image[n],
2966 &msl_info->image[n]->exception);
2967 if (flop_image == (Image *) NULL)
2968 break;
2969 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2970 msl_info->image[n]=flop_image;
2971 break;
2972 }
cristyb988fe72009-09-16 01:01:10 +00002973 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002974 {
2975 FrameInfo
2976 frame_info;
2977
2978 Image
2979 *frame_image;
2980
2981 /*
2982 Frame image.
2983 */
2984 if (msl_info->image[n] == (Image *) NULL)
2985 {
cristyb988fe72009-09-16 01:01:10 +00002986 ThrowMSLException(OptionError,"NoImagesDefined",
2987 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002988 break;
2989 }
2990 SetGeometry(msl_info->image[n],&geometry);
2991 if (attributes != (const xmlChar **) NULL)
2992 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2993 {
2994 keyword=(const char *) attributes[i++];
2995 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002996 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002997 CloneString(&value,attribute);
2998 switch (*keyword)
2999 {
3000 case 'C':
3001 case 'c':
3002 {
3003 if (LocaleCompare(keyword,"compose") == 0)
3004 {
cristy042ee782011-04-22 18:48:30 +00003005 option=ParseCommandOption(MagickComposeOptions,
cristy3ed852e2009-09-05 21:47:34 +00003006 MagickFalse,value);
3007 if (option < 0)
3008 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3009 value);
3010 msl_info->image[n]->compose=(CompositeOperator) option;
3011 break;
3012 }
3013 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3014 keyword);
3015 break;
3016 }
3017 case 'F':
3018 case 'f':
3019 {
3020 if (LocaleCompare(keyword, "fill") == 0)
3021 {
3022 (void) QueryColorDatabase(value,
3023 &msl_info->image[n]->matte_color,&exception);
3024 break;
3025 }
3026 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3027 keyword);
3028 break;
3029 }
3030 case 'G':
3031 case 'g':
3032 {
3033 if (LocaleCompare(keyword,"geometry") == 0)
3034 {
3035 flags=ParsePageGeometry(msl_info->image[n],value,
3036 &geometry,&exception);
3037 if ((flags & HeightValue) == 0)
3038 geometry.height=geometry.width;
3039 frame_info.width=geometry.width;
3040 frame_info.height=geometry.height;
3041 frame_info.outer_bevel=geometry.x;
3042 frame_info.inner_bevel=geometry.y;
3043 break;
3044 }
3045 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3046 keyword);
3047 break;
3048 }
3049 case 'H':
3050 case 'h':
3051 {
3052 if (LocaleCompare(keyword,"height") == 0)
3053 {
cristyf2f27272009-12-17 14:48:46 +00003054 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003055 break;
3056 }
3057 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3058 keyword);
3059 break;
3060 }
3061 case 'I':
3062 case 'i':
3063 {
3064 if (LocaleCompare(keyword,"inner") == 0)
3065 {
cristyf2f27272009-12-17 14:48:46 +00003066 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003067 break;
3068 }
3069 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3070 keyword);
3071 break;
3072 }
3073 case 'O':
3074 case 'o':
3075 {
3076 if (LocaleCompare(keyword,"outer") == 0)
3077 {
cristyf2f27272009-12-17 14:48:46 +00003078 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003079 break;
3080 }
3081 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3082 keyword);
3083 break;
3084 }
3085 case 'W':
3086 case 'w':
3087 {
3088 if (LocaleCompare(keyword,"width") == 0)
3089 {
cristyf2f27272009-12-17 14:48:46 +00003090 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003091 break;
3092 }
3093 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3094 keyword);
3095 break;
3096 }
3097 default:
3098 {
3099 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3100 keyword);
3101 break;
3102 }
3103 }
3104 }
cristybb503372010-05-27 20:51:26 +00003105 frame_info.x=(ssize_t) frame_info.width;
3106 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003107 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3108 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3109 frame_image=FrameImage(msl_info->image[n],&frame_info,
3110 &msl_info->image[n]->exception);
3111 if (frame_image == (Image *) NULL)
3112 break;
3113 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3114 msl_info->image[n]=frame_image;
3115 break;
3116 }
3117 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3118 }
3119 case 'G':
3120 case 'g':
3121 {
cristyb988fe72009-09-16 01:01:10 +00003122 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003123 {
3124 char
3125 gamma[MaxTextExtent];
3126
3127 MagickPixelPacket
3128 pixel;
3129
3130 /*
3131 Gamma image.
3132 */
3133 if (msl_info->image[n] == (Image *) NULL)
3134 {
cristyb988fe72009-09-16 01:01:10 +00003135 ThrowMSLException(OptionError,"NoImagesDefined",
3136 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003137 break;
3138 }
3139 channel=UndefinedChannel;
3140 pixel.red=0.0;
3141 pixel.green=0.0;
3142 pixel.blue=0.0;
3143 *gamma='\0';
3144 if (attributes != (const xmlChar **) NULL)
3145 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3146 {
3147 keyword=(const char *) attributes[i++];
3148 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003149 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003150 CloneString(&value,attribute);
3151 switch (*keyword)
3152 {
3153 case 'B':
3154 case 'b':
3155 {
3156 if (LocaleCompare(keyword,"blue") == 0)
3157 {
cristyf2f27272009-12-17 14:48:46 +00003158 pixel.blue=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003159 break;
3160 }
3161 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3162 keyword);
3163 break;
3164 }
3165 case 'C':
3166 case 'c':
3167 {
3168 if (LocaleCompare(keyword,"channel") == 0)
3169 {
3170 option=ParseChannelOption(value);
3171 if (option < 0)
3172 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3173 value);
3174 channel=(ChannelType) option;
3175 break;
3176 }
3177 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3178 keyword);
3179 break;
3180 }
3181 case 'G':
3182 case 'g':
3183 {
3184 if (LocaleCompare(keyword,"gamma") == 0)
3185 {
3186 (void) CopyMagickString(gamma,value,MaxTextExtent);
3187 break;
3188 }
3189 if (LocaleCompare(keyword,"green") == 0)
3190 {
cristyf2f27272009-12-17 14:48:46 +00003191 pixel.green=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003192 break;
3193 }
3194 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3195 keyword);
3196 break;
3197 }
3198 case 'R':
3199 case 'r':
3200 {
3201 if (LocaleCompare(keyword,"red") == 0)
3202 {
cristyf2f27272009-12-17 14:48:46 +00003203 pixel.red=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003204 break;
3205 }
3206 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3207 keyword);
3208 break;
3209 }
3210 default:
3211 {
3212 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3213 keyword);
3214 break;
3215 }
3216 }
3217 }
3218 if (*gamma == '\0')
cristye7f51092010-01-17 00:39:37 +00003219 (void) FormatMagickString(gamma,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003220 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb988fe72009-09-16 01:01:10 +00003221 switch (channel)
cristy3ed852e2009-09-05 21:47:34 +00003222 {
3223 default:
3224 {
3225 (void) GammaImage(msl_info->image[n],gamma);
3226 break;
3227 }
3228 case RedChannel:
3229 {
3230 (void) GammaImageChannel(msl_info->image[n],RedChannel,pixel.red);
3231 break;
3232 }
3233 case GreenChannel:
3234 {
3235 (void) GammaImageChannel(msl_info->image[n],GreenChannel,
3236 pixel.green);
3237 break;
3238 }
3239 case BlueChannel:
3240 {
3241 (void) GammaImageChannel(msl_info->image[n],BlueChannel,
3242 pixel.blue);
3243 break;
3244 }
3245 }
3246 break;
3247 }
cristyb988fe72009-09-16 01:01:10 +00003248 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003249 {
3250 if (msl_info->image[n] == (Image *) NULL)
3251 {
cristyb988fe72009-09-16 01:01:10 +00003252 ThrowMSLException(OptionError,"NoImagesDefined",
3253 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003254 break;
3255 }
3256 if (attributes == (const xmlChar **) NULL)
3257 break;
3258 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3259 {
3260 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003261 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003262 (void) CopyMagickString(key,value,MaxTextExtent);
3263 switch (*keyword)
3264 {
3265 case 'H':
3266 case 'h':
3267 {
3268 if (LocaleCompare(keyword,"height") == 0)
3269 {
cristye8c25f92010-06-03 00:53:06 +00003270 (void) FormatMagickString(value,MaxTextExtent,"%.20g",
3271 (double) msl_info->image[n]->rows);
cristy3ed852e2009-09-05 21:47:34 +00003272 (void) SetImageProperty(msl_info->attributes[n],key,value);
3273 break;
3274 }
3275 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3276 }
3277 case 'W':
3278 case 'w':
3279 {
3280 if (LocaleCompare(keyword,"width") == 0)
3281 {
cristye8c25f92010-06-03 00:53:06 +00003282 (void) FormatMagickString(value,MaxTextExtent,"%.20g",
3283 (double) msl_info->image[n]->columns);
cristy3ed852e2009-09-05 21:47:34 +00003284 (void) SetImageProperty(msl_info->attributes[n],key,value);
3285 break;
3286 }
3287 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3288 }
3289 default:
3290 {
3291 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3292 break;
3293 }
3294 }
3295 }
3296 break;
3297 }
cristyb988fe72009-09-16 01:01:10 +00003298 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003299 {
3300 msl_info->number_groups++;
3301 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3302 msl_info->group_info,msl_info->number_groups+1UL,
3303 sizeof(*msl_info->group_info));
3304 break;
3305 }
3306 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3307 }
3308 case 'I':
3309 case 'i':
3310 {
cristyb988fe72009-09-16 01:01:10 +00003311 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003312 {
cristy3ed852e2009-09-05 21:47:34 +00003313 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003314 if (attributes == (const xmlChar **) NULL)
3315 break;
3316 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3317 {
3318 keyword=(const char *) attributes[i++];
3319 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003320 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00003321 switch (*keyword)
3322 {
cristyb988fe72009-09-16 01:01:10 +00003323 case 'C':
3324 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003325 {
cristyb988fe72009-09-16 01:01:10 +00003326 if (LocaleCompare(keyword,"color") == 0)
3327 {
3328 Image
3329 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003330
cristyb988fe72009-09-16 01:01:10 +00003331 (void) CopyMagickString(msl_info->image_info[n]->filename,
3332 "xc:",MaxTextExtent);
3333 (void) ConcatenateMagickString(msl_info->image_info[n]->
3334 filename,value,MaxTextExtent);
3335 next_image=ReadImage(msl_info->image_info[n],&exception);
3336 CatchException(&exception);
3337 if (next_image == (Image *) NULL)
3338 continue;
3339 if (msl_info->image[n] == (Image *) NULL)
3340 msl_info->image[n]=next_image;
3341 else
3342 {
3343 register Image
3344 *p;
cristy3ed852e2009-09-05 21:47:34 +00003345
cristyb988fe72009-09-16 01:01:10 +00003346 /*
3347 Link image into image list.
3348 */
3349 p=msl_info->image[n];
3350 while (p->next != (Image *) NULL)
3351 p=GetNextImageInList(p);
3352 next_image->previous=p;
3353 p->next=next_image;
3354 }
3355 break;
3356 }
cristyb20775d2009-09-16 01:51:41 +00003357 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003358 break;
3359 }
3360 default:
3361 {
cristyb20775d2009-09-16 01:51:41 +00003362 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003363 break;
3364 }
3365 }
3366 }
3367 break;
3368 }
cristyb988fe72009-09-16 01:01:10 +00003369 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003370 {
3371 Image
3372 *implode_image;
3373
3374 /*
3375 Implode image.
3376 */
3377 if (msl_info->image[n] == (Image *) NULL)
3378 {
cristyb988fe72009-09-16 01:01:10 +00003379 ThrowMSLException(OptionError,"NoImagesDefined",
3380 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003381 break;
3382 }
3383 if (attributes != (const xmlChar **) NULL)
3384 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3385 {
3386 keyword=(const char *) attributes[i++];
3387 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003388 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003389 CloneString(&value,attribute);
3390 switch (*keyword)
3391 {
3392 case 'A':
3393 case 'a':
3394 {
3395 if (LocaleCompare(keyword,"amount") == 0)
3396 {
cristyf2f27272009-12-17 14:48:46 +00003397 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003398 break;
3399 }
3400 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3401 keyword);
3402 break;
3403 }
3404 case 'G':
3405 case 'g':
3406 {
3407 if (LocaleCompare(keyword,"geometry") == 0)
3408 {
3409 flags=ParseGeometry(value,&geometry_info);
3410 if ((flags & SigmaValue) == 0)
3411 geometry_info.sigma=1.0;
3412 break;
3413 }
3414 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3415 keyword);
3416 break;
3417 }
3418 default:
3419 {
3420 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3421 keyword);
3422 break;
3423 }
3424 }
3425 }
3426 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3427 &msl_info->image[n]->exception);
3428 if (implode_image == (Image *) NULL)
3429 break;
3430 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3431 msl_info->image[n]=implode_image;
3432 break;
3433 }
3434 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3435 }
3436 case 'L':
3437 case 'l':
3438 {
cristyb988fe72009-09-16 01:01:10 +00003439 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003440 break;
cristyb988fe72009-09-16 01:01:10 +00003441 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003442 {
3443 double
3444 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3445
3446 if (msl_info->image[n] == (Image *) NULL)
3447 {
cristyb988fe72009-09-16 01:01:10 +00003448 ThrowMSLException(OptionError,"NoImagesDefined",
3449 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003450 break;
3451 }
3452 if (attributes == (const xmlChar **) NULL)
3453 break;
3454 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3455 {
3456 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003457 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003458 (void) CopyMagickString(key,value,MaxTextExtent);
3459 switch (*keyword)
3460 {
3461 case 'B':
3462 case 'b':
3463 {
3464 if (LocaleCompare(keyword,"black") == 0)
3465 {
cristyf2f27272009-12-17 14:48:46 +00003466 levelBlack = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00003467 break;
3468 }
3469 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3470 break;
3471 }
3472 case 'G':
3473 case 'g':
3474 {
3475 if (LocaleCompare(keyword,"gamma") == 0)
3476 {
cristyf2f27272009-12-17 14:48:46 +00003477 levelGamma = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00003478 break;
3479 }
3480 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3481 break;
3482 }
3483 case 'W':
3484 case 'w':
3485 {
3486 if (LocaleCompare(keyword,"white") == 0)
3487 {
cristyf2f27272009-12-17 14:48:46 +00003488 levelWhite = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00003489 break;
3490 }
3491 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3492 break;
3493 }
3494 default:
3495 {
3496 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3497 break;
3498 }
3499 }
3500 }
3501
3502 /* process image */
3503 {
3504 char level[MaxTextExtent + 1];
3505 (void) FormatMagickString(level,MaxTextExtent,"%3.6f/%3.6f/%3.6f/",
3506 levelBlack,levelGamma,levelWhite);
3507 LevelImage ( msl_info->image[n], level );
3508 break;
3509 }
3510 }
3511 }
3512 case 'M':
3513 case 'm':
3514 {
cristyb988fe72009-09-16 01:01:10 +00003515 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003516 {
3517 Image
3518 *magnify_image;
3519
3520 /*
3521 Magnify image.
3522 */
3523 if (msl_info->image[n] == (Image *) NULL)
3524 {
cristyb988fe72009-09-16 01:01:10 +00003525 ThrowMSLException(OptionError,"NoImagesDefined",
3526 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003527 break;
3528 }
3529 if (attributes != (const xmlChar **) NULL)
3530 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3531 {
3532 keyword=(const char *) attributes[i++];
3533 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003534 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003535 CloneString(&value,attribute);
3536 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3537 }
3538 magnify_image=MagnifyImage(msl_info->image[n],
3539 &msl_info->image[n]->exception);
3540 if (magnify_image == (Image *) NULL)
3541 break;
3542 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3543 msl_info->image[n]=magnify_image;
3544 break;
3545 }
cristyb988fe72009-09-16 01:01:10 +00003546 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003547 {
3548 Image
3549 *affinity_image;
3550
3551 MagickBooleanType
3552 dither;
3553
3554 QuantizeInfo
3555 *quantize_info;
3556
3557 /*
3558 Map image.
3559 */
3560 if (msl_info->image[n] == (Image *) NULL)
3561 {
cristyb988fe72009-09-16 01:01:10 +00003562 ThrowMSLException(OptionError,"NoImagesDefined",
3563 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003564 break;
3565 }
3566 affinity_image=NewImageList();
3567 dither=MagickFalse;
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],
cristyb988fe72009-09-16 01:01:10 +00003573 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003574 CloneString(&value,attribute);
3575 switch (*keyword)
3576 {
3577 case 'D':
3578 case 'd':
3579 {
3580 if (LocaleCompare(keyword,"dither") == 0)
3581 {
cristy042ee782011-04-22 18:48:30 +00003582 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003583 value);
3584 if (option < 0)
3585 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3586 value);
3587 dither=(MagickBooleanType) option;
3588 break;
3589 }
3590 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3591 keyword);
3592 break;
3593 }
3594 case 'I':
3595 case 'i':
3596 {
3597 if (LocaleCompare(keyword,"image") == 0)
3598 for (j=0; j < msl_info->n; j++)
3599 {
3600 const char
3601 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003602
cristy3ed852e2009-09-05 21:47:34 +00003603 attribute=GetImageProperty(msl_info->attributes[j],"id");
3604 if ((attribute != (const char *) NULL) &&
3605 (LocaleCompare(attribute,value) == 0))
3606 {
3607 affinity_image=CloneImage(msl_info->image[j],0,0,
3608 MagickFalse,&exception);
3609 break;
3610 }
3611 }
3612 break;
3613 }
3614 default:
3615 {
3616 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3617 keyword);
3618 break;
3619 }
3620 }
3621 }
3622 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3623 quantize_info->dither=dither;
3624 (void) RemapImages(quantize_info,msl_info->image[n],
3625 affinity_image);
3626 quantize_info=DestroyQuantizeInfo(quantize_info);
3627 affinity_image=DestroyImage(affinity_image);
3628 break;
3629 }
cristyb988fe72009-09-16 01:01:10 +00003630 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003631 {
3632 double
3633 opacity;
3634
3635 MagickPixelPacket
3636 target;
3637
3638 PaintMethod
3639 paint_method;
3640
3641 /*
3642 Matte floodfill image.
3643 */
3644 opacity=0.0;
3645 if (msl_info->image[n] == (Image *) NULL)
3646 {
cristyb988fe72009-09-16 01:01:10 +00003647 ThrowMSLException(OptionError,"NoImagesDefined",
3648 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003649 break;
3650 }
3651 SetGeometry(msl_info->image[n],&geometry);
3652 paint_method=FloodfillMethod;
3653 if (attributes != (const xmlChar **) NULL)
3654 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3655 {
3656 keyword=(const char *) attributes[i++];
3657 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003658 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003659 CloneString(&value,attribute);
3660 switch (*keyword)
3661 {
3662 case 'B':
3663 case 'b':
3664 {
3665 if (LocaleCompare(keyword,"bordercolor") == 0)
3666 {
3667 (void) QueryMagickColor(value,&target,&exception);
3668 paint_method=FillToBorderMethod;
3669 break;
3670 }
3671 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3672 keyword);
3673 break;
3674 }
3675 case 'F':
3676 case 'f':
3677 {
3678 if (LocaleCompare(keyword,"fuzz") == 0)
3679 {
cristyf2f27272009-12-17 14:48:46 +00003680 msl_info->image[n]->fuzz=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003681 break;
3682 }
3683 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3684 keyword);
3685 break;
3686 }
3687 case 'G':
3688 case 'g':
3689 {
3690 if (LocaleCompare(keyword,"geometry") == 0)
3691 {
3692 flags=ParsePageGeometry(msl_info->image[n],value,
3693 &geometry,&exception);
3694 if ((flags & HeightValue) == 0)
3695 geometry.height=geometry.width;
3696 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3697 geometry.x,geometry.y,&target,&exception);
3698 break;
3699 }
3700 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3701 keyword);
3702 break;
3703 }
3704 case 'O':
3705 case 'o':
3706 {
3707 if (LocaleCompare(keyword,"opacity") == 0)
3708 {
cristyf2f27272009-12-17 14:48:46 +00003709 opacity=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003710 break;
3711 }
3712 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3713 keyword);
3714 break;
3715 }
3716 case 'X':
3717 case 'x':
3718 {
3719 if (LocaleCompare(keyword,"x") == 0)
3720 {
cristyf2f27272009-12-17 14:48:46 +00003721 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003722 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3723 geometry.x,geometry.y,&target,&exception);
3724 break;
3725 }
3726 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3727 keyword);
3728 break;
3729 }
3730 case 'Y':
3731 case 'y':
3732 {
3733 if (LocaleCompare(keyword,"y") == 0)
3734 {
cristyf2f27272009-12-17 14:48:46 +00003735 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003736 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3737 geometry.x,geometry.y,&target,&exception);
3738 break;
3739 }
3740 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3741 keyword);
3742 break;
3743 }
3744 default:
3745 {
3746 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3747 keyword);
3748 break;
3749 }
3750 }
3751 }
3752 draw_info=CloneDrawInfo(msl_info->image_info[n],
3753 msl_info->draw_info[n]);
cristyce70c172010-01-07 17:15:30 +00003754 draw_info->fill.opacity=ClampToQuantum(opacity);
cristy3ed852e2009-09-05 21:47:34 +00003755 (void) FloodfillPaintImage(msl_info->image[n],OpacityChannel,
3756 draw_info,&target,geometry.x,geometry.y,
3757 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
3758 draw_info=DestroyDrawInfo(draw_info);
3759 break;
3760 }
cristyb988fe72009-09-16 01:01:10 +00003761 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003762 {
3763 Image
3764 *median_image;
3765
3766 /*
3767 Median-filter image.
3768 */
3769 if (msl_info->image[n] == (Image *) NULL)
3770 {
cristyb988fe72009-09-16 01:01:10 +00003771 ThrowMSLException(OptionError,"NoImagesDefined",
3772 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003773 break;
3774 }
3775 if (attributes != (const xmlChar **) NULL)
3776 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3777 {
3778 keyword=(const char *) attributes[i++];
3779 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003780 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003781 CloneString(&value,attribute);
3782 switch (*keyword)
3783 {
3784 case 'G':
3785 case 'g':
3786 {
3787 if (LocaleCompare(keyword,"geometry") == 0)
3788 {
3789 flags=ParseGeometry(value,&geometry_info);
3790 if ((flags & SigmaValue) == 0)
3791 geometry_info.sigma=1.0;
3792 break;
3793 }
3794 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3795 keyword);
3796 break;
3797 }
3798 case 'R':
3799 case 'r':
3800 {
3801 if (LocaleCompare(keyword,"radius") == 0)
3802 {
cristyf2f27272009-12-17 14:48:46 +00003803 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003804 break;
3805 }
3806 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3807 keyword);
3808 break;
3809 }
3810 default:
3811 {
3812 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3813 keyword);
3814 break;
3815 }
3816 }
3817 }
cristy733678d2011-03-18 21:29:28 +00003818 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003819 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3820 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003821 if (median_image == (Image *) NULL)
3822 break;
3823 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3824 msl_info->image[n]=median_image;
3825 break;
3826 }
cristyb988fe72009-09-16 01:01:10 +00003827 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003828 {
3829 Image
3830 *minify_image;
3831
3832 /*
3833 Minify image.
3834 */
3835 if (msl_info->image[n] == (Image *) NULL)
3836 {
cristyb988fe72009-09-16 01:01:10 +00003837 ThrowMSLException(OptionError,"NoImagesDefined",
3838 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003839 break;
3840 }
3841 if (attributes != (const xmlChar **) NULL)
3842 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3843 {
3844 keyword=(const char *) attributes[i++];
3845 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003846 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003847 CloneString(&value,attribute);
3848 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3849 }
3850 minify_image=MinifyImage(msl_info->image[n],
3851 &msl_info->image[n]->exception);
3852 if (minify_image == (Image *) NULL)
3853 break;
3854 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3855 msl_info->image[n]=minify_image;
3856 break;
3857 }
cristyb988fe72009-09-16 01:01:10 +00003858 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003859 break;
cristyb988fe72009-09-16 01:01:10 +00003860 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003861 {
3862 char
3863 modulate[MaxTextExtent];
3864
3865 /*
3866 Modulate image.
3867 */
3868 if (msl_info->image[n] == (Image *) NULL)
3869 {
cristyb988fe72009-09-16 01:01:10 +00003870 ThrowMSLException(OptionError,"NoImagesDefined",
3871 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003872 break;
3873 }
3874 geometry_info.rho=100.0;
3875 geometry_info.sigma=100.0;
3876 geometry_info.xi=100.0;
3877 if (attributes != (const xmlChar **) NULL)
3878 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3879 {
3880 keyword=(const char *) attributes[i++];
3881 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003882 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003883 CloneString(&value,attribute);
3884 switch (*keyword)
3885 {
3886 case 'B':
3887 case 'b':
3888 {
3889 if (LocaleCompare(keyword,"blackness") == 0)
3890 {
cristyf2f27272009-12-17 14:48:46 +00003891 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003892 break;
3893 }
3894 if (LocaleCompare(keyword,"brightness") == 0)
3895 {
cristyf2f27272009-12-17 14:48:46 +00003896 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003897 break;
3898 }
3899 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3900 keyword);
3901 break;
3902 }
3903 case 'F':
3904 case 'f':
3905 {
3906 if (LocaleCompare(keyword,"factor") == 0)
3907 {
3908 flags=ParseGeometry(value,&geometry_info);
3909 break;
3910 }
3911 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3912 keyword);
3913 break;
3914 }
3915 case 'H':
3916 case 'h':
3917 {
3918 if (LocaleCompare(keyword,"hue") == 0)
3919 {
cristyf2f27272009-12-17 14:48:46 +00003920 geometry_info.xi=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003921 break;
3922 }
3923 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3924 keyword);
3925 break;
3926 }
3927 case 'L':
3928 case 'l':
3929 {
3930 if (LocaleCompare(keyword,"lightness") == 0)
3931 {
cristyf2f27272009-12-17 14:48:46 +00003932 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003933 break;
3934 }
3935 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3936 keyword);
3937 break;
3938 }
3939 case 'S':
3940 case 's':
3941 {
3942 if (LocaleCompare(keyword,"saturation") == 0)
3943 {
cristyf2f27272009-12-17 14:48:46 +00003944 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003945 break;
3946 }
3947 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3948 keyword);
3949 break;
3950 }
3951 case 'W':
3952 case 'w':
3953 {
3954 if (LocaleCompare(keyword,"whiteness") == 0)
3955 {
cristyf2f27272009-12-17 14:48:46 +00003956 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003957 break;
3958 }
3959 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3960 keyword);
3961 break;
3962 }
3963 default:
3964 {
3965 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3966 keyword);
3967 break;
3968 }
3969 }
3970 }
cristye7f51092010-01-17 00:39:37 +00003971 (void) FormatMagickString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003972 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
3973 (void) ModulateImage(msl_info->image[n],modulate);
3974 break;
3975 }
3976 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3977 }
3978 case 'N':
3979 case 'n':
3980 {
cristyb988fe72009-09-16 01:01:10 +00003981 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003982 {
3983 MagickBooleanType
3984 gray;
3985
3986 /*
3987 Negate image.
3988 */
3989 if (msl_info->image[n] == (Image *) NULL)
3990 {
cristyb988fe72009-09-16 01:01:10 +00003991 ThrowMSLException(OptionError,"NoImagesDefined",
3992 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003993 break;
3994 }
3995 gray=MagickFalse;
3996 if (attributes != (const xmlChar **) NULL)
3997 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3998 {
3999 keyword=(const char *) attributes[i++];
4000 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004001 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004002 CloneString(&value,attribute);
4003 switch (*keyword)
4004 {
4005 case 'C':
4006 case 'c':
4007 {
4008 if (LocaleCompare(keyword,"channel") == 0)
4009 {
4010 option=ParseChannelOption(value);
4011 if (option < 0)
4012 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4013 value);
4014 channel=(ChannelType) option;
4015 break;
4016 }
4017 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4018 keyword);
4019 break;
4020 }
4021 case 'G':
4022 case 'g':
4023 {
4024 if (LocaleCompare(keyword,"gray") == 0)
4025 {
cristy042ee782011-04-22 18:48:30 +00004026 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004027 value);
4028 if (option < 0)
4029 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4030 value);
4031 gray=(MagickBooleanType) option;
4032 break;
4033 }
4034 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4035 keyword);
4036 break;
4037 }
4038 default:
4039 {
4040 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4041 keyword);
4042 break;
4043 }
4044 }
4045 }
4046 (void) NegateImageChannel(msl_info->image[n],channel,gray);
4047 break;
4048 }
cristyb988fe72009-09-16 01:01:10 +00004049 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004050 {
4051 /*
4052 Normalize image.
4053 */
4054 if (msl_info->image[n] == (Image *) NULL)
4055 {
cristyb988fe72009-09-16 01:01:10 +00004056 ThrowMSLException(OptionError,"NoImagesDefined",
4057 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004058 break;
4059 }
4060 if (attributes != (const xmlChar **) NULL)
4061 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4062 {
4063 keyword=(const char *) attributes[i++];
4064 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004065 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004066 CloneString(&value,attribute);
4067 switch (*keyword)
4068 {
4069 case 'C':
4070 case 'c':
4071 {
4072 if (LocaleCompare(keyword,"channel") == 0)
4073 {
4074 option=ParseChannelOption(value);
4075 if (option < 0)
4076 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4077 value);
4078 channel=(ChannelType) option;
4079 break;
4080 }
4081 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4082 keyword);
4083 break;
4084 }
4085 default:
4086 {
4087 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4088 keyword);
4089 break;
4090 }
4091 }
4092 }
4093 (void) NormalizeImageChannel(msl_info->image[n],channel);
4094 break;
4095 }
4096 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4097 }
4098 case 'O':
4099 case 'o':
4100 {
cristyb988fe72009-09-16 01:01:10 +00004101 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004102 {
4103 Image
4104 *paint_image;
4105
4106 /*
4107 Oil-paint image.
4108 */
4109 if (msl_info->image[n] == (Image *) NULL)
4110 {
cristyb988fe72009-09-16 01:01:10 +00004111 ThrowMSLException(OptionError,"NoImagesDefined",
4112 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004113 break;
4114 }
4115 if (attributes != (const xmlChar **) NULL)
4116 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4117 {
4118 keyword=(const char *) attributes[i++];
4119 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004120 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004121 CloneString(&value,attribute);
4122 switch (*keyword)
4123 {
4124 case 'G':
4125 case 'g':
4126 {
4127 if (LocaleCompare(keyword,"geometry") == 0)
4128 {
4129 flags=ParseGeometry(value,&geometry_info);
4130 if ((flags & SigmaValue) == 0)
4131 geometry_info.sigma=1.0;
4132 break;
4133 }
4134 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4135 keyword);
4136 break;
4137 }
4138 case 'R':
4139 case 'r':
4140 {
4141 if (LocaleCompare(keyword,"radius") == 0)
4142 {
cristyf2f27272009-12-17 14:48:46 +00004143 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004144 break;
4145 }
4146 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4147 keyword);
4148 break;
4149 }
4150 default:
4151 {
4152 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4153 keyword);
4154 break;
4155 }
4156 }
4157 }
4158 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4159 &msl_info->image[n]->exception);
4160 if (paint_image == (Image *) NULL)
4161 break;
4162 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4163 msl_info->image[n]=paint_image;
4164 break;
4165 }
cristyb988fe72009-09-16 01:01:10 +00004166 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004167 {
4168 MagickPixelPacket
4169 fill_color,
4170 target;
4171
4172 /*
4173 Opaque image.
4174 */
4175 if (msl_info->image[n] == (Image *) NULL)
4176 {
cristyb988fe72009-09-16 01:01:10 +00004177 ThrowMSLException(OptionError,"NoImagesDefined",
4178 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004179 break;
4180 }
4181 (void) QueryMagickColor("none",&target,&exception);
4182 (void) QueryMagickColor("none",&fill_color,&exception);
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],
cristyb988fe72009-09-16 01:01:10 +00004188 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004189 CloneString(&value,attribute);
4190 switch (*keyword)
4191 {
4192 case 'C':
4193 case 'c':
4194 {
4195 if (LocaleCompare(keyword,"channel") == 0)
4196 {
4197 option=ParseChannelOption(value);
4198 if (option < 0)
4199 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4200 value);
4201 channel=(ChannelType) option;
4202 break;
4203 }
4204 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4205 keyword);
4206 break;
4207 }
4208 case 'F':
4209 case 'f':
4210 {
4211 if (LocaleCompare(keyword,"fill") == 0)
4212 {
4213 (void) QueryMagickColor(value,&fill_color,&exception);
4214 break;
4215 }
4216 if (LocaleCompare(keyword,"fuzz") == 0)
4217 {
cristyf2f27272009-12-17 14:48:46 +00004218 msl_info->image[n]->fuzz=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004219 break;
4220 }
4221 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4222 keyword);
4223 break;
4224 }
4225 default:
4226 {
4227 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4228 keyword);
4229 break;
4230 }
4231 }
4232 }
4233 (void) OpaquePaintImageChannel(msl_info->image[n],channel,
4234 &target,&fill_color,MagickFalse);
4235 break;
4236 }
4237 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4238 }
4239 case 'P':
4240 case 'p':
4241 {
cristyb988fe72009-09-16 01:01:10 +00004242 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004243 {
4244 if (attributes == (const xmlChar **) NULL)
4245 break;
4246 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4247 {
4248 keyword=(const char *) attributes[i++];
4249 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004250 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004251 CloneString(&value,attribute);
4252 switch (*keyword)
4253 {
4254 case 'O':
4255 case 'o':
4256 {
4257 if (LocaleCompare(keyword,"output") == 0)
4258 {
4259 (void) fprintf(stdout,"%s",value);
4260 break;
4261 }
4262 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4263 break;
4264 }
4265 default:
4266 {
4267 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4268 break;
4269 }
4270 }
4271 }
4272 break;
4273 }
cristy4fa36e42009-09-18 14:24:06 +00004274 if (LocaleCompare((const char *) tag, "profile") == 0)
4275 {
cristy4fa36e42009-09-18 14:24:06 +00004276 if (msl_info->image[n] == (Image *) NULL)
4277 {
4278 ThrowMSLException(OptionError,"NoImagesDefined",
4279 (const char *) tag);
4280 break;
4281 }
4282 if (attributes == (const xmlChar **) NULL)
4283 break;
4284 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4285 {
4286 const char
4287 *name;
4288
4289 const StringInfo
4290 *profile;
4291
4292 Image
4293 *profile_image;
4294
4295 ImageInfo
4296 *profile_info;
4297
4298 keyword=(const char *) attributes[i++];
4299 attribute=InterpretImageProperties(msl_info->image_info[n],
4300 msl_info->attributes[n],(const char *) attributes[i]);
4301 CloneString(&value,attribute);
4302 if (*keyword == '+')
4303 {
4304 /*
4305 Remove a profile from the image.
4306 */
4307 (void) ProfileImage(msl_info->image[n],keyword,
4308 (const unsigned char *) NULL,0,MagickTrue);
4309 continue;
4310 }
4311 /*
4312 Associate a profile with the image.
4313 */
4314 profile_info=CloneImageInfo(msl_info->image_info[n]);
4315 profile=GetImageProfile(msl_info->image[n],"iptc");
4316 if (profile != (StringInfo *) NULL)
4317 profile_info->profile=(void *) CloneStringInfo(profile);
4318 profile_image=GetImageCache(profile_info,keyword,&exception);
4319 profile_info=DestroyImageInfo(profile_info);
4320 if (profile_image == (Image *) NULL)
4321 {
4322 char
4323 name[MaxTextExtent],
4324 filename[MaxTextExtent];
4325
4326 register char
4327 *p;
4328
4329 StringInfo
4330 *profile;
4331
4332 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4333 (void) CopyMagickString(name,keyword,MaxTextExtent);
4334 for (p=filename; *p != '\0'; p++)
4335 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4336 (IsPathAccessible(keyword) == MagickFalse))
4337 {
4338 register char
4339 *q;
4340
4341 /*
4342 Look for profile name (e.g. name:profile).
4343 */
4344 (void) CopyMagickString(name,filename,(size_t)
4345 (p-filename+1));
4346 for (q=filename; *q != '\0'; q++)
4347 *q=(*++p);
4348 break;
4349 }
4350 profile=FileToStringInfo(filename,~0UL,&exception);
4351 if (profile != (StringInfo *) NULL)
4352 {
4353 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004354 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004355 GetStringInfoLength(profile),MagickFalse);
4356 profile=DestroyStringInfo(profile);
4357 }
4358 continue;
4359 }
4360 ResetImageProfileIterator(profile_image);
4361 name=GetNextImageProfile(profile_image);
4362 while (name != (const char *) NULL)
4363 {
4364 profile=GetImageProfile(profile_image,name);
4365 if (profile != (StringInfo *) NULL)
4366 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004367 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004368 GetStringInfoLength(profile),MagickFalse);
4369 name=GetNextImageProfile(profile_image);
4370 }
4371 profile_image=DestroyImage(profile_image);
4372 }
4373 break;
4374 }
cristy3ed852e2009-09-05 21:47:34 +00004375 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4376 }
4377 case 'Q':
4378 case 'q':
4379 {
cristyb988fe72009-09-16 01:01:10 +00004380 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004381 {
4382 QuantizeInfo
4383 quantize_info;
4384
4385 /*
4386 Quantize image.
4387 */
4388 if (msl_info->image[n] == (Image *) NULL)
4389 {
cristyb988fe72009-09-16 01:01:10 +00004390 ThrowMSLException(OptionError,"NoImagesDefined",
4391 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004392 break;
4393 }
4394 GetQuantizeInfo(&quantize_info);
4395 if (attributes != (const xmlChar **) NULL)
4396 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4397 {
4398 keyword=(const char *) attributes[i++];
4399 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004400 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004401 CloneString(&value,attribute);
4402 switch (*keyword)
4403 {
4404 case 'C':
4405 case 'c':
4406 {
4407 if (LocaleCompare(keyword,"colors") == 0)
4408 {
cristyf2f27272009-12-17 14:48:46 +00004409 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004410 break;
4411 }
4412 if (LocaleCompare(keyword,"colorspace") == 0)
4413 {
cristy042ee782011-04-22 18:48:30 +00004414 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004415 MagickFalse,value);
4416 if (option < 0)
4417 ThrowMSLException(OptionError,
4418 "UnrecognizedColorspaceType",value);
4419 quantize_info.colorspace=(ColorspaceType) option;
4420 break;
4421 }
4422 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4423 keyword);
4424 break;
4425 }
4426 case 'D':
4427 case 'd':
4428 {
4429 if (LocaleCompare(keyword,"dither") == 0)
4430 {
cristy042ee782011-04-22 18:48:30 +00004431 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004432 value);
4433 if (option < 0)
4434 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4435 value);
4436 quantize_info.dither=(MagickBooleanType) option;
4437 break;
4438 }
4439 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4440 keyword);
4441 break;
4442 }
4443 case 'M':
4444 case 'm':
4445 {
4446 if (LocaleCompare(keyword,"measure") == 0)
4447 {
cristy042ee782011-04-22 18:48:30 +00004448 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004449 value);
4450 if (option < 0)
4451 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4452 value);
4453 quantize_info.measure_error=(MagickBooleanType) option;
4454 break;
4455 }
4456 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4457 keyword);
4458 break;
4459 }
4460 case 'T':
4461 case 't':
4462 {
4463 if (LocaleCompare(keyword,"treedepth") == 0)
4464 {
cristyf2f27272009-12-17 14:48:46 +00004465 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004466 break;
4467 }
4468 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4469 keyword);
4470 break;
4471 }
4472 default:
4473 {
4474 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4475 keyword);
4476 break;
4477 }
4478 }
4479 }
4480 (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4481 break;
4482 }
cristyb988fe72009-09-16 01:01:10 +00004483 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004484 {
4485 char
4486 text[MaxTextExtent];
4487
4488 MagickBooleanType
4489 status;
4490
4491 TypeMetric
4492 metrics;
4493
4494 /*
4495 Query font metrics.
4496 */
4497 draw_info=CloneDrawInfo(msl_info->image_info[n],
4498 msl_info->draw_info[n]);
4499 angle=0.0;
4500 current=draw_info->affine;
4501 GetAffineMatrix(&affine);
4502 if (attributes != (const xmlChar **) NULL)
4503 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4504 {
4505 keyword=(const char *) attributes[i++];
4506 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004507 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004508 CloneString(&value,attribute);
4509 switch (*keyword)
4510 {
4511 case 'A':
4512 case 'a':
4513 {
4514 if (LocaleCompare(keyword,"affine") == 0)
4515 {
4516 char
4517 *p;
4518
4519 p=value;
4520 draw_info->affine.sx=strtod(p,&p);
4521 if (*p ==',')
4522 p++;
4523 draw_info->affine.rx=strtod(p,&p);
4524 if (*p ==',')
4525 p++;
4526 draw_info->affine.ry=strtod(p,&p);
4527 if (*p ==',')
4528 p++;
4529 draw_info->affine.sy=strtod(p,&p);
4530 if (*p ==',')
4531 p++;
4532 draw_info->affine.tx=strtod(p,&p);
4533 if (*p ==',')
4534 p++;
4535 draw_info->affine.ty=strtod(p,&p);
4536 break;
4537 }
4538 if (LocaleCompare(keyword,"align") == 0)
4539 {
cristy042ee782011-04-22 18:48:30 +00004540 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004541 value);
4542 if (option < 0)
4543 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4544 value);
4545 draw_info->align=(AlignType) option;
4546 break;
4547 }
4548 if (LocaleCompare(keyword,"antialias") == 0)
4549 {
cristy042ee782011-04-22 18:48:30 +00004550 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004551 value);
4552 if (option < 0)
4553 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4554 value);
4555 draw_info->stroke_antialias=(MagickBooleanType) option;
4556 draw_info->text_antialias=(MagickBooleanType) option;
4557 break;
4558 }
4559 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4560 keyword);
4561 break;
4562 }
4563 case 'D':
4564 case 'd':
4565 {
4566 if (LocaleCompare(keyword,"density") == 0)
4567 {
4568 CloneString(&draw_info->density,value);
4569 break;
4570 }
4571 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4572 keyword);
4573 break;
4574 }
4575 case 'E':
4576 case 'e':
4577 {
4578 if (LocaleCompare(keyword,"encoding") == 0)
4579 {
4580 CloneString(&draw_info->encoding,value);
4581 break;
4582 }
4583 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4584 keyword);
4585 break;
4586 }
4587 case 'F':
4588 case 'f':
4589 {
4590 if (LocaleCompare(keyword, "fill") == 0)
4591 {
4592 (void) QueryColorDatabase(value,&draw_info->fill,
4593 &exception);
4594 break;
4595 }
4596 if (LocaleCompare(keyword,"family") == 0)
4597 {
4598 CloneString(&draw_info->family,value);
4599 break;
4600 }
4601 if (LocaleCompare(keyword,"font") == 0)
4602 {
4603 CloneString(&draw_info->font,value);
4604 break;
4605 }
4606 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4607 keyword);
4608 break;
4609 }
4610 case 'G':
4611 case 'g':
4612 {
4613 if (LocaleCompare(keyword,"geometry") == 0)
4614 {
4615 flags=ParsePageGeometry(msl_info->image[n],value,
4616 &geometry,&exception);
4617 if ((flags & HeightValue) == 0)
4618 geometry.height=geometry.width;
4619 break;
4620 }
4621 if (LocaleCompare(keyword,"gravity") == 0)
4622 {
cristy042ee782011-04-22 18:48:30 +00004623 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004624 value);
4625 if (option < 0)
4626 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4627 value);
4628 draw_info->gravity=(GravityType) option;
4629 break;
4630 }
4631 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4632 keyword);
4633 break;
4634 }
4635 case 'P':
4636 case 'p':
4637 {
4638 if (LocaleCompare(keyword,"pointsize") == 0)
4639 {
cristyf2f27272009-12-17 14:48:46 +00004640 draw_info->pointsize=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004641 break;
4642 }
4643 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4644 keyword);
4645 break;
4646 }
4647 case 'R':
4648 case 'r':
4649 {
4650 if (LocaleCompare(keyword,"rotate") == 0)
4651 {
cristyf2f27272009-12-17 14:48:46 +00004652 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004653 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4654 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4655 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4656 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4657 break;
4658 }
4659 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4660 keyword);
4661 break;
4662 }
4663 case 'S':
4664 case 's':
4665 {
4666 if (LocaleCompare(keyword,"scale") == 0)
4667 {
4668 flags=ParseGeometry(value,&geometry_info);
4669 if ((flags & SigmaValue) == 0)
4670 geometry_info.sigma=1.0;
4671 affine.sx=geometry_info.rho;
4672 affine.sy=geometry_info.sigma;
4673 break;
4674 }
4675 if (LocaleCompare(keyword,"skewX") == 0)
4676 {
cristyf2f27272009-12-17 14:48:46 +00004677 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004678 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4679 break;
4680 }
4681 if (LocaleCompare(keyword,"skewY") == 0)
4682 {
cristyf2f27272009-12-17 14:48:46 +00004683 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004684 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4685 break;
4686 }
4687 if (LocaleCompare(keyword,"stretch") == 0)
4688 {
cristy042ee782011-04-22 18:48:30 +00004689 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004690 value);
4691 if (option < 0)
4692 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4693 value);
4694 draw_info->stretch=(StretchType) option;
4695 break;
4696 }
4697 if (LocaleCompare(keyword, "stroke") == 0)
4698 {
4699 (void) QueryColorDatabase(value,&draw_info->stroke,
4700 &exception);
4701 break;
4702 }
4703 if (LocaleCompare(keyword,"strokewidth") == 0)
4704 {
cristyf2f27272009-12-17 14:48:46 +00004705 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004706 break;
4707 }
4708 if (LocaleCompare(keyword,"style") == 0)
4709 {
cristy042ee782011-04-22 18:48:30 +00004710 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004711 value);
4712 if (option < 0)
4713 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4714 value);
4715 draw_info->style=(StyleType) option;
4716 break;
4717 }
4718 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4719 keyword);
4720 break;
4721 }
4722 case 'T':
4723 case 't':
4724 {
4725 if (LocaleCompare(keyword,"text") == 0)
4726 {
4727 CloneString(&draw_info->text,value);
4728 break;
4729 }
4730 if (LocaleCompare(keyword,"translate") == 0)
4731 {
4732 flags=ParseGeometry(value,&geometry_info);
4733 if ((flags & SigmaValue) == 0)
4734 geometry_info.sigma=1.0;
4735 affine.tx=geometry_info.rho;
4736 affine.ty=geometry_info.sigma;
4737 break;
4738 }
4739 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4740 keyword);
4741 break;
4742 }
4743 case 'U':
4744 case 'u':
4745 {
4746 if (LocaleCompare(keyword, "undercolor") == 0)
4747 {
4748 (void) QueryColorDatabase(value,&draw_info->undercolor,
4749 &exception);
4750 break;
4751 }
4752 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4753 keyword);
4754 break;
4755 }
4756 case 'W':
4757 case 'w':
4758 {
4759 if (LocaleCompare(keyword,"weight") == 0)
4760 {
cristyf2f27272009-12-17 14:48:46 +00004761 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004762 break;
4763 }
4764 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4765 keyword);
4766 break;
4767 }
4768 case 'X':
4769 case 'x':
4770 {
4771 if (LocaleCompare(keyword,"x") == 0)
4772 {
cristyf2f27272009-12-17 14:48:46 +00004773 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004774 break;
4775 }
4776 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4777 keyword);
4778 break;
4779 }
4780 case 'Y':
4781 case 'y':
4782 {
4783 if (LocaleCompare(keyword,"y") == 0)
4784 {
cristyf2f27272009-12-17 14:48:46 +00004785 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004786 break;
4787 }
4788 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4789 keyword);
4790 break;
4791 }
4792 default:
4793 {
4794 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4795 keyword);
4796 break;
4797 }
4798 }
4799 }
cristye8c25f92010-06-03 00:53:06 +00004800 (void) FormatMagickString(text,MaxTextExtent,
4801 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4802 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004803 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004804 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4805 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4806 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4807 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4808 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4809 affine.tx;
4810 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4811 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00004812 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4813 if (status != MagickFalse)
4814 {
4815 Image
4816 *image;
4817
4818 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004819 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004820 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004821 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004822 "%g",metrics.pixels_per_em.y);
4823 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004824 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004825 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004826 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004827 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004828 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004829 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004830 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004831 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004832 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004833 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004834 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004835 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004836 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004837 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004838 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004839 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004840 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004841 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004842 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004843 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004844 metrics.origin.y);
4845 }
4846 draw_info=DestroyDrawInfo(draw_info);
4847 break;
4848 }
4849 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4850 }
4851 case 'R':
4852 case 'r':
4853 {
cristyb988fe72009-09-16 01:01:10 +00004854 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004855 {
4856 MagickBooleanType
4857 raise;
4858
4859 /*
4860 Raise image.
4861 */
4862 if (msl_info->image[n] == (Image *) NULL)
4863 {
cristyb988fe72009-09-16 01:01:10 +00004864 ThrowMSLException(OptionError,"NoImagesDefined",
4865 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004866 break;
4867 }
4868 raise=MagickFalse;
4869 SetGeometry(msl_info->image[n],&geometry);
4870 if (attributes != (const xmlChar **) NULL)
4871 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4872 {
4873 keyword=(const char *) attributes[i++];
4874 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004875 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004876 CloneString(&value,attribute);
4877 switch (*keyword)
4878 {
4879 case 'G':
4880 case 'g':
4881 {
4882 if (LocaleCompare(keyword,"geometry") == 0)
4883 {
4884 flags=ParsePageGeometry(msl_info->image[n],value,
4885 &geometry,&exception);
4886 if ((flags & HeightValue) == 0)
4887 geometry.height=geometry.width;
4888 break;
4889 }
4890 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4891 keyword);
4892 break;
4893 }
4894 case 'H':
4895 case 'h':
4896 {
4897 if (LocaleCompare(keyword,"height") == 0)
4898 {
cristyf2f27272009-12-17 14:48:46 +00004899 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004900 break;
4901 }
4902 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4903 keyword);
4904 break;
4905 }
4906 case 'R':
4907 case 'r':
4908 {
4909 if (LocaleCompare(keyword,"raise") == 0)
4910 {
cristy042ee782011-04-22 18:48:30 +00004911 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004912 value);
4913 if (option < 0)
4914 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4915 value);
4916 raise=(MagickBooleanType) option;
4917 break;
4918 }
4919 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4920 keyword);
4921 break;
4922 }
4923 case 'W':
4924 case 'w':
4925 {
4926 if (LocaleCompare(keyword,"width") == 0)
4927 {
cristyf2f27272009-12-17 14:48:46 +00004928 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004929 break;
4930 }
4931 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4932 keyword);
4933 break;
4934 }
4935 default:
4936 {
4937 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4938 keyword);
4939 break;
4940 }
4941 }
4942 }
4943 (void) RaiseImage(msl_info->image[n],&geometry,raise);
4944 break;
4945 }
cristyb988fe72009-09-16 01:01:10 +00004946 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004947 {
4948 if (attributes == (const xmlChar **) NULL)
4949 break;
4950 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4951 {
4952 keyword=(const char *) attributes[i++];
4953 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004954 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00004955 switch (*keyword)
4956 {
4957 case 'F':
4958 case 'f':
4959 {
4960 if (LocaleCompare(keyword,"filename") == 0)
4961 {
4962 Image
4963 *image;
4964
4965 (void) CopyMagickString(msl_info->image_info[n]->filename,
4966 value,MaxTextExtent);
4967 image=ReadImage(msl_info->image_info[n],&exception);
4968 CatchException(&exception);
4969 if (image == (Image *) NULL)
4970 continue;
4971 AppendImageToList(&msl_info->image[n],image);
4972 break;
4973 }
cristy4582cbb2009-09-23 00:35:43 +00004974 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004975 break;
4976 }
4977 default:
4978 {
cristy4582cbb2009-09-23 00:35:43 +00004979 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004980 break;
4981 }
4982 }
4983 }
4984 break;
4985 }
cristyb988fe72009-09-16 01:01:10 +00004986 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004987 {
4988 Image
4989 *paint_image;
4990
4991 /*
4992 Reduce-noise image.
4993 */
4994 if (msl_info->image[n] == (Image *) NULL)
4995 {
cristyb988fe72009-09-16 01:01:10 +00004996 ThrowMSLException(OptionError,"NoImagesDefined",
4997 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004998 break;
4999 }
5000 if (attributes != (const xmlChar **) NULL)
5001 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5002 {
5003 keyword=(const char *) attributes[i++];
5004 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005005 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005006 CloneString(&value,attribute);
5007 switch (*keyword)
5008 {
5009 case 'G':
5010 case 'g':
5011 {
5012 if (LocaleCompare(keyword,"geometry") == 0)
5013 {
5014 flags=ParseGeometry(value,&geometry_info);
5015 if ((flags & SigmaValue) == 0)
5016 geometry_info.sigma=1.0;
5017 break;
5018 }
5019 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5020 keyword);
5021 break;
5022 }
5023 case 'R':
5024 case 'r':
5025 {
5026 if (LocaleCompare(keyword,"radius") == 0)
5027 {
cristyf2f27272009-12-17 14:48:46 +00005028 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005029 break;
5030 }
5031 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5032 keyword);
5033 break;
5034 }
5035 default:
5036 {
5037 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5038 keyword);
5039 break;
5040 }
5041 }
5042 }
cristy733678d2011-03-18 21:29:28 +00005043 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005044 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5045 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00005046 if (paint_image == (Image *) NULL)
5047 break;
5048 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5049 msl_info->image[n]=paint_image;
5050 break;
5051 }
cristyb988fe72009-09-16 01:01:10 +00005052 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005053 {
5054 /* init the values */
5055 width=msl_info->image[n]->page.width;
5056 height=msl_info->image[n]->page.height;
5057 x=msl_info->image[n]->page.x;
5058 y=msl_info->image[n]->page.y;
5059
5060 if (msl_info->image[n] == (Image *) NULL)
5061 {
cristyb988fe72009-09-16 01:01:10 +00005062 ThrowMSLException(OptionError,"NoImagesDefined",
5063 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005064 break;
5065 }
5066 if (attributes == (const xmlChar **) NULL)
5067 break;
5068 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5069 {
5070 keyword=(const char *) attributes[i++];
5071 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005072 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005073 switch (*keyword)
5074 {
5075 case 'G':
5076 case 'g':
5077 {
5078 if (LocaleCompare(keyword,"geometry") == 0)
5079 {
5080 int
5081 flags;
5082
5083 RectangleInfo
5084 geometry;
5085
5086 flags=ParseAbsoluteGeometry(value,&geometry);
5087 if ((flags & WidthValue) != 0)
5088 {
5089 if ((flags & HeightValue) == 0)
5090 geometry.height=geometry.width;
5091 width=geometry.width;
5092 height=geometry.height;
5093 }
5094 if ((flags & AspectValue) != 0)
5095 {
5096 if ((flags & XValue) != 0)
5097 x+=geometry.x;
5098 if ((flags & YValue) != 0)
5099 y+=geometry.y;
5100 }
5101 else
5102 {
5103 if ((flags & XValue) != 0)
5104 {
5105 x=geometry.x;
5106 if ((width == 0) && (geometry.x > 0))
5107 width=msl_info->image[n]->columns+geometry.x;
5108 }
5109 if ((flags & YValue) != 0)
5110 {
5111 y=geometry.y;
5112 if ((height == 0) && (geometry.y > 0))
5113 height=msl_info->image[n]->rows+geometry.y;
5114 }
5115 }
5116 break;
5117 }
5118 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5119 break;
5120 }
5121 case 'H':
5122 case 'h':
5123 {
5124 if (LocaleCompare(keyword,"height") == 0)
5125 {
cristyf2f27272009-12-17 14:48:46 +00005126 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005127 break;
5128 }
5129 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5130 break;
5131 }
5132 case 'W':
5133 case 'w':
5134 {
5135 if (LocaleCompare(keyword,"width") == 0)
5136 {
cristyf2f27272009-12-17 14:48:46 +00005137 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005138 break;
5139 }
5140 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5141 break;
5142 }
5143 case 'X':
5144 case 'x':
5145 {
5146 if (LocaleCompare(keyword,"x") == 0)
5147 {
cristyf2f27272009-12-17 14:48:46 +00005148 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005149 break;
5150 }
5151 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5152 break;
5153 }
5154 case 'Y':
5155 case 'y':
5156 {
5157 if (LocaleCompare(keyword,"y") == 0)
5158 {
cristyf2f27272009-12-17 14:48:46 +00005159 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005160 break;
5161 }
5162 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5163 break;
5164 }
5165 default:
5166 {
5167 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5168 break;
5169 }
5170 }
5171 }
5172
cristyb988fe72009-09-16 01:01:10 +00005173 msl_info->image[n]->page.width=width;
5174 msl_info->image[n]->page.height=height;
5175 msl_info->image[n]->page.x=x;
5176 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005177 break;
5178 }
cristyb988fe72009-09-16 01:01:10 +00005179 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005180 {
5181 double
5182 x_resolution,
5183 y_resolution;
5184
5185 if (msl_info->image[n] == (Image *) NULL)
5186 {
cristyb988fe72009-09-16 01:01:10 +00005187 ThrowMSLException(OptionError,"NoImagesDefined",
5188 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005189 break;
5190 }
5191 if (attributes == (const xmlChar **) NULL)
5192 break;
5193 x_resolution=DefaultResolution;
5194 y_resolution=DefaultResolution;
5195 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5196 {
5197 keyword=(const char *) attributes[i++];
5198 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005199 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005200 switch (*keyword)
5201 {
5202 case 'b':
5203 {
5204 if (LocaleCompare(keyword,"blur") == 0)
5205 {
cristyf2f27272009-12-17 14:48:46 +00005206 msl_info->image[n]->blur=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005207 break;
5208 }
5209 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5210 break;
5211 }
5212 case 'G':
5213 case 'g':
5214 {
5215 if (LocaleCompare(keyword,"geometry") == 0)
5216 {
cristybb503372010-05-27 20:51:26 +00005217 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005218 flags;
5219
5220 flags=ParseGeometry(value,&geometry_info);
5221 if ((flags & SigmaValue) == 0)
5222 geometry_info.sigma*=geometry_info.rho;
5223 x_resolution=geometry_info.rho;
5224 y_resolution=geometry_info.sigma;
5225 break;
5226 }
5227 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5228 break;
5229 }
5230 case 'X':
5231 case 'x':
5232 {
5233 if (LocaleCompare(keyword,"x-resolution") == 0)
5234 {
cristyf2f27272009-12-17 14:48:46 +00005235 x_resolution=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005236 break;
5237 }
5238 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5239 break;
5240 }
5241 case 'Y':
5242 case 'y':
5243 {
5244 if (LocaleCompare(keyword,"y-resolution") == 0)
5245 {
cristyf2f27272009-12-17 14:48:46 +00005246 y_resolution=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005247 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 Resample image.
5261 */
5262 {
5263 double
5264 factor;
5265
5266 Image
5267 *resample_image;
5268
5269 factor=1.0;
5270 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5271 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005272 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy3ed852e2009-09-05 21:47:34 +00005273 (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5274 msl_info->image[n]->x_resolution))+0.5);
cristybb503372010-05-27 20:51:26 +00005275 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy3ed852e2009-09-05 21:47:34 +00005276 (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5277 msl_info->image[n]->y_resolution))+0.5);
5278 resample_image=ResizeImage(msl_info->image[n],width,height,
5279 msl_info->image[n]->filter,msl_info->image[n]->blur,
5280 &msl_info->image[n]->exception);
5281 if (resample_image == (Image *) NULL)
5282 break;
5283 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5284 msl_info->image[n]=resample_image;
5285 }
5286 break;
5287 }
cristyb988fe72009-09-16 01:01:10 +00005288 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005289 {
5290 double
5291 blur;
5292
5293 FilterTypes
5294 filter;
5295
5296 Image
5297 *resize_image;
5298
5299 /*
5300 Resize image.
5301 */
5302 if (msl_info->image[n] == (Image *) NULL)
5303 {
cristyb988fe72009-09-16 01:01:10 +00005304 ThrowMSLException(OptionError,"NoImagesDefined",
5305 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005306 break;
5307 }
5308 filter=UndefinedFilter;
5309 blur=1.0;
5310 if (attributes != (const xmlChar **) NULL)
5311 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5312 {
5313 keyword=(const char *) attributes[i++];
5314 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005315 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005316 CloneString(&value,attribute);
5317 switch (*keyword)
5318 {
5319 case 'F':
5320 case 'f':
5321 {
5322 if (LocaleCompare(keyword,"filter") == 0)
5323 {
cristy042ee782011-04-22 18:48:30 +00005324 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005325 value);
5326 if (option < 0)
5327 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5328 value);
5329 filter=(FilterTypes) option;
5330 break;
5331 }
5332 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5333 keyword);
5334 break;
5335 }
5336 case 'G':
5337 case 'g':
5338 {
5339 if (LocaleCompare(keyword,"geometry") == 0)
5340 {
5341 flags=ParseRegionGeometry(msl_info->image[n],value,
5342 &geometry,&exception);
5343 break;
5344 }
5345 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5346 keyword);
5347 break;
5348 }
5349 case 'H':
5350 case 'h':
5351 {
5352 if (LocaleCompare(keyword,"height") == 0)
5353 {
cristye27293e2009-12-18 02:53:20 +00005354 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005355 break;
5356 }
5357 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5358 keyword);
5359 break;
5360 }
5361 case 'S':
5362 case 's':
5363 {
5364 if (LocaleCompare(keyword,"support") == 0)
5365 {
cristyf2f27272009-12-17 14:48:46 +00005366 blur=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005367 break;
5368 }
5369 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5370 keyword);
5371 break;
5372 }
5373 case 'W':
5374 case 'w':
5375 {
5376 if (LocaleCompare(keyword,"width") == 0)
5377 {
cristyf2f27272009-12-17 14:48:46 +00005378 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005379 break;
5380 }
5381 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5382 keyword);
5383 break;
5384 }
5385 default:
5386 {
5387 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5388 keyword);
5389 break;
5390 }
5391 }
5392 }
5393 resize_image=ResizeImage(msl_info->image[n],geometry.width,
5394 geometry.height,filter,blur,&msl_info->image[n]->exception);
5395 if (resize_image == (Image *) NULL)
5396 break;
5397 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5398 msl_info->image[n]=resize_image;
5399 break;
5400 }
cristyb988fe72009-09-16 01:01:10 +00005401 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005402 {
5403 Image
5404 *roll_image;
5405
5406 /*
5407 Roll image.
5408 */
5409 if (msl_info->image[n] == (Image *) NULL)
5410 {
cristyb988fe72009-09-16 01:01:10 +00005411 ThrowMSLException(OptionError,"NoImagesDefined",
5412 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005413 break;
5414 }
5415 SetGeometry(msl_info->image[n],&geometry);
5416 if (attributes != (const xmlChar **) NULL)
5417 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5418 {
5419 keyword=(const char *) attributes[i++];
5420 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005421 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005422 CloneString(&value,attribute);
5423 switch (*keyword)
5424 {
5425 case 'G':
5426 case 'g':
5427 {
5428 if (LocaleCompare(keyword,"geometry") == 0)
5429 {
5430 flags=ParsePageGeometry(msl_info->image[n],value,
5431 &geometry,&exception);
5432 if ((flags & HeightValue) == 0)
5433 geometry.height=geometry.width;
5434 break;
5435 }
5436 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5437 keyword);
5438 break;
5439 }
5440 case 'X':
5441 case 'x':
5442 {
5443 if (LocaleCompare(keyword,"x") == 0)
5444 {
cristyf2f27272009-12-17 14:48:46 +00005445 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005446 break;
5447 }
5448 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5449 keyword);
5450 break;
5451 }
5452 case 'Y':
5453 case 'y':
5454 {
5455 if (LocaleCompare(keyword,"y") == 0)
5456 {
cristyf2f27272009-12-17 14:48:46 +00005457 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005458 break;
5459 }
5460 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5461 keyword);
5462 break;
5463 }
5464 default:
5465 {
5466 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5467 keyword);
5468 break;
5469 }
5470 }
5471 }
5472 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5473 &msl_info->image[n]->exception);
5474 if (roll_image == (Image *) NULL)
5475 break;
5476 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5477 msl_info->image[n]=roll_image;
5478 break;
5479 }
cristyb988fe72009-09-16 01:01:10 +00005480 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005481 {
5482 /* init the values */
5483 width=msl_info->image[n]->columns;
5484 height=msl_info->image[n]->rows;
5485 x = y = 0;
5486
5487 if (msl_info->image[n] == (Image *) NULL)
5488 {
cristyb988fe72009-09-16 01:01:10 +00005489 ThrowMSLException(OptionError,"NoImagesDefined",
5490 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005491 break;
5492 }
5493 if (attributes == (const xmlChar **) NULL)
5494 break;
5495 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5496 {
5497 keyword=(const char *) attributes[i++];
5498 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005499 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005500 switch (*keyword)
5501 {
5502 case 'G':
5503 case 'g':
5504 {
5505 if (LocaleCompare(keyword,"geometry") == 0)
5506 {
5507 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5508 break;
5509 }
5510 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5511 break;
5512 }
5513 case 'X':
5514 case 'x':
5515 {
5516 if (LocaleCompare(keyword,"x") == 0)
5517 {
cristyf2f27272009-12-17 14:48:46 +00005518 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005519 break;
5520 }
5521 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5522 break;
5523 }
5524 case 'Y':
5525 case 'y':
5526 {
5527 if (LocaleCompare(keyword,"y") == 0)
5528 {
cristyf2f27272009-12-17 14:48:46 +00005529 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005530 break;
5531 }
5532 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5533 break;
5534 }
5535 default:
5536 {
5537 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5538 break;
5539 }
5540 }
5541 }
5542
5543 /*
5544 process image.
5545 */
5546 {
5547 Image
5548 *newImage;
5549
5550 newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5551 if (newImage == (Image *) NULL)
5552 break;
5553 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5554 msl_info->image[n]=newImage;
5555 }
5556
5557 break;
5558 }
cristyb988fe72009-09-16 01:01:10 +00005559 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005560 {
5561 Image
5562 *rotate_image;
5563
5564 /*
5565 Rotate image.
5566 */
5567 if (msl_info->image[n] == (Image *) NULL)
5568 {
cristyb988fe72009-09-16 01:01:10 +00005569 ThrowMSLException(OptionError,"NoImagesDefined",
5570 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005571 break;
5572 }
5573 if (attributes != (const xmlChar **) NULL)
5574 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5575 {
5576 keyword=(const char *) attributes[i++];
5577 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005578 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005579 CloneString(&value,attribute);
5580 switch (*keyword)
5581 {
5582 case 'D':
5583 case 'd':
5584 {
5585 if (LocaleCompare(keyword,"degrees") == 0)
5586 {
cristyf2f27272009-12-17 14:48:46 +00005587 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005588 break;
5589 }
5590 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5591 keyword);
5592 break;
5593 }
5594 case 'G':
5595 case 'g':
5596 {
5597 if (LocaleCompare(keyword,"geometry") == 0)
5598 {
5599 flags=ParseGeometry(value,&geometry_info);
5600 if ((flags & SigmaValue) == 0)
5601 geometry_info.sigma=1.0;
5602 break;
5603 }
5604 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5605 keyword);
5606 break;
5607 }
5608 default:
5609 {
5610 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5611 keyword);
5612 break;
5613 }
5614 }
5615 }
5616 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5617 &msl_info->image[n]->exception);
5618 if (rotate_image == (Image *) NULL)
5619 break;
5620 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5621 msl_info->image[n]=rotate_image;
5622 break;
5623 }
cristyb988fe72009-09-16 01:01:10 +00005624 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005625 {
5626 /* init the values */
5627 double degrees = 0;
5628
5629 if (msl_info->image[n] == (Image *) NULL)
5630 {
cristyb988fe72009-09-16 01:01:10 +00005631 ThrowMSLException(OptionError,"NoImagesDefined",
5632 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005633 break;
5634 }
5635 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005636 break;
cristy3ed852e2009-09-05 21:47:34 +00005637 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5638 {
5639 keyword=(const char *) attributes[i++];
5640 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005641 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005642 switch (*keyword)
5643 {
5644 case 'D':
5645 case 'd':
5646 {
5647 if (LocaleCompare(keyword,"degrees") == 0)
5648 {
cristyf2f27272009-12-17 14:48:46 +00005649 degrees = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00005650 break;
5651 }
5652 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5653 break;
5654 }
5655 default:
5656 {
5657 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5658 break;
5659 }
5660 }
5661 }
5662
5663 /*
5664 process image.
5665 */
5666 {
5667 Image
5668 *newImage;
5669
5670 newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5671 if (newImage == (Image *) NULL)
5672 break;
5673 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5674 msl_info->image[n]=newImage;
5675 }
5676
5677 break;
5678 }
5679 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5680 }
5681 case 'S':
5682 case 's':
5683 {
cristyb988fe72009-09-16 01:01:10 +00005684 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005685 {
5686 Image
5687 *sample_image;
5688
5689 /*
5690 Sample image.
5691 */
5692 if (msl_info->image[n] == (Image *) NULL)
5693 {
cristyb988fe72009-09-16 01:01:10 +00005694 ThrowMSLException(OptionError,"NoImagesDefined",
5695 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005696 break;
5697 }
5698 if (attributes != (const xmlChar **) NULL)
5699 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5700 {
5701 keyword=(const char *) attributes[i++];
5702 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005703 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005704 CloneString(&value,attribute);
5705 switch (*keyword)
5706 {
5707 case 'G':
5708 case 'g':
5709 {
5710 if (LocaleCompare(keyword,"geometry") == 0)
5711 {
5712 flags=ParseRegionGeometry(msl_info->image[n],value,
5713 &geometry,&exception);
5714 break;
5715 }
5716 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5717 keyword);
5718 break;
5719 }
5720 case 'H':
5721 case 'h':
5722 {
5723 if (LocaleCompare(keyword,"height") == 0)
5724 {
cristye27293e2009-12-18 02:53:20 +00005725 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005726 break;
5727 }
5728 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5729 keyword);
5730 break;
5731 }
5732 case 'W':
5733 case 'w':
5734 {
5735 if (LocaleCompare(keyword,"width") == 0)
5736 {
cristyf2f27272009-12-17 14:48:46 +00005737 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005738 break;
5739 }
5740 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5741 keyword);
5742 break;
5743 }
5744 default:
5745 {
5746 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5747 keyword);
5748 break;
5749 }
5750 }
5751 }
5752 sample_image=SampleImage(msl_info->image[n],geometry.width,
5753 geometry.height,&msl_info->image[n]->exception);
5754 if (sample_image == (Image *) NULL)
5755 break;
5756 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5757 msl_info->image[n]=sample_image;
5758 break;
5759 }
cristyb988fe72009-09-16 01:01:10 +00005760 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005761 {
5762 Image
5763 *scale_image;
5764
5765 /*
5766 Scale image.
5767 */
5768 if (msl_info->image[n] == (Image *) NULL)
5769 {
cristyb988fe72009-09-16 01:01:10 +00005770 ThrowMSLException(OptionError,"NoImagesDefined",
5771 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005772 break;
5773 }
5774 if (attributes != (const xmlChar **) NULL)
5775 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5776 {
5777 keyword=(const char *) attributes[i++];
5778 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005779 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005780 CloneString(&value,attribute);
5781 switch (*keyword)
5782 {
5783 case 'G':
5784 case 'g':
5785 {
5786 if (LocaleCompare(keyword,"geometry") == 0)
5787 {
5788 flags=ParseRegionGeometry(msl_info->image[n],value,
5789 &geometry,&exception);
5790 break;
5791 }
5792 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5793 keyword);
5794 break;
5795 }
5796 case 'H':
5797 case 'h':
5798 {
5799 if (LocaleCompare(keyword,"height") == 0)
5800 {
cristye27293e2009-12-18 02:53:20 +00005801 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005802 break;
5803 }
5804 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5805 keyword);
5806 break;
5807 }
5808 case 'W':
5809 case 'w':
5810 {
5811 if (LocaleCompare(keyword,"width") == 0)
5812 {
cristyf2f27272009-12-17 14:48:46 +00005813 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005814 break;
5815 }
5816 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5817 keyword);
5818 break;
5819 }
5820 default:
5821 {
5822 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5823 keyword);
5824 break;
5825 }
5826 }
5827 }
5828 scale_image=ScaleImage(msl_info->image[n],geometry.width,
5829 geometry.height,&msl_info->image[n]->exception);
5830 if (scale_image == (Image *) NULL)
5831 break;
5832 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5833 msl_info->image[n]=scale_image;
5834 break;
5835 }
cristyb988fe72009-09-16 01:01:10 +00005836 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005837 {
5838 ColorspaceType
5839 colorspace;
5840
5841 MagickBooleanType
5842 verbose;
cristyb988fe72009-09-16 01:01:10 +00005843
cristy3ed852e2009-09-05 21:47:34 +00005844 /*
5845 Segment image.
5846 */
5847 if (msl_info->image[n] == (Image *) NULL)
5848 {
cristyb988fe72009-09-16 01:01:10 +00005849 ThrowMSLException(OptionError,"NoImagesDefined",
5850 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005851 break;
5852 }
5853 geometry_info.rho=1.0;
5854 geometry_info.sigma=1.5;
5855 colorspace=RGBColorspace;
5856 verbose=MagickFalse;
5857 if (attributes != (const xmlChar **) NULL)
5858 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5859 {
5860 keyword=(const char *) attributes[i++];
5861 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005862 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005863 CloneString(&value,attribute);
5864 switch (*keyword)
5865 {
5866 case 'C':
5867 case 'c':
5868 {
5869 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5870 {
cristyf2f27272009-12-17 14:48:46 +00005871 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005872 break;
5873 }
5874 if (LocaleCompare(keyword,"colorspace") == 0)
5875 {
cristy042ee782011-04-22 18:48:30 +00005876 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005877 MagickFalse,value);
5878 if (option < 0)
5879 ThrowMSLException(OptionError,
5880 "UnrecognizedColorspaceType",value);
5881 colorspace=(ColorspaceType) option;
5882 break;
5883 }
5884 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5885 keyword);
5886 break;
5887 }
5888 case 'G':
5889 case 'g':
5890 {
5891 if (LocaleCompare(keyword,"geometry") == 0)
5892 {
5893 flags=ParseGeometry(value,&geometry_info);
5894 if ((flags & SigmaValue) == 0)
5895 geometry_info.sigma=1.5;
5896 break;
5897 }
5898 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5899 keyword);
5900 break;
5901 }
5902 case 'S':
5903 case 's':
5904 {
5905 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5906 {
cristyf2f27272009-12-17 14:48:46 +00005907 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005908 break;
5909 }
5910 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5911 keyword);
5912 break;
5913 }
5914 default:
5915 {
5916 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5917 keyword);
5918 break;
5919 }
5920 }
5921 }
5922 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5923 geometry_info.rho,geometry_info.sigma);
5924 break;
5925 }
cristyb988fe72009-09-16 01:01:10 +00005926 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005927 {
5928 if (msl_info->image[n] == (Image *) NULL)
5929 {
cristyb988fe72009-09-16 01:01:10 +00005930 ThrowMSLException(OptionError,"NoImagesDefined",
5931 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005932 break;
5933 }
5934
5935 if (attributes == (const xmlChar **) NULL)
5936 break;
5937 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5938 {
5939 keyword=(const char *) attributes[i++];
5940 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005941 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005942 switch (*keyword)
5943 {
cristy3ed852e2009-09-05 21:47:34 +00005944 case 'C':
5945 case 'c':
5946 {
5947 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005948 {
cristy2c8b6312009-09-16 02:37:23 +00005949 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005950 {
cristy2c8b6312009-09-16 02:37:23 +00005951 const char
5952 *property;
5953
5954 property=GetImageProperty(msl_info->attributes[j],"id");
5955 if (LocaleCompare(property,value) == 0)
5956 {
5957 SetImageMask(msl_info->image[n],msl_info->image[j]);
5958 break;
5959 }
cristy3ed852e2009-09-05 21:47:34 +00005960 }
cristy2c8b6312009-09-16 02:37:23 +00005961 break;
cristy3ed852e2009-09-05 21:47:34 +00005962 }
cristy3ed852e2009-09-05 21:47:34 +00005963 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005964 {
cristy2c8b6312009-09-16 02:37:23 +00005965 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005966 {
cristy2c8b6312009-09-16 02:37:23 +00005967 const char
5968 *property;
5969
5970 property=GetImageProperty(msl_info->attributes[j],"id");
5971 if (LocaleCompare(property,value) == 0)
5972 {
5973 SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5974 break;
5975 }
cristy3ed852e2009-09-05 21:47:34 +00005976 }
cristy2c8b6312009-09-16 02:37:23 +00005977 break;
cristy3ed852e2009-09-05 21:47:34 +00005978 }
cristy2c8b6312009-09-16 02:37:23 +00005979 if (LocaleCompare(keyword,"colorspace") == 0)
5980 {
cristybb503372010-05-27 20:51:26 +00005981 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00005982 colorspace;
5983
cristy042ee782011-04-22 18:48:30 +00005984 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00005985 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00005986 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00005987 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00005988 value);
5989 (void) TransformImageColorspace(msl_info->image[n],
5990 (ColorspaceType) colorspace);
5991 break;
5992 }
5993 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005994 break;
5995 }
5996 case 'D':
5997 case 'd':
5998 {
cristy2c8b6312009-09-16 02:37:23 +00005999 if (LocaleCompare(keyword,"density") == 0)
6000 {
6001 flags=ParseGeometry(value,&geometry_info);
6002 msl_info->image[n]->x_resolution=geometry_info.rho;
6003 msl_info->image[n]->y_resolution=geometry_info.sigma;
6004 if ((flags & SigmaValue) == 0)
6005 msl_info->image[n]->y_resolution=
6006 msl_info->image[n]->x_resolution;
6007 break;
6008 }
6009 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006010 break;
6011 }
6012 case 'O':
6013 case 'o':
6014 {
6015 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006016 {
cristybb503372010-05-27 20:51:26 +00006017 ssize_t opac = OpaqueOpacity,
6018 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006019
cristy2c8b6312009-09-16 02:37:23 +00006020 if (value[len-1] == '%') {
6021 char tmp[100];
6022 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006023 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006024 opac = (int)(QuantumRange * ((float)opac/100));
6025 } else
cristyf2f27272009-12-17 14:48:46 +00006026 opac = StringToLong( value );
cristy2c8b6312009-09-16 02:37:23 +00006027 (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6028 break;
cristy3ed852e2009-09-05 21:47:34 +00006029 }
cristy2c8b6312009-09-16 02:37:23 +00006030 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006031 break;
6032 }
6033 case 'P':
6034 case 'p':
6035 {
6036 if (LocaleCompare(keyword, "page") == 0)
6037 {
6038 char
6039 page[MaxTextExtent];
6040
6041 const char
6042 *image_option;
6043
6044 MagickStatusType
6045 flags;
6046
6047 RectangleInfo
6048 geometry;
6049
6050 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6051 image_option=GetImageOption(msl_info->image_info[n],"page");
6052 if (image_option != (const char *) NULL)
6053 flags=ParseAbsoluteGeometry(image_option,&geometry);
6054 flags=ParseAbsoluteGeometry(value,&geometry);
cristye8c25f92010-06-03 00:53:06 +00006055 (void) FormatMagickString(page,MaxTextExtent,"%.20gx%.20g",
6056 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006057 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristyf2faecf2010-05-28 19:19:36 +00006058 (void) FormatMagickString(page,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00006059 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6060 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006061 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006062 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6063 msl_info->image_info[n]->page=GetPageGeometry(page);
6064 break;
6065 }
cristy2c8b6312009-09-16 02:37:23 +00006066 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006067 break;
6068 }
6069 default:
6070 {
cristy2c8b6312009-09-16 02:37:23 +00006071 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006072 break;
6073 }
6074 }
6075 }
6076 break;
6077 }
cristyb988fe72009-09-16 01:01:10 +00006078 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006079 {
6080 Image
6081 *shade_image;
6082
6083 MagickBooleanType
6084 gray;
6085
6086 /*
6087 Shade image.
6088 */
6089 if (msl_info->image[n] == (Image *) NULL)
6090 {
cristyb988fe72009-09-16 01:01:10 +00006091 ThrowMSLException(OptionError,"NoImagesDefined",
6092 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006093 break;
6094 }
6095 gray=MagickFalse;
6096 if (attributes != (const xmlChar **) NULL)
6097 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6098 {
6099 keyword=(const char *) attributes[i++];
6100 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006101 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006102 CloneString(&value,attribute);
6103 switch (*keyword)
6104 {
6105 case 'A':
6106 case 'a':
6107 {
6108 if (LocaleCompare(keyword,"azimuth") == 0)
6109 {
cristyf2f27272009-12-17 14:48:46 +00006110 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006111 break;
6112 }
6113 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6114 keyword);
6115 break;
6116 }
6117 case 'E':
6118 case 'e':
6119 {
6120 if (LocaleCompare(keyword,"elevation") == 0)
6121 {
cristyf2f27272009-12-17 14:48:46 +00006122 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006123 break;
6124 }
6125 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6126 keyword);
6127 break;
6128 }
6129 case 'G':
6130 case 'g':
6131 {
6132 if (LocaleCompare(keyword,"geometry") == 0)
6133 {
6134 flags=ParseGeometry(value,&geometry_info);
6135 if ((flags & SigmaValue) == 0)
6136 geometry_info.sigma=1.0;
6137 break;
6138 }
6139 if (LocaleCompare(keyword,"gray") == 0)
6140 {
cristy042ee782011-04-22 18:48:30 +00006141 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006142 value);
6143 if (option < 0)
6144 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6145 value);
6146 gray=(MagickBooleanType) option;
6147 break;
6148 }
6149 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6150 keyword);
6151 break;
6152 }
6153 default:
6154 {
6155 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6156 keyword);
6157 break;
6158 }
6159 }
6160 }
6161 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6162 geometry_info.sigma,&msl_info->image[n]->exception);
6163 if (shade_image == (Image *) NULL)
6164 break;
6165 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6166 msl_info->image[n]=shade_image;
6167 break;
6168 }
cristyb988fe72009-09-16 01:01:10 +00006169 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006170 {
6171 Image
6172 *shadow_image;
6173
6174 /*
6175 Shear image.
6176 */
6177 if (msl_info->image[n] == (Image *) NULL)
6178 {
cristyb988fe72009-09-16 01:01:10 +00006179 ThrowMSLException(OptionError,"NoImagesDefined",
6180 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006181 break;
6182 }
6183 if (attributes != (const xmlChar **) NULL)
6184 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6185 {
6186 keyword=(const char *) attributes[i++];
6187 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006188 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006189 CloneString(&value,attribute);
6190 switch (*keyword)
6191 {
6192 case 'G':
6193 case 'g':
6194 {
6195 if (LocaleCompare(keyword,"geometry") == 0)
6196 {
6197 flags=ParseGeometry(value,&geometry_info);
6198 if ((flags & SigmaValue) == 0)
6199 geometry_info.sigma=1.0;
6200 break;
6201 }
6202 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6203 keyword);
6204 break;
6205 }
6206 case 'O':
6207 case 'o':
6208 {
6209 if (LocaleCompare(keyword,"opacity") == 0)
6210 {
cristyf2f27272009-12-17 14:48:46 +00006211 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006212 break;
6213 }
6214 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6215 keyword);
6216 break;
6217 }
6218 case 'S':
6219 case 's':
6220 {
6221 if (LocaleCompare(keyword,"sigma") == 0)
6222 {
cristyf2f27272009-12-17 14:48:46 +00006223 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006224 break;
6225 }
6226 break;
6227 }
6228 case 'X':
6229 case 'x':
6230 {
6231 if (LocaleCompare(keyword,"x") == 0)
6232 {
cristyf2f27272009-12-17 14:48:46 +00006233 geometry_info.xi=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006234 break;
6235 }
6236 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6237 keyword);
6238 break;
6239 }
6240 case 'Y':
6241 case 'y':
6242 {
6243 if (LocaleCompare(keyword,"y") == 0)
6244 {
cristyf2f27272009-12-17 14:48:46 +00006245 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006246 break;
6247 }
6248 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6249 keyword);
6250 break;
6251 }
6252 default:
6253 {
6254 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6255 keyword);
6256 break;
6257 }
6258 }
6259 }
6260 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristybb503372010-05-27 20:51:26 +00006261 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
cristy0534a6b2010-03-18 01:19:38 +00006262 ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006263 if (shadow_image == (Image *) NULL)
6264 break;
6265 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6266 msl_info->image[n]=shadow_image;
6267 break;
6268 }
cristyb988fe72009-09-16 01:01:10 +00006269 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006270 {
6271 double radius = 0.0,
6272 sigma = 1.0;
6273
6274 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006275 {
6276 ThrowMSLException(OptionError,"NoImagesDefined",
6277 (const char *) tag);
6278 break;
6279 }
cristy3ed852e2009-09-05 21:47:34 +00006280 /*
6281 NOTE: sharpen can have no attributes, since we use all the defaults!
6282 */
6283 if (attributes != (const xmlChar **) NULL)
6284 {
6285 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6286 {
6287 keyword=(const char *) attributes[i++];
6288 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006289 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006290 switch (*keyword)
6291 {
6292 case 'R':
6293 case 'r':
6294 {
6295 if (LocaleCompare(keyword, "radius") == 0)
6296 {
cristyf2f27272009-12-17 14:48:46 +00006297 radius = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00006298 break;
6299 }
6300 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6301 break;
6302 }
6303 case 'S':
6304 case 's':
6305 {
6306 if (LocaleCompare(keyword,"sigma") == 0)
6307 {
cristyf2f27272009-12-17 14:48:46 +00006308 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006309 break;
6310 }
6311 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6312 break;
6313 }
6314 default:
6315 {
6316 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6317 break;
6318 }
6319 }
6320 }
6321 }
6322
6323 /*
6324 sharpen image.
6325 */
6326 {
6327 Image
6328 *newImage;
6329
6330 newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6331 if (newImage == (Image *) NULL)
6332 break;
6333 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6334 msl_info->image[n]=newImage;
6335 break;
6336 }
6337 }
cristyb988fe72009-09-16 01:01:10 +00006338 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006339 {
6340 /* init the values */
6341 width = height = 0;
6342 x = y = 0;
6343
6344 if (msl_info->image[n] == (Image *) NULL)
6345 {
cristyb988fe72009-09-16 01:01:10 +00006346 ThrowMSLException(OptionError,"NoImagesDefined",
6347 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006348 break;
6349 }
6350 if (attributes == (const xmlChar **) NULL)
6351 break;
6352 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6353 {
6354 keyword=(const char *) attributes[i++];
6355 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006356 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006357 switch (*keyword)
6358 {
6359 case 'G':
6360 case 'g':
6361 {
6362 if (LocaleCompare(keyword,"geometry") == 0)
6363 {
6364 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6365 break;
6366 }
6367 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6368 break;
6369 }
6370 case 'H':
6371 case 'h':
6372 {
6373 if (LocaleCompare(keyword,"height") == 0)
6374 {
cristyf2f27272009-12-17 14:48:46 +00006375 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006376 break;
6377 }
6378 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6379 break;
6380 }
6381 case 'W':
6382 case 'w':
6383 {
6384 if (LocaleCompare(keyword,"width") == 0)
6385 {
cristyf2f27272009-12-17 14:48:46 +00006386 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006387 break;
6388 }
6389 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6390 break;
6391 }
6392 default:
6393 {
6394 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6395 break;
6396 }
6397 }
6398 }
6399
6400 /*
6401 process image.
6402 */
6403 {
6404 Image
6405 *newImage;
6406 RectangleInfo
6407 rectInfo;
6408
6409 rectInfo.height = height;
6410 rectInfo.width = width;
6411 rectInfo.x = x;
6412 rectInfo.y = y;
6413
6414
6415 newImage=ShaveImage(msl_info->image[n], &rectInfo,
6416 &msl_info->image[n]->exception);
6417 if (newImage == (Image *) NULL)
6418 break;
6419 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6420 msl_info->image[n]=newImage;
6421 }
6422
6423 break;
6424 }
cristyb988fe72009-09-16 01:01:10 +00006425 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006426 {
6427 Image
6428 *shear_image;
6429
6430 /*
6431 Shear image.
6432 */
6433 if (msl_info->image[n] == (Image *) NULL)
6434 {
cristyb988fe72009-09-16 01:01:10 +00006435 ThrowMSLException(OptionError,"NoImagesDefined",
6436 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006437 break;
6438 }
6439 if (attributes != (const xmlChar **) NULL)
6440 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6441 {
6442 keyword=(const char *) attributes[i++];
6443 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006444 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006445 CloneString(&value,attribute);
6446 switch (*keyword)
6447 {
6448 case 'F':
6449 case 'f':
6450 {
6451 if (LocaleCompare(keyword, "fill") == 0)
6452 {
6453 (void) QueryColorDatabase(value,
6454 &msl_info->image[n]->background_color,&exception);
6455 break;
6456 }
6457 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6458 keyword);
6459 break;
6460 }
6461 case 'G':
6462 case 'g':
6463 {
6464 if (LocaleCompare(keyword,"geometry") == 0)
6465 {
6466 flags=ParseGeometry(value,&geometry_info);
6467 if ((flags & SigmaValue) == 0)
6468 geometry_info.sigma=1.0;
6469 break;
6470 }
6471 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6472 keyword);
6473 break;
6474 }
6475 case 'X':
6476 case 'x':
6477 {
6478 if (LocaleCompare(keyword,"x") == 0)
6479 {
cristyf2f27272009-12-17 14:48:46 +00006480 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006481 break;
6482 }
6483 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6484 keyword);
6485 break;
6486 }
6487 case 'Y':
6488 case 'y':
6489 {
6490 if (LocaleCompare(keyword,"y") == 0)
6491 {
cristyf2f27272009-12-17 14:48:46 +00006492 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006493 break;
6494 }
6495 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6496 keyword);
6497 break;
6498 }
6499 default:
6500 {
6501 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6502 keyword);
6503 break;
6504 }
6505 }
6506 }
6507 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6508 geometry_info.sigma,&msl_info->image[n]->exception);
6509 if (shear_image == (Image *) NULL)
6510 break;
6511 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6512 msl_info->image[n]=shear_image;
6513 break;
6514 }
cristyb988fe72009-09-16 01:01:10 +00006515 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006516 {
6517 /*
6518 Signature image.
6519 */
6520 if (msl_info->image[n] == (Image *) NULL)
6521 {
cristyb988fe72009-09-16 01:01:10 +00006522 ThrowMSLException(OptionError,"NoImagesDefined",
6523 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006524 break;
6525 }
6526 if (attributes != (const xmlChar **) NULL)
6527 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6528 {
6529 keyword=(const char *) attributes[i++];
6530 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006531 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006532 CloneString(&value,attribute);
6533 switch (*keyword)
6534 {
6535 default:
6536 {
6537 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6538 keyword);
6539 break;
6540 }
6541 }
6542 }
6543 (void) SignatureImage(msl_info->image[n]);
6544 break;
6545 }
cristyb988fe72009-09-16 01:01:10 +00006546 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006547 {
6548 /*
6549 Solarize image.
6550 */
6551 if (msl_info->image[n] == (Image *) NULL)
6552 {
cristyb988fe72009-09-16 01:01:10 +00006553 ThrowMSLException(OptionError,"NoImagesDefined",
6554 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006555 break;
6556 }
6557 geometry_info.rho=QuantumRange/2.0;
6558 if (attributes != (const xmlChar **) NULL)
6559 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6560 {
6561 keyword=(const char *) attributes[i++];
6562 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006563 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006564 CloneString(&value,attribute);
6565 switch (*keyword)
6566 {
6567 case 'G':
6568 case 'g':
6569 {
6570 if (LocaleCompare(keyword,"geometry") == 0)
6571 {
6572 flags=ParseGeometry(value,&geometry_info);
6573 break;
6574 }
6575 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6576 keyword);
6577 break;
6578 }
6579 case 'T':
6580 case 't':
6581 {
6582 if (LocaleCompare(keyword,"threshold") == 0)
6583 {
cristyf2f27272009-12-17 14:48:46 +00006584 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006585 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 (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6600 break;
6601 }
cristyb988fe72009-09-16 01:01:10 +00006602 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006603 {
6604 Image
6605 *spread_image;
6606
6607 /*
6608 Spread image.
6609 */
6610 if (msl_info->image[n] == (Image *) NULL)
6611 {
cristyb988fe72009-09-16 01:01:10 +00006612 ThrowMSLException(OptionError,"NoImagesDefined",
6613 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006614 break;
6615 }
6616 if (attributes != (const xmlChar **) NULL)
6617 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6618 {
6619 keyword=(const char *) attributes[i++];
6620 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006621 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006622 CloneString(&value,attribute);
6623 switch (*keyword)
6624 {
6625 case 'G':
6626 case 'g':
6627 {
6628 if (LocaleCompare(keyword,"geometry") == 0)
6629 {
6630 flags=ParseGeometry(value,&geometry_info);
6631 if ((flags & SigmaValue) == 0)
6632 geometry_info.sigma=1.0;
6633 break;
6634 }
6635 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6636 keyword);
6637 break;
6638 }
6639 case 'R':
6640 case 'r':
6641 {
6642 if (LocaleCompare(keyword,"radius") == 0)
6643 {
cristyf2f27272009-12-17 14:48:46 +00006644 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006645 break;
6646 }
6647 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6648 keyword);
6649 break;
6650 }
6651 default:
6652 {
6653 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6654 keyword);
6655 break;
6656 }
6657 }
6658 }
6659 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6660 &msl_info->image[n]->exception);
6661 if (spread_image == (Image *) NULL)
6662 break;
6663 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6664 msl_info->image[n]=spread_image;
6665 break;
6666 }
cristyb988fe72009-09-16 01:01:10 +00006667 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006668 {
6669 Image *
6670 watermark = (Image*)NULL;
6671
6672 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006673 {
6674 ThrowMSLException(OptionError,"NoImagesDefined",
6675 (const char *) tag);
6676 break;
6677 }
cristy3ed852e2009-09-05 21:47:34 +00006678 if (attributes == (const xmlChar **) NULL)
6679 break;
6680 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6681 {
6682 keyword=(const char *) attributes[i++];
6683 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006684 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006685 switch (*keyword)
6686 {
6687 case 'I':
6688 case 'i':
6689 {
6690 if (LocaleCompare(keyword,"image") == 0)
6691 {
6692 for (j=0; j<msl_info->n;j++)
6693 {
6694 const char *
6695 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6696 if (theAttr && LocaleCompare(theAttr, value) == 0)
6697 {
6698 watermark = msl_info->image[j];
6699 break;
6700 }
6701 }
6702 break;
6703 }
6704 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6705 break;
6706 }
6707 default:
6708 {
6709 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6710 break;
6711 }
6712 }
6713 }
6714
6715 /*
6716 process image.
6717 */
6718 if ( watermark != (Image*) NULL )
6719 {
6720 Image
6721 *newImage;
6722
6723 newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6724 if (newImage == (Image *) NULL)
6725 break;
6726 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6727 msl_info->image[n]=newImage;
6728 break;
6729 } else
6730 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6731 }
cristyb988fe72009-09-16 01:01:10 +00006732 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006733 {
6734 Image *
6735 stereoImage = (Image*)NULL;
6736
6737 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006738 {
6739 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6740 break;
6741 }
cristy3ed852e2009-09-05 21:47:34 +00006742 if (attributes == (const xmlChar **) NULL)
6743 break;
6744 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6745 {
6746 keyword=(const char *) attributes[i++];
6747 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006748 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006749 switch (*keyword)
6750 {
6751 case 'I':
6752 case 'i':
6753 {
6754 if (LocaleCompare(keyword,"image") == 0)
6755 {
6756 for (j=0; j<msl_info->n;j++)
6757 {
6758 const char *
6759 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6760 if (theAttr && LocaleCompare(theAttr, value) == 0)
6761 {
6762 stereoImage = msl_info->image[j];
6763 break;
6764 }
6765 }
6766 break;
6767 }
6768 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6769 break;
6770 }
6771 default:
6772 {
6773 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6774 break;
6775 }
6776 }
6777 }
6778
6779 /*
6780 process image.
6781 */
6782 if ( stereoImage != (Image*) NULL )
6783 {
6784 Image
6785 *newImage;
6786
6787 newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6788 if (newImage == (Image *) NULL)
6789 break;
6790 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6791 msl_info->image[n]=newImage;
6792 break;
6793 } else
6794 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6795 }
cristyb988fe72009-09-16 01:01:10 +00006796 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006797 {
6798 Image
6799 *p,
6800 *q,
6801 *swap;
6802
cristybb503372010-05-27 20:51:26 +00006803 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006804 index,
6805 swap_index;
6806
6807 if (msl_info->image[n] == (Image *) NULL)
6808 {
cristyb988fe72009-09-16 01:01:10 +00006809 ThrowMSLException(OptionError,"NoImagesDefined",
6810 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006811 break;
6812 }
6813 index=(-1);
6814 swap_index=(-2);
6815 if (attributes != (const xmlChar **) NULL)
6816 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6817 {
6818 keyword=(const char *) attributes[i++];
6819 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006820 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006821 CloneString(&value,attribute);
6822 switch (*keyword)
6823 {
6824 case 'G':
6825 case 'g':
6826 {
6827 if (LocaleCompare(keyword,"indexes") == 0)
6828 {
6829 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006830 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006831 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006832 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006833 break;
6834 }
6835 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6836 keyword);
6837 break;
6838 }
6839 default:
6840 {
6841 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6842 keyword);
6843 break;
6844 }
6845 }
6846 }
6847 /*
6848 Swap images.
6849 */
6850 p=GetImageFromList(msl_info->image[n],index);
6851 q=GetImageFromList(msl_info->image[n],swap_index);
6852 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6853 {
cristyb988fe72009-09-16 01:01:10 +00006854 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006855 break;
6856 }
6857 swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6858 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6859 ReplaceImageInList(&q,swap);
6860 msl_info->image[n]=GetFirstImageInList(q);
6861 break;
6862 }
cristyb988fe72009-09-16 01:01:10 +00006863 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006864 {
6865 Image
6866 *swirl_image;
6867
6868 /*
6869 Swirl image.
6870 */
6871 if (msl_info->image[n] == (Image *) NULL)
6872 {
cristyb988fe72009-09-16 01:01:10 +00006873 ThrowMSLException(OptionError,"NoImagesDefined",
6874 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006875 break;
6876 }
6877 if (attributes != (const xmlChar **) NULL)
6878 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6879 {
6880 keyword=(const char *) attributes[i++];
6881 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006882 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006883 CloneString(&value,attribute);
6884 switch (*keyword)
6885 {
6886 case 'D':
6887 case 'd':
6888 {
6889 if (LocaleCompare(keyword,"degrees") == 0)
6890 {
cristyf2f27272009-12-17 14:48:46 +00006891 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006892 break;
6893 }
6894 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6895 keyword);
6896 break;
6897 }
6898 case 'G':
6899 case 'g':
6900 {
6901 if (LocaleCompare(keyword,"geometry") == 0)
6902 {
6903 flags=ParseGeometry(value,&geometry_info);
6904 if ((flags & SigmaValue) == 0)
6905 geometry_info.sigma=1.0;
6906 break;
6907 }
6908 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6909 keyword);
6910 break;
6911 }
6912 default:
6913 {
6914 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6915 keyword);
6916 break;
6917 }
6918 }
6919 }
6920 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6921 &msl_info->image[n]->exception);
6922 if (swirl_image == (Image *) NULL)
6923 break;
6924 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6925 msl_info->image[n]=swirl_image;
6926 break;
6927 }
cristyb988fe72009-09-16 01:01:10 +00006928 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006929 {
6930 /*
6931 Sync image.
6932 */
6933 if (msl_info->image[n] == (Image *) NULL)
6934 {
cristyb988fe72009-09-16 01:01:10 +00006935 ThrowMSLException(OptionError,"NoImagesDefined",
6936 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006937 break;
6938 }
6939 if (attributes != (const xmlChar **) NULL)
6940 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6941 {
6942 keyword=(const char *) attributes[i++];
6943 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006944 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006945 CloneString(&value,attribute);
6946 switch (*keyword)
6947 {
6948 default:
6949 {
6950 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6951 keyword);
6952 break;
6953 }
6954 }
6955 }
6956 (void) SyncImage(msl_info->image[n]);
6957 break;
6958 }
6959 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6960 }
6961 case 'T':
6962 case 't':
6963 {
cristyb988fe72009-09-16 01:01:10 +00006964 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006965 {
6966 Image
6967 *texture_image;
6968
6969 /*
6970 Texture image.
6971 */
6972 if (msl_info->image[n] == (Image *) NULL)
6973 {
cristyb988fe72009-09-16 01:01:10 +00006974 ThrowMSLException(OptionError,"NoImagesDefined",
6975 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006976 break;
6977 }
6978 texture_image=NewImageList();
6979 if (attributes != (const xmlChar **) NULL)
6980 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6981 {
6982 keyword=(const char *) attributes[i++];
6983 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006984 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006985 CloneString(&value,attribute);
6986 switch (*keyword)
6987 {
6988 case 'I':
6989 case 'i':
6990 {
6991 if (LocaleCompare(keyword,"image") == 0)
6992 for (j=0; j < msl_info->n; j++)
6993 {
6994 const char
6995 *attribute;
cristyb988fe72009-09-16 01:01:10 +00006996
cristy3ed852e2009-09-05 21:47:34 +00006997 attribute=GetImageProperty(msl_info->attributes[j],"id");
6998 if ((attribute != (const char *) NULL) &&
6999 (LocaleCompare(attribute,value) == 0))
7000 {
7001 texture_image=CloneImage(msl_info->image[j],0,0,
7002 MagickFalse,&exception);
7003 break;
7004 }
7005 }
7006 break;
7007 }
7008 default:
7009 {
7010 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7011 keyword);
7012 break;
7013 }
7014 }
7015 }
7016 (void) TextureImage(msl_info->image[n],texture_image);
7017 texture_image=DestroyImage(texture_image);
7018 break;
7019 }
cristyb988fe72009-09-16 01:01:10 +00007020 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007021 {
7022 /* init the values */
7023 double threshold = 0;
7024
7025 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007026 {
7027 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7028 break;
7029 }
cristy3ed852e2009-09-05 21:47:34 +00007030 if (attributes == (const xmlChar **) NULL)
7031 break;
7032 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7033 {
7034 keyword=(const char *) attributes[i++];
7035 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007036 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007037 switch (*keyword)
7038 {
7039 case 'T':
7040 case 't':
7041 {
7042 if (LocaleCompare(keyword,"threshold") == 0)
7043 {
cristyf2f27272009-12-17 14:48:46 +00007044 threshold = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00007045 break;
7046 }
7047 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7048 break;
7049 }
7050 default:
7051 {
7052 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7053 break;
7054 }
7055 }
7056 }
7057
7058 /*
7059 process image.
7060 */
7061 {
7062 BilevelImageChannel(msl_info->image[n],
cristy9a9230e2011-04-26 14:56:14 +00007063 (ChannelType) ((ssize_t) (CompositeChannels &~ (ssize_t) OpacityChannel)),
cristy3ed852e2009-09-05 21:47:34 +00007064 threshold);
7065 break;
7066 }
7067 }
cristyb988fe72009-09-16 01:01:10 +00007068 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007069 {
7070 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007071 {
7072 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7073 break;
7074 }
cristy3ed852e2009-09-05 21:47:34 +00007075 if (attributes == (const xmlChar **) NULL)
7076 break;
7077 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7078 {
7079 keyword=(const char *) attributes[i++];
7080 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007081 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007082 switch (*keyword)
7083 {
7084 case 'C':
7085 case 'c':
7086 {
7087 if (LocaleCompare(keyword,"color") == 0)
7088 {
7089 MagickPixelPacket
7090 target;
7091
7092 (void) QueryMagickColor(value,&target,&exception);
7093 (void) TransparentPaintImage(msl_info->image[n],&target,
7094 TransparentOpacity,MagickFalse);
7095 break;
7096 }
7097 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7098 break;
7099 }
7100 default:
7101 {
7102 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7103 break;
7104 }
7105 }
7106 }
7107 break;
7108 }
cristyb988fe72009-09-16 01:01:10 +00007109 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007110 {
7111 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007112 {
7113 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7114 break;
7115 }
cristy3ed852e2009-09-05 21:47:34 +00007116
7117 /* no attributes here */
7118
7119 /* process the image */
7120 {
7121 Image
7122 *newImage;
7123 RectangleInfo
7124 rectInfo;
7125
7126 /* all zeros on a crop == trim edges! */
7127 rectInfo.height = rectInfo.width = 0;
7128 rectInfo.x = rectInfo.y = 0;
7129
7130 newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7131 if (newImage == (Image *) NULL)
7132 break;
7133 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7134 msl_info->image[n]=newImage;
7135 break;
7136 }
7137 }
7138 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7139 }
7140 case 'W':
7141 case 'w':
7142 {
cristyb988fe72009-09-16 01:01:10 +00007143 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007144 {
7145 if (msl_info->image[n] == (Image *) NULL)
7146 {
cristyb988fe72009-09-16 01:01:10 +00007147 ThrowMSLException(OptionError,"NoImagesDefined",
7148 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007149 break;
7150 }
7151 if (attributes == (const xmlChar **) NULL)
7152 break;
7153 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7154 {
7155 keyword=(const char *) attributes[i++];
7156 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007157 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007158 switch (*keyword)
7159 {
7160 case 'F':
7161 case 'f':
7162 {
7163 if (LocaleCompare(keyword,"filename") == 0)
7164 {
7165 (void) CopyMagickString(msl_info->image[n]->filename,value,
7166 MaxTextExtent);
7167 break;
7168 }
cristy4582cbb2009-09-23 00:35:43 +00007169 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007170 }
7171 default:
7172 {
cristy4582cbb2009-09-23 00:35:43 +00007173 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007174 break;
7175 }
7176 }
7177 }
7178
7179 /* process */
7180 {
7181 (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7182 break;
7183 }
7184 }
7185 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7186 }
7187 default:
7188 {
7189 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7190 break;
7191 }
7192 }
7193 if ( value != NULL )
7194 value=DestroyString(value);
7195 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7196}
7197
7198static void MSLEndElement(void *context,const xmlChar *tag)
7199{
cristybb503372010-05-27 20:51:26 +00007200 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007201 n;
7202
7203 MSLInfo
7204 *msl_info;
7205
7206 /*
7207 Called when the end of an element has been detected.
7208 */
7209 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7210 tag);
7211 msl_info=(MSLInfo *) context;
7212 n=msl_info->n;
7213 switch (*tag)
7214 {
7215 case 'C':
7216 case 'c':
7217 {
cristyb988fe72009-09-16 01:01:10 +00007218 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007219 {
7220 (void) DeleteImageProperty(msl_info->image[n],"comment");
7221 if (msl_info->content == (char *) NULL)
7222 break;
7223 StripString(msl_info->content);
7224 (void) SetImageProperty(msl_info->image[n],"comment",
7225 msl_info->content);
7226 break;
7227 }
7228 break;
7229 }
7230 case 'G':
7231 case 'g':
7232 {
cristyb988fe72009-09-16 01:01:10 +00007233 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007234 {
7235 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7236 {
cristybb503372010-05-27 20:51:26 +00007237 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007238 (msl_info->group_info[msl_info->number_groups-1].numImages);
7239 while ( i-- )
7240 {
7241 if (msl_info->image[msl_info->n] != (Image *) NULL)
7242 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7243 msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7244 msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7245 msl_info->n--;
7246 }
7247 }
7248 msl_info->number_groups--;
7249 }
7250 break;
7251 }
7252 case 'I':
7253 case 'i':
7254 {
cristyb988fe72009-09-16 01:01:10 +00007255 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007256 MSLPopImage(msl_info);
7257 break;
7258 }
7259 case 'L':
7260 case 'l':
7261 {
cristyb988fe72009-09-16 01:01:10 +00007262 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007263 {
7264 (void) DeleteImageProperty(msl_info->image[n],"label");
7265 if (msl_info->content == (char *) NULL)
7266 break;
7267 StripString(msl_info->content);
7268 (void) SetImageProperty(msl_info->image[n],"label",
7269 msl_info->content);
7270 break;
7271 }
7272 break;
7273 }
7274 case 'M':
7275 case 'm':
7276 {
cristyb988fe72009-09-16 01:01:10 +00007277 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007278 {
7279 /*
7280 This our base element.
7281 at the moment we don't do anything special
7282 but someday we might!
7283 */
7284 }
7285 break;
7286 }
7287 default:
7288 break;
7289 }
7290 if (msl_info->content != (char *) NULL)
7291 msl_info->content=DestroyString(msl_info->content);
7292}
7293
7294static void MSLCharacters(void *context,const xmlChar *c,int length)
7295{
7296 MSLInfo
7297 *msl_info;
7298
7299 register char
7300 *p;
7301
cristybb503372010-05-27 20:51:26 +00007302 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007303 i;
7304
7305 /*
7306 Receiving some characters from the parser.
7307 */
7308 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7309 " SAX.characters(%s,%d)",c,length);
7310 msl_info=(MSLInfo *) context;
7311 if (msl_info->content != (char *) NULL)
7312 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7313 strlen(msl_info->content)+length+MaxTextExtent,
7314 sizeof(*msl_info->content));
7315 else
7316 {
7317 msl_info->content=(char *) NULL;
7318 if (~length >= MaxTextExtent)
7319 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7320 sizeof(*msl_info->content));
7321 if (msl_info->content != (char *) NULL)
7322 *msl_info->content='\0';
7323 }
7324 if (msl_info->content == (char *) NULL)
7325 return;
7326 p=msl_info->content+strlen(msl_info->content);
7327 for (i=0; i < length; i++)
7328 *p++=c[i];
7329 *p='\0';
7330}
7331
7332static void MSLReference(void *context,const xmlChar *name)
7333{
7334 MSLInfo
7335 *msl_info;
7336
7337 xmlParserCtxtPtr
7338 parser;
7339
7340 /*
7341 Called when an entity reference is detected.
7342 */
7343 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7344 " SAX.reference(%s)",name);
7345 msl_info=(MSLInfo *) context;
7346 parser=msl_info->parser;
7347 if (*name == '#')
7348 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7349 else
7350 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7351}
7352
7353static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7354{
7355 MSLInfo
7356 *msl_info;
7357
7358 /*
7359 Receiving some ignorable whitespaces from the parser.
7360 */
7361 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7362 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7363 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007364 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007365}
7366
7367static void MSLProcessingInstructions(void *context,const xmlChar *target,
7368 const xmlChar *data)
7369{
7370 MSLInfo
7371 *msl_info;
7372
7373 /*
7374 A processing instruction has been parsed.
7375 */
7376 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7377 " SAX.processingInstruction(%s, %s)",
7378 target,data);
7379 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007380 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007381}
7382
7383static void MSLComment(void *context,const xmlChar *value)
7384{
7385 MSLInfo
7386 *msl_info;
7387
7388 /*
7389 A comment has been parsed.
7390 */
7391 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7392 " SAX.comment(%s)",value);
7393 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007394 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007395}
7396
7397static void MSLWarning(void *context,const char *format,...)
7398{
7399 char
7400 *message,
7401 reason[MaxTextExtent];
7402
7403 MSLInfo
7404 *msl_info;
7405
7406 va_list
7407 operands;
7408
7409 /**
7410 Display and format a warning messages, gives file, line, position and
7411 extra parameters.
7412 */
7413 va_start(operands,format);
7414 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7415 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7416 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007417 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007418#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7419 (void) vsprintf(reason,format,operands);
7420#else
7421 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7422#endif
7423 message=GetExceptionMessage(errno);
7424 ThrowMSLException(CoderError,reason,message);
7425 message=DestroyString(message);
7426 va_end(operands);
7427}
7428
7429static void MSLError(void *context,const char *format,...)
7430{
7431 char
7432 reason[MaxTextExtent];
7433
7434 MSLInfo
7435 *msl_info;
7436
7437 va_list
7438 operands;
7439
7440 /*
7441 Display and format a error formats, gives file, line, position and
7442 extra parameters.
7443 */
7444 va_start(operands,format);
7445 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7446 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7447 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007448 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007449#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7450 (void) vsprintf(reason,format,operands);
7451#else
7452 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7453#endif
7454 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7455 va_end(operands);
7456}
7457
7458static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7459{
7460 MSLInfo
7461 *msl_info;
7462
7463 xmlNodePtr
7464 child;
7465
7466 xmlParserCtxtPtr
7467 parser;
7468
7469 /*
7470 Called when a pcdata block has been parsed.
7471 */
7472 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7473 " SAX.pcdata(%s, %d)",value,length);
7474 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007475 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007476 parser=msl_info->parser;
7477 child=xmlGetLastChild(parser->node);
7478 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7479 {
7480 xmlTextConcat(child,value,length);
7481 return;
7482 }
7483 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7484}
7485
7486static void MSLExternalSubset(void *context,const xmlChar *name,
7487 const xmlChar *external_id,const xmlChar *system_id)
7488{
7489 MSLInfo
7490 *msl_info;
7491
7492 xmlParserCtxt
7493 parser_context;
7494
7495 xmlParserCtxtPtr
7496 parser;
7497
7498 xmlParserInputPtr
7499 input;
7500
7501 /*
7502 Does this document has an external subset?
7503 */
7504 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7505 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007506 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7507 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007508 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007509 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007510 parser=msl_info->parser;
7511 if (((external_id == NULL) && (system_id == NULL)) ||
7512 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7513 (msl_info->document == 0)))
7514 return;
7515 input=MSLResolveEntity(context,external_id,system_id);
7516 if (input == NULL)
7517 return;
7518 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7519 parser_context=(*parser);
7520 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7521 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7522 {
7523 parser->errNo=XML_ERR_NO_MEMORY;
7524 parser->input=parser_context.input;
7525 parser->inputNr=parser_context.inputNr;
7526 parser->inputMax=parser_context.inputMax;
7527 parser->inputTab=parser_context.inputTab;
7528 return;
7529 }
7530 parser->inputNr=0;
7531 parser->inputMax=5;
7532 parser->input=NULL;
7533 xmlPushInput(parser,input);
7534 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7535 if (input->filename == (char *) NULL)
7536 input->filename=(char *) xmlStrdup(system_id);
7537 input->line=1;
7538 input->col=1;
7539 input->base=parser->input->cur;
7540 input->cur=parser->input->cur;
7541 input->free=NULL;
7542 xmlParseExternalSubset(parser,external_id,system_id);
7543 while (parser->inputNr > 1)
7544 (void) xmlPopInput(parser);
7545 xmlFreeInputStream(parser->input);
7546 xmlFree(parser->inputTab);
7547 parser->input=parser_context.input;
7548 parser->inputNr=parser_context.inputNr;
7549 parser->inputMax=parser_context.inputMax;
7550 parser->inputTab=parser_context.inputTab;
7551}
7552
7553#if defined(__cplusplus) || defined(c_plusplus)
7554}
7555#endif
7556
7557static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7558 ExceptionInfo *exception)
7559{
cristy3ed852e2009-09-05 21:47:34 +00007560 char
7561 message[MaxTextExtent];
7562
7563 Image
7564 *msl_image;
7565
7566 int
7567 status;
7568
cristybb503372010-05-27 20:51:26 +00007569 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007570 n;
7571
7572 MSLInfo
7573 msl_info;
7574
cristy5f6f01c2009-11-19 19:36:42 +00007575 xmlSAXHandler
7576 sax_modules;
7577
cristy3ed852e2009-09-05 21:47:34 +00007578 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007579 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007580
7581 /*
7582 Open image file.
7583 */
7584 assert(image_info != (const ImageInfo *) NULL);
7585 assert(image_info->signature == MagickSignature);
7586 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007587 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7588 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007589 assert(image != (Image **) NULL);
7590 msl_image=AcquireImage(image_info);
7591 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7592 if (status == MagickFalse)
7593 {
7594 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7595 msl_image->filename);
7596 msl_image=DestroyImageList(msl_image);
7597 return(MagickFalse);
7598 }
7599 msl_image->columns=1;
7600 msl_image->rows=1;
7601 /*
7602 Parse MSL file.
7603 */
7604 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7605 msl_info.exception=exception;
7606 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7607 sizeof(*msl_info.image_info));
7608 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7609 sizeof(*msl_info.draw_info));
7610 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007611 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007612 msl_info.attributes=(Image **) AcquireMagickMemory(
7613 sizeof(*msl_info.attributes));
7614 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7615 sizeof(*msl_info.group_info));
7616 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7617 (msl_info.image == (Image **) NULL) ||
7618 (msl_info.attributes == (Image **) NULL) ||
7619 (msl_info.group_info == (MSLGroupInfo *) NULL))
7620 ThrowFatalException(ResourceLimitFatalError,
7621 "UnableToInterpretMSLImage");
7622 *msl_info.image_info=CloneImageInfo(image_info);
7623 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7624 *msl_info.attributes=AcquireImage(image_info);
7625 msl_info.group_info[0].numImages=0;
7626 /* the first slot is used to point to the MSL file image */
7627 *msl_info.image=msl_image;
7628 if (*image != (Image *) NULL)
7629 MSLPushImage(&msl_info,*image);
7630 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007631 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7632 sax_modules.internalSubset=MSLInternalSubset;
7633 sax_modules.isStandalone=MSLIsStandalone;
7634 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7635 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7636 sax_modules.resolveEntity=MSLResolveEntity;
7637 sax_modules.getEntity=MSLGetEntity;
7638 sax_modules.entityDecl=MSLEntityDeclaration;
7639 sax_modules.notationDecl=MSLNotationDeclaration;
7640 sax_modules.attributeDecl=MSLAttributeDeclaration;
7641 sax_modules.elementDecl=MSLElementDeclaration;
7642 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7643 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7644 sax_modules.startDocument=MSLStartDocument;
7645 sax_modules.endDocument=MSLEndDocument;
7646 sax_modules.startElement=MSLStartElement;
7647 sax_modules.endElement=MSLEndElement;
7648 sax_modules.reference=MSLReference;
7649 sax_modules.characters=MSLCharacters;
7650 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7651 sax_modules.processingInstruction=MSLProcessingInstructions;
7652 sax_modules.comment=MSLComment;
7653 sax_modules.warning=MSLWarning;
7654 sax_modules.error=MSLError;
7655 sax_modules.fatalError=MSLError;
7656 sax_modules.getParameterEntity=MSLGetParameterEntity;
7657 sax_modules.cdataBlock=MSLCDataBlock;
7658 sax_modules.externalSubset=MSLExternalSubset;
7659 sax_handler=(&sax_modules);
7660 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007661 msl_image->filename);
7662 while (ReadBlobString(msl_image,message) != (char *) NULL)
7663 {
cristybb503372010-05-27 20:51:26 +00007664 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007665 if (n == 0)
7666 continue;
7667 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7668 if (status != 0)
7669 break;
7670 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7671 if (msl_info.exception->severity >= ErrorException)
7672 break;
7673 }
7674 if (msl_info.exception->severity == UndefinedException)
7675 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7676 xmlFreeParserCtxt(msl_info.parser);
7677 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7678 xmlCleanupParser();
7679 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7680 msl_info.group_info);
7681 if (*image == (Image *) NULL)
7682 *image=(*msl_info.image);
cristy5f6f01c2009-11-19 19:36:42 +00007683 if ((*msl_info.image)->exception.severity != UndefinedException)
7684 return(MagickFalse);
7685 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007686}
7687
7688static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7689{
7690 Image
7691 *image;
7692
7693 /*
7694 Open image file.
7695 */
7696 assert(image_info != (const ImageInfo *) NULL);
7697 assert(image_info->signature == MagickSignature);
7698 if (image_info->debug != MagickFalse)
7699 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7700 image_info->filename);
7701 assert(exception != (ExceptionInfo *) NULL);
7702 assert(exception->signature == MagickSignature);
7703 image=(Image *) NULL;
7704 (void) ProcessMSLScript(image_info,&image,exception);
7705 return(GetFirstImageInList(image));
7706}
7707#endif
7708
7709/*
7710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7711% %
7712% %
7713% %
7714% R e g i s t e r M S L I m a g e %
7715% %
7716% %
7717% %
7718%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7719%
7720% RegisterMSLImage() adds attributes for the MSL image format to
7721% the list of supported formats. The attributes include the image format
7722% tag, a method to read and/or write the format, whether the format
7723% supports the saving of more than one frame to the same file or blob,
7724% whether the format supports native in-memory I/O, and a brief
7725% description of the format.
7726%
7727% The format of the RegisterMSLImage method is:
7728%
cristybb503372010-05-27 20:51:26 +00007729% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007730%
7731*/
cristybb503372010-05-27 20:51:26 +00007732ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007733{
7734 MagickInfo
7735 *entry;
7736
7737 entry=SetMagickInfo("MSL");
7738#if defined(MAGICKCORE_XML_DELEGATE)
7739 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7740 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7741#endif
7742 entry->description=ConstantString("Magick Scripting Language");
7743 entry->module=ConstantString("MSL");
7744 (void) RegisterMagickInfo(entry);
7745 return(MagickImageCoderSignature);
7746}
7747
cristy6b9f7ed2010-04-24 01:08:02 +00007748#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007749/*
7750%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7751% %
7752% %
7753% %
cristyb988fe72009-09-16 01:01:10 +00007754% S e t M S L A t t r i b u t e s %
7755% %
7756% %
7757% %
7758%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7759%
7760% SetMSLAttributes() ...
7761%
7762% The format of the SetMSLAttributes method is:
7763%
7764% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007765% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007766%
7767% A description of each parameter follows:
7768%
7769% o msl_info: the MSL info.
7770%
cristyb20775d2009-09-16 01:51:41 +00007771% o keyword: the keyword.
7772%
7773% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007774%
7775*/
cristyb20775d2009-09-16 01:51:41 +00007776static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7777 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007778{
cristy4582cbb2009-09-23 00:35:43 +00007779 Image
7780 *attributes;
7781
cristyb20775d2009-09-16 01:51:41 +00007782 DrawInfo
7783 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007784
7785 ExceptionInfo
7786 *exception;
7787
cristy4582cbb2009-09-23 00:35:43 +00007788 GeometryInfo
7789 geometry_info;
7790
cristy4fa36e42009-09-18 14:24:06 +00007791 Image
7792 *image;
7793
cristyb20775d2009-09-16 01:51:41 +00007794 ImageInfo
7795 *image_info;
7796
cristy4582cbb2009-09-23 00:35:43 +00007797 int
7798 flags;
7799
cristybb503372010-05-27 20:51:26 +00007800 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007801 n;
7802
cristyb988fe72009-09-16 01:01:10 +00007803 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007804 if (keyword == (const char *) NULL)
7805 return(MagickTrue);
7806 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007807 return(MagickTrue);
7808 exception=msl_info->exception;
7809 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007810 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007811 image_info=msl_info->image_info[n];
7812 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007813 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007814 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007815 {
cristyfb758a52009-09-16 14:36:08 +00007816 case 'A':
7817 case 'a':
7818 {
7819 if (LocaleCompare(keyword,"adjoin") == 0)
7820 {
cristybb503372010-05-27 20:51:26 +00007821 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007822 adjoin;
7823
cristy042ee782011-04-22 18:48:30 +00007824 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007825 if (adjoin < 0)
7826 ThrowMSLException(OptionError,"UnrecognizedType",value);
7827 image_info->adjoin=(MagickBooleanType) adjoin;
7828 break;
7829 }
cristy4fa36e42009-09-18 14:24:06 +00007830 if (LocaleCompare(keyword,"alpha") == 0)
7831 {
cristybb503372010-05-27 20:51:26 +00007832 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007833 alpha;
7834
cristy042ee782011-04-22 18:48:30 +00007835 alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007836 if (alpha < 0)
7837 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007838 if (image != (Image *) NULL)
7839 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha);
7840 break;
7841 }
7842 if (LocaleCompare(keyword,"antialias") == 0)
7843 {
cristybb503372010-05-27 20:51:26 +00007844 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007845 antialias;
7846
cristy042ee782011-04-22 18:48:30 +00007847 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007848 if (antialias < 0)
7849 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7850 image_info->antialias=(MagickBooleanType) antialias;
7851 break;
7852 }
7853 if (LocaleCompare(keyword,"area-limit") == 0)
7854 {
7855 MagickSizeType
7856 limit;
7857
7858 limit=MagickResourceInfinity;
7859 if (LocaleCompare(value,"unlimited") != 0)
cristyf2f27272009-12-17 14:48:46 +00007860 limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007861 (void) SetMagickResourceLimit(AreaResource,limit);
7862 break;
7863 }
7864 if (LocaleCompare(keyword,"attenuate") == 0)
7865 {
7866 (void) SetImageOption(image_info,keyword,value);
7867 break;
7868 }
7869 if (LocaleCompare(keyword,"authenticate") == 0)
7870 {
7871 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007872 break;
7873 }
cristyfb758a52009-09-16 14:36:08 +00007874 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7875 break;
7876 }
cristyb20775d2009-09-16 01:51:41 +00007877 case 'B':
7878 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007879 {
cristyb20775d2009-09-16 01:51:41 +00007880 if (LocaleCompare(keyword,"background") == 0)
7881 {
cristy2c8b6312009-09-16 02:37:23 +00007882 (void) QueryColorDatabase(value,&image_info->background_color,
cristyb20775d2009-09-16 01:51:41 +00007883 exception);
7884 break;
7885 }
cristy4582cbb2009-09-23 00:35:43 +00007886 if (LocaleCompare(keyword,"bias") == 0)
7887 {
7888 if (image == (Image *) NULL)
7889 break;
cristyf2f27272009-12-17 14:48:46 +00007890 image->bias=SiPrefixToDouble(value,QuantumRange);
cristy4582cbb2009-09-23 00:35:43 +00007891 break;
7892 }
7893 if (LocaleCompare(keyword,"blue-primary") == 0)
7894 {
7895 if (image == (Image *) NULL)
7896 break;
7897 flags=ParseGeometry(value,&geometry_info);
7898 image->chromaticity.blue_primary.x=geometry_info.rho;
7899 image->chromaticity.blue_primary.y=geometry_info.sigma;
7900 if ((flags & SigmaValue) == 0)
7901 image->chromaticity.blue_primary.y=
7902 image->chromaticity.blue_primary.x;
7903 break;
7904 }
cristy2c8b6312009-09-16 02:37:23 +00007905 if (LocaleCompare(keyword,"bordercolor") == 0)
7906 {
7907 (void) QueryColorDatabase(value,&image_info->border_color,
7908 exception);
7909 break;
7910 }
7911 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7912 break;
7913 }
7914 case 'D':
7915 case 'd':
7916 {
7917 if (LocaleCompare(keyword,"density") == 0)
7918 {
7919 (void) CloneString(&image_info->density,value);
7920 (void) CloneString(&draw_info->density,value);
7921 break;
7922 }
cristyb20775d2009-09-16 01:51:41 +00007923 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7924 break;
7925 }
7926 case 'F':
7927 case 'f':
7928 {
7929 if (LocaleCompare(keyword,"fill") == 0)
7930 {
cristy2c8b6312009-09-16 02:37:23 +00007931 (void) QueryColorDatabase(value,&draw_info->fill,exception);
cristya30afaf2009-09-22 13:42:12 +00007932 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00007933 break;
7934 }
cristy4582cbb2009-09-23 00:35:43 +00007935 if (LocaleCompare(keyword,"filename") == 0)
7936 {
7937 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7938 break;
7939 }
7940 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7941 break;
7942 }
7943 case 'G':
7944 case 'g':
7945 {
7946 if (LocaleCompare(keyword,"gravity") == 0)
7947 {
cristybb503372010-05-27 20:51:26 +00007948 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007949 gravity;
7950
cristy042ee782011-04-22 18:48:30 +00007951 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007952 if (gravity < 0)
7953 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7954 (void) SetImageOption(image_info,keyword,value);
7955 break;
7956 }
cristyb20775d2009-09-16 01:51:41 +00007957 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7958 break;
7959 }
7960 case 'I':
7961 case 'i':
7962 {
7963 if (LocaleCompare(keyword,"id") == 0)
7964 {
cristy4582cbb2009-09-23 00:35:43 +00007965 (void) SetImageProperty(attributes,keyword,value);
cristy2c8b6312009-09-16 02:37:23 +00007966 break;
7967 }
7968 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7969 break;
7970 }
7971 case 'M':
7972 case 'm':
7973 {
7974 if (LocaleCompare(keyword,"magick") == 0)
7975 {
7976 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
7977 break;
7978 }
cristy2c8b6312009-09-16 02:37:23 +00007979 if (LocaleCompare(keyword,"mattecolor") == 0)
7980 {
7981 (void) QueryColorDatabase(value,&image_info->matte_color,
7982 exception);
cristyb20775d2009-09-16 01:51:41 +00007983 break;
7984 }
7985 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7986 break;
7987 }
7988 case 'P':
7989 case 'p':
7990 {
7991 if (LocaleCompare(keyword,"pointsize") == 0)
7992 {
cristyf2f27272009-12-17 14:48:46 +00007993 image_info->pointsize=StringToDouble(value);
7994 draw_info->pointsize=StringToDouble(value);
cristyb20775d2009-09-16 01:51:41 +00007995 break;
7996 }
7997 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7998 break;
7999 }
cristy4582cbb2009-09-23 00:35:43 +00008000 case 'Q':
8001 case 'q':
8002 {
8003 if (LocaleCompare(keyword,"quality") == 0)
8004 {
cristyf2f27272009-12-17 14:48:46 +00008005 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008006 if (image == (Image *) NULL)
8007 break;
cristyf2f27272009-12-17 14:48:46 +00008008 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008009 break;
8010 }
8011 break;
8012 }
cristyb20775d2009-09-16 01:51:41 +00008013 case 'S':
8014 case 's':
8015 {
8016 if (LocaleCompare(keyword,"size") == 0)
8017 {
cristy2c8b6312009-09-16 02:37:23 +00008018 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008019 break;
8020 }
8021 if (LocaleCompare(keyword,"stroke") == 0)
8022 {
cristy2c8b6312009-09-16 02:37:23 +00008023 (void) QueryColorDatabase(value,&draw_info->stroke,exception);
cristya30afaf2009-09-22 13:42:12 +00008024 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008025 break;
8026 }
8027 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8028 break;
8029 }
8030 default:
8031 {
8032 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8033 break;
cristyb988fe72009-09-16 01:01:10 +00008034 }
8035 }
8036 return(MagickTrue);
8037}
cristy6b9f7ed2010-04-24 01:08:02 +00008038#endif
cristyb988fe72009-09-16 01:01:10 +00008039
8040/*
8041%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8042% %
8043% %
8044% %
cristy3ed852e2009-09-05 21:47:34 +00008045% U n r e g i s t e r M S L I m a g e %
8046% %
8047% %
8048% %
8049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8050%
8051% UnregisterMSLImage() removes format registrations made by the
8052% MSL module from the list of supported formats.
8053%
8054% The format of the UnregisterMSLImage method is:
8055%
8056% UnregisterMSLImage(void)
8057%
8058*/
8059ModuleExport void UnregisterMSLImage(void)
8060{
8061 (void) UnregisterMagickInfo("MSL");
8062}
8063
8064#if defined(MAGICKCORE_XML_DELEGATE)
8065/*
8066%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8067% %
8068% %
8069% %
8070% W r i t e M S L I m a g e %
8071% %
8072% %
8073% %
8074%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8075%
8076% WriteMSLImage() writes an image to a file in MVG image format.
8077%
8078% The format of the WriteMSLImage method is:
8079%
8080% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8081%
8082% A description of each parameter follows.
8083%
8084% o image_info: the image info.
8085%
8086% o image: The image.
8087%
8088*/
8089static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8090{
8091 assert(image_info != (const ImageInfo *) NULL);
8092 assert(image_info->signature == MagickSignature);
8093 assert(image != (Image *) NULL);
8094 assert(image->signature == MagickSignature);
8095 if (image->debug != MagickFalse)
8096 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8097 (void) ReferenceImage(image);
8098 (void) ProcessMSLScript(image_info,&image,&image->exception);
8099 return(MagickTrue);
8100}
8101#endif