blob: 4c8daf2a98fa116ee08494a99dff7834323a0011 [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;
505}
506
507static void MSLStartDocument(void *context)
508{
509 MSLInfo
510 *msl_info;
511
512 xmlParserCtxtPtr
513 parser;
514
515 /*
516 Called when the document start being processed.
517 */
518 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
519 " SAX.startDocument()");
520 msl_info=(MSLInfo *) context;
521 parser=msl_info->parser;
522 msl_info->document=xmlNewDoc(parser->version);
523 if (msl_info->document == (xmlDocPtr) NULL)
524 return;
525 if (parser->encoding == NULL)
526 msl_info->document->encoding=NULL;
527 else
528 msl_info->document->encoding=xmlStrdup(parser->encoding);
529 msl_info->document->standalone=parser->standalone;
530}
531
532static void MSLEndDocument(void *context)
533{
534 MSLInfo
535 *msl_info;
536
537 /*
538 Called when the document end has been detected.
539 */
540 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endDocument()");
541 msl_info=(MSLInfo *) context;
542 if (msl_info->content != (char *) NULL)
543 msl_info->content=DestroyString(msl_info->content);
544}
545
546static void MSLPushImage(MSLInfo *msl_info,Image *image)
547{
cristybb503372010-05-27 20:51:26 +0000548 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000549 n;
550
551 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
552 assert(msl_info != (MSLInfo *) NULL);
553 msl_info->n++;
554 n=msl_info->n;
555 msl_info->image_info=(ImageInfo **) ResizeQuantumMemory(msl_info->image_info,
556 (n+1),sizeof(*msl_info->image_info));
557 msl_info->draw_info=(DrawInfo **) ResizeQuantumMemory(msl_info->draw_info,
558 (n+1),sizeof(*msl_info->draw_info));
559 msl_info->attributes=(Image **) ResizeQuantumMemory(msl_info->attributes,
560 (n+1),sizeof(*msl_info->attributes));
561 msl_info->image=(Image **) ResizeQuantumMemory(msl_info->image,(n+1),
562 sizeof(*msl_info->image));
563 if ((msl_info->image_info == (ImageInfo **) NULL) ||
564 (msl_info->draw_info == (DrawInfo **) NULL) ||
565 (msl_info->attributes == (Image **) NULL) ||
566 (msl_info->image == (Image **) NULL))
567 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
568 msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
569 msl_info->draw_info[n]=CloneDrawInfo(msl_info->image_info[n-1],
570 msl_info->draw_info[n-1]);
571 if (image == (Image *) NULL)
572 msl_info->attributes[n]=AcquireImage(msl_info->image_info[n]);
573 else
574 msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,&image->exception);
575 msl_info->image[n]=(Image *) image;
576 if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
577 (msl_info->attributes[n] == (Image *) NULL))
578 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
579 if (msl_info->number_groups != 0)
580 msl_info->group_info[msl_info->number_groups-1].numImages++;
581}
582
583static void MSLPopImage(MSLInfo *msl_info)
584{
585 if (msl_info->number_groups != 0)
586 return;
587 if (msl_info->image[msl_info->n] != (Image *) NULL)
588 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
589 msl_info->attributes[msl_info->n]=DestroyImage(
590 msl_info->attributes[msl_info->n]);
591 msl_info->image_info[msl_info->n]=DestroyImageInfo(
592 msl_info->image_info[msl_info->n]);
593 msl_info->n--;
594}
595
596static void MSLStartElement(void *context,const xmlChar *tag,
597 const xmlChar **attributes)
598{
599 AffineMatrix
600 affine,
601 current;
602
603 ChannelType
604 channel;
605
606 char
607 key[MaxTextExtent],
608 *value;
609
610 const char
611 *attribute,
612 *keyword;
613
614 double
615 angle;
616
617 DrawInfo
618 *draw_info;
619
620 ExceptionInfo
621 exception;
622
623 GeometryInfo
624 geometry_info;
625
626 Image
627 *image;
628
629 int
630 flags;
631
cristybb503372010-05-27 20:51:26 +0000632 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000633 option,
634 j,
635 n,
636 x,
637 y;
638
639 MSLInfo
640 *msl_info;
641
642 RectangleInfo
643 geometry;
644
cristybb503372010-05-27 20:51:26 +0000645 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000646 i;
647
cristybb503372010-05-27 20:51:26 +0000648 size_t
cristy3ed852e2009-09-05 21:47:34 +0000649 height,
650 width;
651
652 /*
653 Called when an opening tag has been processed.
654 */
655 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
656 " SAX.startElement(%s",tag);
657 GetExceptionInfo(&exception);
658 msl_info=(MSLInfo *) context;
659 n=msl_info->n;
660 keyword=(const char *) NULL;
661 value=(char *) NULL;
662 SetGeometryInfo(&geometry_info);
663 channel=DefaultChannels;
664 switch (*tag)
665 {
666 case 'A':
667 case 'a':
668 {
cristyb988fe72009-09-16 01:01:10 +0000669 if (LocaleCompare((const char *) tag,"add-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000670 {
671 Image
672 *noise_image;
673
674 NoiseType
675 noise;
676
677 /*
678 Add noise image.
679 */
680 if (msl_info->image[n] == (Image *) NULL)
681 {
cristyb988fe72009-09-16 01:01:10 +0000682 ThrowMSLException(OptionError,"NoImagesDefined",
683 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000684 break;
685 }
686 noise=UniformNoise;
687 if (attributes != (const xmlChar **) NULL)
688 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
689 {
690 keyword=(const char *) attributes[i++];
691 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +0000692 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +0000693 CloneString(&value,attribute);
694 switch (*keyword)
695 {
696 case 'C':
697 case 'c':
698 {
699 if (LocaleCompare(keyword,"channel") == 0)
700 {
701 option=ParseChannelOption(value);
702 if (option < 0)
703 ThrowMSLException(OptionError,"UnrecognizedChannelType",
704 value);
705 channel=(ChannelType) option;
706 break;
707 }
708 ThrowMSLException(OptionError,"UnrecognizedAttribute",
709 keyword);
710 break;
711 }
712 case 'N':
713 case 'n':
714 {
715 if (LocaleCompare(keyword,"noise") == 0)
716 {
717 option=ParseMagickOption(MagickNoiseOptions,MagickFalse,
718 value);
719 if (option < 0)
720 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
721 value);
722 noise=(NoiseType) option;
723 break;
724 }
725 ThrowMSLException(OptionError,"UnrecognizedAttribute",
726 keyword);
727 break;
728 }
729 default:
730 {
731 ThrowMSLException(OptionError,"UnrecognizedAttribute",
732 keyword);
733 break;
734 }
735 }
736 }
737 noise_image=AddNoiseImageChannel(msl_info->image[n],channel,noise,
738 &msl_info->image[n]->exception);
739 if (noise_image == (Image *) NULL)
740 break;
741 msl_info->image[n]=DestroyImage(msl_info->image[n]);
742 msl_info->image[n]=noise_image;
743 break;
744 }
cristyb988fe72009-09-16 01:01:10 +0000745 if (LocaleCompare((const char *) tag,"annotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000746 {
747 char
748 text[MaxTextExtent];
749
750 /*
751 Annotate image.
752 */
753 if (msl_info->image[n] == (Image *) NULL)
754 {
cristyb988fe72009-09-16 01:01:10 +0000755 ThrowMSLException(OptionError,"NoImagesDefined",
756 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000757 break;
758 }
759 draw_info=CloneDrawInfo(msl_info->image_info[n],
760 msl_info->draw_info[n]);
761 angle=0.0;
762 current=draw_info->affine;
763 GetAffineMatrix(&affine);
764 if (attributes != (const xmlChar **) NULL)
765 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
766 {
767 keyword=(const char *) attributes[i++];
768 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +0000769 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +0000770 CloneString(&value,attribute);
771 switch (*keyword)
772 {
773 case 'A':
774 case 'a':
775 {
776 if (LocaleCompare(keyword,"affine") == 0)
777 {
778 char
779 *p;
780
781 p=value;
782 draw_info->affine.sx=strtod(p,&p);
783 if (*p ==',')
784 p++;
785 draw_info->affine.rx=strtod(p,&p);
786 if (*p ==',')
787 p++;
788 draw_info->affine.ry=strtod(p,&p);
789 if (*p ==',')
790 p++;
791 draw_info->affine.sy=strtod(p,&p);
792 if (*p ==',')
793 p++;
794 draw_info->affine.tx=strtod(p,&p);
795 if (*p ==',')
796 p++;
797 draw_info->affine.ty=strtod(p,&p);
798 break;
799 }
800 if (LocaleCompare(keyword,"align") == 0)
801 {
802 option=ParseMagickOption(MagickAlignOptions,MagickFalse,
803 value);
804 if (option < 0)
805 ThrowMSLException(OptionError,"UnrecognizedAlignType",
806 value);
807 draw_info->align=(AlignType) option;
808 break;
809 }
810 if (LocaleCompare(keyword,"antialias") == 0)
811 {
812 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
813 value);
814 if (option < 0)
815 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
816 value);
817 draw_info->stroke_antialias=(MagickBooleanType) option;
818 draw_info->text_antialias=(MagickBooleanType) option;
819 break;
820 }
821 ThrowMSLException(OptionError,"UnrecognizedAttribute",
822 keyword);
823 break;
824 }
825 case 'D':
826 case 'd':
827 {
828 if (LocaleCompare(keyword,"density") == 0)
829 {
830 CloneString(&draw_info->density,value);
831 break;
832 }
833 ThrowMSLException(OptionError,"UnrecognizedAttribute",
834 keyword);
835 break;
836 }
837 case 'E':
838 case 'e':
839 {
840 if (LocaleCompare(keyword,"encoding") == 0)
841 {
842 CloneString(&draw_info->encoding,value);
843 break;
844 }
845 ThrowMSLException(OptionError,"UnrecognizedAttribute",
846 keyword);
847 break;
848 }
849 case 'F':
850 case 'f':
851 {
852 if (LocaleCompare(keyword, "fill") == 0)
853 {
854 (void) QueryColorDatabase(value,&draw_info->fill,
855 &exception);
856 break;
857 }
858 if (LocaleCompare(keyword,"family") == 0)
859 {
860 CloneString(&draw_info->family,value);
861 break;
862 }
863 if (LocaleCompare(keyword,"font") == 0)
864 {
865 CloneString(&draw_info->font,value);
866 break;
867 }
868 ThrowMSLException(OptionError,"UnrecognizedAttribute",
869 keyword);
870 break;
871 }
872 case 'G':
873 case 'g':
874 {
875 if (LocaleCompare(keyword,"geometry") == 0)
876 {
877 flags=ParsePageGeometry(msl_info->image[n],value,
878 &geometry,&exception);
879 if ((flags & HeightValue) == 0)
880 geometry.height=geometry.width;
881 break;
882 }
883 if (LocaleCompare(keyword,"gravity") == 0)
884 {
885 option=ParseMagickOption(MagickGravityOptions,MagickFalse,
886 value);
887 if (option < 0)
888 ThrowMSLException(OptionError,"UnrecognizedGravityType",
889 value);
890 draw_info->gravity=(GravityType) option;
891 break;
892 }
893 ThrowMSLException(OptionError,"UnrecognizedAttribute",
894 keyword);
895 break;
896 }
897 case 'P':
898 case 'p':
899 {
900 if (LocaleCompare(keyword,"pointsize") == 0)
901 {
cristyf2f27272009-12-17 14:48:46 +0000902 draw_info->pointsize=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +0000903 break;
904 }
905 ThrowMSLException(OptionError,"UnrecognizedAttribute",
906 keyword);
907 break;
908 }
909 case 'R':
910 case 'r':
911 {
912 if (LocaleCompare(keyword,"rotate") == 0)
913 {
cristyf2f27272009-12-17 14:48:46 +0000914 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +0000915 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
916 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
917 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
918 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
919 break;
920 }
921 ThrowMSLException(OptionError,"UnrecognizedAttribute",
922 keyword);
923 break;
924 }
925 case 'S':
926 case 's':
927 {
928 if (LocaleCompare(keyword,"scale") == 0)
929 {
930 flags=ParseGeometry(value,&geometry_info);
931 if ((flags & SigmaValue) == 0)
932 geometry_info.sigma=1.0;
933 affine.sx=geometry_info.rho;
934 affine.sy=geometry_info.sigma;
935 break;
936 }
937 if (LocaleCompare(keyword,"skewX") == 0)
938 {
cristyf2f27272009-12-17 14:48:46 +0000939 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +0000940 affine.ry=tan(DegreesToRadians(fmod((double) angle,
941 360.0)));
942 break;
943 }
944 if (LocaleCompare(keyword,"skewY") == 0)
945 {
cristyf2f27272009-12-17 14:48:46 +0000946 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +0000947 affine.rx=tan(DegreesToRadians(fmod((double) angle,
948 360.0)));
949 break;
950 }
951 if (LocaleCompare(keyword,"stretch") == 0)
952 {
953 option=ParseMagickOption(MagickStretchOptions,MagickFalse,
954 value);
955 if (option < 0)
956 ThrowMSLException(OptionError,"UnrecognizedStretchType",
957 value);
958 draw_info->stretch=(StretchType) option;
959 break;
960 }
961 if (LocaleCompare(keyword, "stroke") == 0)
962 {
963 (void) QueryColorDatabase(value,&draw_info->stroke,
964 &exception);
965 break;
966 }
967 if (LocaleCompare(keyword,"strokewidth") == 0)
968 {
cristyf2f27272009-12-17 14:48:46 +0000969 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000970 break;
971 }
972 if (LocaleCompare(keyword,"style") == 0)
973 {
974 option=ParseMagickOption(MagickStyleOptions,MagickFalse,
975 value);
976 if (option < 0)
977 ThrowMSLException(OptionError,"UnrecognizedStyleType",
978 value);
979 draw_info->style=(StyleType) option;
980 break;
981 }
982 ThrowMSLException(OptionError,"UnrecognizedAttribute",
983 keyword);
984 break;
985 }
986 case 'T':
987 case 't':
988 {
989 if (LocaleCompare(keyword,"text") == 0)
990 {
991 CloneString(&draw_info->text,value);
992 break;
993 }
994 if (LocaleCompare(keyword,"translate") == 0)
995 {
996 flags=ParseGeometry(value,&geometry_info);
997 if ((flags & SigmaValue) == 0)
998 geometry_info.sigma=1.0;
999 affine.tx=geometry_info.rho;
1000 affine.ty=geometry_info.sigma;
1001 break;
1002 }
1003 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1004 keyword);
1005 break;
1006 }
1007 case 'U':
1008 case 'u':
1009 {
1010 if (LocaleCompare(keyword, "undercolor") == 0)
1011 {
1012 (void) QueryColorDatabase(value,&draw_info->undercolor,
1013 &exception);
1014 break;
1015 }
1016 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1017 keyword);
1018 break;
1019 }
1020 case 'W':
1021 case 'w':
1022 {
1023 if (LocaleCompare(keyword,"weight") == 0)
1024 {
cristyf2f27272009-12-17 14:48:46 +00001025 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001026 break;
1027 }
1028 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1029 keyword);
1030 break;
1031 }
1032 case 'X':
1033 case 'x':
1034 {
1035 if (LocaleCompare(keyword,"x") == 0)
1036 {
cristyf2f27272009-12-17 14:48:46 +00001037 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001038 break;
1039 }
1040 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1041 keyword);
1042 break;
1043 }
1044 case 'Y':
1045 case 'y':
1046 {
1047 if (LocaleCompare(keyword,"y") == 0)
1048 {
cristyf2f27272009-12-17 14:48:46 +00001049 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001050 break;
1051 }
1052 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1053 keyword);
1054 break;
1055 }
1056 default:
1057 {
1058 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1059 keyword);
1060 break;
1061 }
1062 }
1063 }
cristye8c25f92010-06-03 00:53:06 +00001064 (void) FormatMagickString(text,MaxTextExtent,
1065 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
1066 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00001067 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00001068 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
1069 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
1070 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
1071 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
1072 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
1073 affine.tx;
1074 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
1075 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00001076 (void) AnnotateImage(msl_info->image[n],draw_info);
1077 draw_info=DestroyDrawInfo(draw_info);
1078 break;
1079 }
cristyb988fe72009-09-16 01:01:10 +00001080 if (LocaleCompare((const char *) tag,"append") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001081 {
1082 Image
1083 *append_image;
1084
1085 MagickBooleanType
1086 stack;
cristyb988fe72009-09-16 01:01:10 +00001087
cristy3ed852e2009-09-05 21:47:34 +00001088 if (msl_info->image[n] == (Image *) NULL)
1089 {
cristyb988fe72009-09-16 01:01:10 +00001090 ThrowMSLException(OptionError,"NoImagesDefined",
1091 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001092 break;
1093 }
1094 stack=MagickFalse;
1095 if (attributes != (const xmlChar **) NULL)
1096 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1097 {
1098 keyword=(const char *) attributes[i++];
1099 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001100 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001101 CloneString(&value,attribute);
1102 switch (*keyword)
1103 {
1104 case 'S':
1105 case 's':
1106 {
1107 if (LocaleCompare(keyword,"stack") == 0)
1108 {
1109 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
1110 value);
1111 if (option < 0)
1112 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1113 value);
1114 stack=(MagickBooleanType) option;
1115 break;
1116 }
1117 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1118 keyword);
1119 break;
1120 }
1121 default:
1122 {
1123 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1124 keyword);
1125 break;
1126 }
1127 }
1128 }
1129 append_image=AppendImages(msl_info->image[n],stack,
1130 &msl_info->image[n]->exception);
1131 if (append_image == (Image *) NULL)
1132 break;
1133 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1134 msl_info->image[n]=append_image;
1135 break;
1136 }
1137 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1138 break;
1139 }
1140 case 'B':
1141 case 'b':
1142 {
cristyb988fe72009-09-16 01:01:10 +00001143 if (LocaleCompare((const char *) tag,"blur") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001144 {
1145 Image
1146 *blur_image;
1147
1148 /*
1149 Blur image.
1150 */
1151 if (msl_info->image[n] == (Image *) NULL)
1152 {
cristyb988fe72009-09-16 01:01:10 +00001153 ThrowMSLException(OptionError,"NoImagesDefined",
1154 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001155 break;
1156 }
1157 if (attributes != (const xmlChar **) NULL)
1158 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1159 {
1160 keyword=(const char *) attributes[i++];
1161 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001162 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001163 CloneString(&value,attribute);
1164 switch (*keyword)
1165 {
1166 case 'C':
1167 case 'c':
1168 {
1169 if (LocaleCompare(keyword,"channel") == 0)
1170 {
1171 option=ParseChannelOption(value);
1172 if (option < 0)
1173 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1174 value);
1175 channel=(ChannelType) option;
1176 break;
1177 }
1178 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1179 keyword);
1180 break;
1181 }
1182 case 'G':
1183 case 'g':
1184 {
1185 if (LocaleCompare(keyword,"geometry") == 0)
1186 {
1187 flags=ParseGeometry(value,&geometry_info);
1188 if ((flags & SigmaValue) == 0)
1189 geometry_info.sigma=1.0;
1190 break;
1191 }
1192 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1193 keyword);
1194 break;
1195 }
1196 case 'R':
1197 case 'r':
1198 {
1199 if (LocaleCompare(keyword,"radius") == 0)
1200 {
cristyf2f27272009-12-17 14:48:46 +00001201 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00001202 break;
1203 }
1204 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1205 keyword);
1206 break;
1207 }
1208 case 'S':
1209 case 's':
1210 {
1211 if (LocaleCompare(keyword,"sigma") == 0)
1212 {
cristyf2f27272009-12-17 14:48:46 +00001213 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001214 break;
1215 }
1216 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1217 keyword);
1218 break;
1219 }
1220 default:
1221 {
1222 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1223 keyword);
1224 break;
1225 }
1226 }
1227 }
1228 blur_image=BlurImageChannel(msl_info->image[n],channel,
1229 geometry_info.rho,geometry_info.sigma,
1230 &msl_info->image[n]->exception);
1231 if (blur_image == (Image *) NULL)
1232 break;
1233 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1234 msl_info->image[n]=blur_image;
1235 break;
1236 }
cristyb988fe72009-09-16 01:01:10 +00001237 if (LocaleCompare((const char *) tag,"border") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001238 {
1239 Image
1240 *border_image;
1241
1242 /*
1243 Border image.
1244 */
1245 if (msl_info->image[n] == (Image *) NULL)
1246 {
cristyb988fe72009-09-16 01:01:10 +00001247 ThrowMSLException(OptionError,"NoImagesDefined",
1248 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001249 break;
1250 }
1251 SetGeometry(msl_info->image[n],&geometry);
1252 if (attributes != (const xmlChar **) NULL)
1253 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1254 {
1255 keyword=(const char *) attributes[i++];
1256 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001257 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001258 CloneString(&value,attribute);
1259 switch (*keyword)
1260 {
1261 case 'C':
1262 case 'c':
1263 {
1264 if (LocaleCompare(keyword,"compose") == 0)
1265 {
1266 option=ParseMagickOption(MagickComposeOptions,MagickFalse,
1267 value);
1268 if (option < 0)
1269 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1270 value);
1271 msl_info->image[n]->compose=(CompositeOperator) option;
1272 break;
1273 }
1274 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1275 keyword);
1276 break;
1277 }
1278 case 'F':
1279 case 'f':
1280 {
1281 if (LocaleCompare(keyword, "fill") == 0)
1282 {
1283 (void) QueryColorDatabase(value,
1284 &msl_info->image[n]->border_color,&exception);
1285 break;
1286 }
1287 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1288 keyword);
1289 break;
1290 }
1291 case 'G':
1292 case 'g':
1293 {
1294 if (LocaleCompare(keyword,"geometry") == 0)
1295 {
1296 flags=ParsePageGeometry(msl_info->image[n],value,
1297 &geometry,&exception);
1298 if ((flags & HeightValue) == 0)
1299 geometry.height=geometry.width;
1300 break;
1301 }
1302 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1303 keyword);
1304 break;
1305 }
1306 case 'H':
1307 case 'h':
1308 {
1309 if (LocaleCompare(keyword,"height") == 0)
1310 {
cristyf2f27272009-12-17 14:48:46 +00001311 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001312 break;
1313 }
1314 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1315 keyword);
1316 break;
1317 }
1318 case 'W':
1319 case 'w':
1320 {
1321 if (LocaleCompare(keyword,"width") == 0)
1322 {
cristyf2f27272009-12-17 14:48:46 +00001323 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001324 break;
1325 }
1326 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1327 keyword);
1328 break;
1329 }
1330 default:
1331 {
1332 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1333 keyword);
1334 break;
1335 }
1336 }
1337 }
1338 border_image=BorderImage(msl_info->image[n],&geometry,
1339 &msl_info->image[n]->exception);
1340 if (border_image == (Image *) NULL)
1341 break;
1342 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1343 msl_info->image[n]=border_image;
1344 break;
1345 }
1346 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1347 }
1348 case 'C':
1349 case 'c':
1350 {
cristyb988fe72009-09-16 01:01:10 +00001351 if (LocaleCompare((const char *) tag,"colorize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001352 {
1353 char
1354 opacity[MaxTextExtent];
1355
1356 Image
1357 *colorize_image;
1358
1359 PixelPacket
1360 target;
1361
1362 /*
1363 Add noise image.
1364 */
1365 if (msl_info->image[n] == (Image *) NULL)
1366 {
cristyb988fe72009-09-16 01:01:10 +00001367 ThrowMSLException(OptionError,"NoImagesDefined",
1368 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001369 break;
1370 }
1371 target=msl_info->image[n]->background_color;
1372 (void) CopyMagickString(opacity,"100",MaxTextExtent);
1373 if (attributes != (const xmlChar **) NULL)
1374 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1375 {
1376 keyword=(const char *) attributes[i++];
1377 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001378 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001379 CloneString(&value,attribute);
1380 switch (*keyword)
1381 {
1382 case 'F':
1383 case 'f':
1384 {
1385 if (LocaleCompare(keyword,"fill") == 0)
1386 {
1387 (void) QueryColorDatabase(value,&target,
1388 &msl_info->image[n]->exception);
1389 break;
1390 }
1391 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1392 keyword);
1393 break;
1394 }
1395 case 'O':
1396 case 'o':
1397 {
1398 if (LocaleCompare(keyword,"opacity") == 0)
1399 {
1400 (void) CopyMagickString(opacity,value,MaxTextExtent);
1401 break;
1402 }
1403 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1404 keyword);
1405 break;
1406 }
1407 default:
1408 {
1409 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1410 keyword);
1411 break;
1412 }
1413 }
1414 }
1415 colorize_image=ColorizeImage(msl_info->image[n],opacity,target,
1416 &msl_info->image[n]->exception);
1417 if (colorize_image == (Image *) NULL)
1418 break;
1419 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1420 msl_info->image[n]=colorize_image;
1421 break;
1422 }
cristyb988fe72009-09-16 01:01:10 +00001423 if (LocaleCompare((const char *) tag, "charcoal") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001424 {
1425 double radius = 0.0,
1426 sigma = 1.0;
1427
1428 if (msl_info->image[n] == (Image *) NULL)
1429 {
cristyb988fe72009-09-16 01:01:10 +00001430 ThrowMSLException(OptionError,"NoImagesDefined",
1431 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001432 break;
1433 }
1434 /*
1435 NOTE: charcoal can have no attributes, since we use all the defaults!
1436 */
1437 if (attributes != (const xmlChar **) NULL)
1438 {
1439 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1440 {
1441 keyword=(const char *) attributes[i++];
1442 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001443 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00001444 switch (*keyword)
1445 {
1446 case 'R':
1447 case 'r':
1448 {
1449 if (LocaleCompare(keyword, "radius") == 0)
1450 {
cristyf2f27272009-12-17 14:48:46 +00001451 radius = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00001452 break;
1453 }
1454 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1455 break;
1456 }
1457 case 'S':
1458 case 's':
1459 {
1460 if (LocaleCompare(keyword,"sigma") == 0)
1461 {
cristyf2f27272009-12-17 14:48:46 +00001462 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00001463 break;
1464 }
1465 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1466 break;
1467 }
1468 default:
1469 {
1470 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1471 break;
1472 }
1473 }
1474 }
1475 }
1476
1477 /*
1478 charcoal image.
1479 */
1480 {
1481 Image
1482 *newImage;
1483
1484 newImage=CharcoalImage(msl_info->image[n],radius,sigma,
1485 &msl_info->image[n]->exception);
1486 if (newImage == (Image *) NULL)
1487 break;
1488 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1489 msl_info->image[n]=newImage;
1490 break;
1491 }
1492 }
cristyb988fe72009-09-16 01:01:10 +00001493 if (LocaleCompare((const char *) tag,"chop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001494 {
1495 Image
1496 *chop_image;
1497
1498 /*
1499 Chop image.
1500 */
1501 if (msl_info->image[n] == (Image *) NULL)
1502 {
cristyb988fe72009-09-16 01:01:10 +00001503 ThrowMSLException(OptionError,"NoImagesDefined",
1504 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001505 break;
1506 }
1507 SetGeometry(msl_info->image[n],&geometry);
1508 if (attributes != (const xmlChar **) NULL)
1509 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1510 {
1511 keyword=(const char *) attributes[i++];
1512 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001513 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001514 CloneString(&value,attribute);
1515 switch (*keyword)
1516 {
1517 case 'G':
1518 case 'g':
1519 {
1520 if (LocaleCompare(keyword,"geometry") == 0)
1521 {
1522 flags=ParsePageGeometry(msl_info->image[n],value,
1523 &geometry,&exception);
1524 if ((flags & HeightValue) == 0)
1525 geometry.height=geometry.width;
1526 break;
1527 }
1528 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1529 keyword);
1530 break;
1531 }
1532 case 'H':
1533 case 'h':
1534 {
1535 if (LocaleCompare(keyword,"height") == 0)
1536 {
cristyf2f27272009-12-17 14:48:46 +00001537 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001538 break;
1539 }
1540 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1541 keyword);
1542 break;
1543 }
1544 case 'W':
1545 case 'w':
1546 {
1547 if (LocaleCompare(keyword,"width") == 0)
1548 {
cristyf2f27272009-12-17 14:48:46 +00001549 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001550 break;
1551 }
1552 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1553 keyword);
1554 break;
1555 }
1556 case 'X':
1557 case 'x':
1558 {
1559 if (LocaleCompare(keyword,"x") == 0)
1560 {
cristyf2f27272009-12-17 14:48:46 +00001561 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001562 break;
1563 }
1564 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1565 keyword);
1566 break;
1567 }
1568 case 'Y':
1569 case 'y':
1570 {
1571 if (LocaleCompare(keyword,"y") == 0)
1572 {
cristyf2f27272009-12-17 14:48:46 +00001573 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001574 break;
1575 }
1576 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1577 keyword);
1578 break;
1579 }
1580 default:
1581 {
1582 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1583 keyword);
1584 break;
1585 }
1586 }
1587 }
1588 chop_image=ChopImage(msl_info->image[n],&geometry,
1589 &msl_info->image[n]->exception);
1590 if (chop_image == (Image *) NULL)
1591 break;
1592 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1593 msl_info->image[n]=chop_image;
1594 break;
1595 }
cristyb988fe72009-09-16 01:01:10 +00001596 if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001597 {
1598 PaintMethod
1599 paint_method;
1600
1601 MagickPixelPacket
1602 target;
1603
1604 /*
1605 Color floodfill image.
1606 */
1607 if (msl_info->image[n] == (Image *) NULL)
1608 {
cristyb988fe72009-09-16 01:01:10 +00001609 ThrowMSLException(OptionError,"NoImagesDefined",
1610 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001611 break;
1612 }
1613 draw_info=CloneDrawInfo(msl_info->image_info[n],
1614 msl_info->draw_info[n]);
1615 SetGeometry(msl_info->image[n],&geometry);
1616 paint_method=FloodfillMethod;
1617 if (attributes != (const xmlChar **) NULL)
1618 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1619 {
1620 keyword=(const char *) attributes[i++];
1621 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001622 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001623 CloneString(&value,attribute);
1624 switch (*keyword)
1625 {
1626 case 'B':
1627 case 'b':
1628 {
1629 if (LocaleCompare(keyword,"bordercolor") == 0)
1630 {
1631 (void) QueryMagickColor(value,&target,&exception);
1632 paint_method=FillToBorderMethod;
1633 break;
1634 }
1635 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1636 keyword);
1637 break;
1638 }
1639 case 'F':
1640 case 'f':
1641 {
1642 if (LocaleCompare(keyword,"fill") == 0)
1643 {
1644 (void) QueryColorDatabase(value,&draw_info->fill,
1645 &exception);
1646 break;
1647 }
1648 if (LocaleCompare(keyword,"fuzz") == 0)
1649 {
cristyf2f27272009-12-17 14:48:46 +00001650 msl_info->image[n]->fuzz=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00001651 break;
1652 }
1653 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1654 keyword);
1655 break;
1656 }
1657 case 'G':
1658 case 'g':
1659 {
1660 if (LocaleCompare(keyword,"geometry") == 0)
1661 {
1662 flags=ParsePageGeometry(msl_info->image[n],value,
1663 &geometry,&exception);
1664 if ((flags & HeightValue) == 0)
1665 geometry.height=geometry.width;
1666 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1667 geometry.x,geometry.y,&target,&exception);
1668 break;
1669 }
1670 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1671 keyword);
1672 break;
1673 }
1674 case 'X':
1675 case 'x':
1676 {
1677 if (LocaleCompare(keyword,"x") == 0)
1678 {
cristyf2f27272009-12-17 14:48:46 +00001679 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001680 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1681 geometry.x,geometry.y,&target,&exception);
1682 break;
1683 }
1684 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1685 keyword);
1686 break;
1687 }
1688 case 'Y':
1689 case 'y':
1690 {
1691 if (LocaleCompare(keyword,"y") == 0)
1692 {
cristyf2f27272009-12-17 14:48:46 +00001693 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001694 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1695 geometry.x,geometry.y,&target,&exception);
1696 break;
1697 }
1698 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1699 keyword);
1700 break;
1701 }
1702 default:
1703 {
1704 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1705 keyword);
1706 break;
1707 }
1708 }
1709 }
1710 (void) FloodfillPaintImage(msl_info->image[n],DefaultChannels,
1711 draw_info,&target,geometry.x,geometry.y,
1712 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
1713 draw_info=DestroyDrawInfo(draw_info);
1714 break;
1715 }
cristyb988fe72009-09-16 01:01:10 +00001716 if (LocaleCompare((const char *) tag,"comment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001717 break;
cristyb988fe72009-09-16 01:01:10 +00001718 if (LocaleCompare((const char *) tag,"composite") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001719 {
1720 char
1721 composite_geometry[MaxTextExtent];
1722
1723 CompositeOperator
1724 compose;
1725
1726 Image
1727 *composite_image,
1728 *rotate_image;
1729
1730 PixelPacket
1731 target;
1732
1733 /*
1734 Composite image.
1735 */
1736 if (msl_info->image[n] == (Image *) NULL)
1737 {
cristyb988fe72009-09-16 01:01:10 +00001738 ThrowMSLException(OptionError,"NoImagesDefined",
1739 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001740 break;
1741 }
1742 composite_image=NewImageList();
1743 compose=OverCompositeOp;
1744 if (attributes != (const xmlChar **) NULL)
1745 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1746 {
1747 keyword=(const char *) attributes[i++];
1748 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001749 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001750 CloneString(&value,attribute);
1751 switch (*keyword)
1752 {
1753 case 'C':
1754 case 'c':
1755 {
1756 if (LocaleCompare(keyword,"compose") == 0)
1757 {
1758 option=ParseMagickOption(MagickComposeOptions,MagickFalse,
1759 value);
1760 if (option < 0)
1761 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1762 value);
1763 compose=(CompositeOperator) option;
1764 break;
1765 }
1766 break;
1767 }
1768 case 'I':
1769 case 'i':
1770 {
1771 if (LocaleCompare(keyword,"image") == 0)
1772 for (j=0; j < msl_info->n; j++)
1773 {
1774 const char
1775 *attribute;
cristyb988fe72009-09-16 01:01:10 +00001776
cristy3ed852e2009-09-05 21:47:34 +00001777 attribute=GetImageProperty(msl_info->attributes[j],"id");
1778 if ((attribute != (const char *) NULL) &&
1779 (LocaleCompare(attribute,value) == 0))
1780 {
1781 composite_image=CloneImage(msl_info->image[j],0,0,
1782 MagickFalse,&exception);
1783 break;
1784 }
1785 }
1786 break;
1787 }
1788 default:
1789 break;
1790 }
1791 }
1792 if (composite_image == (Image *) NULL)
1793 break;
1794 rotate_image=NewImageList();
1795 SetGeometry(msl_info->image[n],&geometry);
1796 if (attributes != (const xmlChar **) NULL)
1797 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1798 {
1799 keyword=(const char *) attributes[i++];
1800 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001801 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001802 CloneString(&value,attribute);
1803 switch (*keyword)
1804 {
1805 case 'B':
1806 case 'b':
1807 {
1808 if (LocaleCompare(keyword,"blend") == 0)
1809 {
1810 (void) SetImageArtifact(composite_image,
1811 "compose:args",value);
1812 break;
1813 }
1814 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1815 keyword);
1816 break;
1817 }
1818 case 'C':
1819 case 'c':
1820 {
1821 if (LocaleCompare(keyword,"channel") == 0)
1822 {
1823 option=ParseChannelOption(value);
1824 if (option < 0)
1825 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1826 value);
1827 channel=(ChannelType) option;
1828 break;
1829 }
1830 if (LocaleCompare(keyword, "color") == 0)
1831 {
1832 (void) QueryColorDatabase(value,
1833 &composite_image->background_color,&exception);
1834 break;
1835 }
1836 if (LocaleCompare(keyword,"compose") == 0)
1837 break;
1838 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1839 keyword);
1840 break;
1841 }
1842 case 'G':
1843 case 'g':
1844 {
1845 if (LocaleCompare(keyword,"geometry") == 0)
1846 {
1847 flags=ParsePageGeometry(msl_info->image[n],value,
1848 &geometry,&exception);
1849 if ((flags & HeightValue) == 0)
1850 geometry.height=geometry.width;
1851 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
1852 geometry.y,&target,&exception);
1853 break;
1854 }
1855 if (LocaleCompare(keyword,"gravity") == 0)
1856 {
1857 option=ParseMagickOption(MagickGravityOptions,MagickFalse,
1858 value);
1859 if (option < 0)
1860 ThrowMSLException(OptionError,"UnrecognizedGravityType",
1861 value);
1862 msl_info->image[n]->gravity=(GravityType) option;
1863 break;
1864 }
1865 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1866 keyword);
1867 break;
1868 }
1869 case 'I':
1870 case 'i':
1871 {
1872 if (LocaleCompare(keyword,"image") == 0)
1873 break;
1874 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1875 keyword);
1876 break;
1877 }
1878 case 'M':
1879 case 'm':
1880 {
1881 if (LocaleCompare(keyword,"mask") == 0)
1882 for (j=0; j < msl_info->n; j++)
1883 {
1884 const char
1885 *attribute;
1886
1887 attribute=GetImageProperty(msl_info->attributes[j],"id");
1888 if ((attribute != (const char *) NULL) &&
1889 (LocaleCompare(value,value) == 0))
1890 {
1891 SetImageType(composite_image,TrueColorMatteType);
1892 (void) CompositeImage(composite_image,
1893 CopyOpacityCompositeOp,msl_info->image[j],0,0);
1894 break;
1895 }
1896 }
1897 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1898 keyword);
1899 break;
1900 }
1901 case 'O':
1902 case 'o':
1903 {
1904 if (LocaleCompare(keyword,"opacity") == 0)
1905 {
cristybb503372010-05-27 20:51:26 +00001906 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001907 opacity,
1908 y;
cristyb988fe72009-09-16 01:01:10 +00001909
cristybb503372010-05-27 20:51:26 +00001910 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001911 x;
cristyb988fe72009-09-16 01:01:10 +00001912
cristy3ed852e2009-09-05 21:47:34 +00001913 register PixelPacket
1914 *q;
cristyb988fe72009-09-16 01:01:10 +00001915
cristy3ed852e2009-09-05 21:47:34 +00001916 CacheView
1917 *composite_view;
1918
cristyf2f27272009-12-17 14:48:46 +00001919 opacity=QuantumRange-StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001920 if (compose != DissolveCompositeOp)
1921 {
cristyb988fe72009-09-16 01:01:10 +00001922 (void) SetImageOpacity(composite_image,(Quantum)
1923 opacity);
cristy3ed852e2009-09-05 21:47:34 +00001924 break;
1925 }
1926 (void) SetImageArtifact(msl_info->image[n],
1927 "compose:args",value);
1928 if (composite_image->matte != MagickTrue)
1929 (void) SetImageOpacity(composite_image,OpaqueOpacity);
1930 composite_view=AcquireCacheView(composite_image);
cristybb503372010-05-27 20:51:26 +00001931 for (y=0; y < (ssize_t) composite_image->rows ; y++)
cristyb988fe72009-09-16 01:01:10 +00001932 {
cristybb503372010-05-27 20:51:26 +00001933 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00001934 composite_image->columns,1,&exception);
cristybb503372010-05-27 20:51:26 +00001935 for (x=0; x < (ssize_t) composite_image->columns; x++)
cristyb988fe72009-09-16 01:01:10 +00001936 {
cristy3ed852e2009-09-05 21:47:34 +00001937 if (q->opacity == OpaqueOpacity)
cristyce70c172010-01-07 17:15:30 +00001938 q->opacity=ClampToQuantum(opacity);
cristy3ed852e2009-09-05 21:47:34 +00001939 q++;
1940 }
1941 if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1942 break;
1943 }
1944 composite_view=DestroyCacheView(composite_view);
1945 break;
1946 }
1947 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1948 keyword);
1949 break;
1950 }
1951 case 'R':
1952 case 'r':
1953 {
1954 if (LocaleCompare(keyword,"rotate") == 0)
1955 {
cristyf2f27272009-12-17 14:48:46 +00001956 rotate_image=RotateImage(composite_image,StringToDouble(value),
cristy3ed852e2009-09-05 21:47:34 +00001957 &exception);
1958 break;
1959 }
1960 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1961 keyword);
1962 break;
1963 }
1964 case 'T':
1965 case 't':
1966 {
1967 if (LocaleCompare(keyword,"tile") == 0)
1968 {
1969 MagickBooleanType
1970 tile;
1971
1972 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
1973 value);
1974 if (option < 0)
1975 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1976 value);
1977 tile=(MagickBooleanType) option;
1978 if (rotate_image != (Image *) NULL)
1979 (void) SetImageArtifact(rotate_image,
1980 "compose:outside-overlay","false");
1981 else
1982 (void) SetImageArtifact(composite_image,
1983 "compose:outside-overlay","false");
1984 image=msl_info->image[n];
1985 height=composite_image->rows;
1986 width=composite_image->columns;
cristyeaedf062010-05-29 22:36:02 +00001987 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
1988 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
cristy3ed852e2009-09-05 21:47:34 +00001989 {
1990 if (rotate_image != (Image *) NULL)
1991 (void) CompositeImage(image,compose,rotate_image,
1992 x,y);
1993 else
1994 (void) CompositeImage(image,compose,
1995 composite_image,x,y);
1996 }
1997 if (rotate_image != (Image *) NULL)
1998 rotate_image=DestroyImage(rotate_image);
1999 break;
2000 }
2001 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2002 keyword);
2003 break;
2004 }
2005 case 'X':
2006 case 'x':
2007 {
2008 if (LocaleCompare(keyword,"x") == 0)
2009 {
cristyf2f27272009-12-17 14:48:46 +00002010 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002011 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2012 geometry.y,&target,&exception);
2013 break;
2014 }
2015 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2016 keyword);
2017 break;
2018 }
2019 case 'Y':
2020 case 'y':
2021 {
2022 if (LocaleCompare(keyword,"y") == 0)
2023 {
cristyf2f27272009-12-17 14:48:46 +00002024 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002025 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2026 geometry.y,&target,&exception);
2027 break;
2028 }
2029 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2030 keyword);
2031 break;
2032 }
2033 default:
2034 {
2035 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2036 keyword);
2037 break;
2038 }
2039 }
2040 }
2041 image=msl_info->image[n];
2042 (void) FormatMagickString(composite_geometry,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002043 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2044 (double) composite_image->rows,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00002045 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002046 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2047 &exception);
2048 if (rotate_image == (Image *) NULL)
2049 CompositeImageChannel(image,channel,compose,composite_image,
2050 geometry.x,geometry.y);
2051 else
2052 {
2053 /*
2054 Rotate image.
2055 */
cristybb503372010-05-27 20:51:26 +00002056 geometry.x-=(ssize_t) (rotate_image->columns-
cristy3ed852e2009-09-05 21:47:34 +00002057 composite_image->columns)/2;
cristybb503372010-05-27 20:51:26 +00002058 geometry.y-=(ssize_t) (rotate_image->rows-composite_image->rows)/2;
cristy3ed852e2009-09-05 21:47:34 +00002059 CompositeImageChannel(image,channel,compose,rotate_image,
2060 geometry.x,geometry.y);
2061 rotate_image=DestroyImage(rotate_image);
2062 }
2063 composite_image=DestroyImage(composite_image);
2064 break;
2065 }
cristyb988fe72009-09-16 01:01:10 +00002066 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002067 {
2068 MagickBooleanType
2069 sharpen;
2070
2071 /*
2072 Contrast image.
2073 */
2074 if (msl_info->image[n] == (Image *) NULL)
2075 {
cristyb988fe72009-09-16 01:01:10 +00002076 ThrowMSLException(OptionError,"NoImagesDefined",
2077 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002078 break;
2079 }
2080 sharpen=MagickFalse;
2081 if (attributes != (const xmlChar **) NULL)
2082 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2083 {
2084 keyword=(const char *) attributes[i++];
2085 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002086 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002087 CloneString(&value,attribute);
2088 switch (*keyword)
2089 {
2090 case 'S':
2091 case 's':
2092 {
2093 if (LocaleCompare(keyword,"sharpen") == 0)
2094 {
2095 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2096 value);
2097 if (option < 0)
2098 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2099 value);
2100 sharpen=(MagickBooleanType) option;
2101 break;
2102 }
2103 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2104 keyword);
2105 break;
2106 }
2107 default:
2108 {
2109 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2110 keyword);
2111 break;
2112 }
2113 }
2114 }
2115 (void) ContrastImage(msl_info->image[n],sharpen);
2116 break;
2117 }
cristyb988fe72009-09-16 01:01:10 +00002118 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002119 {
2120 Image
2121 *crop_image;
2122
2123 /*
2124 Crop image.
2125 */
2126 if (msl_info->image[n] == (Image *) NULL)
2127 {
cristyb988fe72009-09-16 01:01:10 +00002128 ThrowMSLException(OptionError,"NoImagesDefined",
2129 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002130 break;
2131 }
2132 SetGeometry(msl_info->image[n],&geometry);
2133 if (attributes != (const xmlChar **) NULL)
2134 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2135 {
2136 keyword=(const char *) attributes[i++];
2137 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002138 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002139 CloneString(&value,attribute);
2140 switch (*keyword)
2141 {
2142 case 'G':
2143 case 'g':
2144 {
2145 if (LocaleCompare(keyword,"geometry") == 0)
2146 {
2147 flags=ParsePageGeometry(msl_info->image[n],value,
2148 &geometry,&exception);
2149 if ((flags & HeightValue) == 0)
2150 geometry.height=geometry.width;
2151 break;
2152 }
2153 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2154 keyword);
2155 break;
2156 }
2157 case 'H':
2158 case 'h':
2159 {
2160 if (LocaleCompare(keyword,"height") == 0)
2161 {
cristyf2f27272009-12-17 14:48:46 +00002162 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002163 break;
2164 }
2165 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2166 keyword);
2167 break;
2168 }
2169 case 'W':
2170 case 'w':
2171 {
2172 if (LocaleCompare(keyword,"width") == 0)
2173 {
cristyf2f27272009-12-17 14:48:46 +00002174 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002175 break;
2176 }
2177 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2178 keyword);
2179 break;
2180 }
2181 case 'X':
2182 case 'x':
2183 {
2184 if (LocaleCompare(keyword,"x") == 0)
2185 {
cristyf2f27272009-12-17 14:48:46 +00002186 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002187 break;
2188 }
2189 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2190 keyword);
2191 break;
2192 }
2193 case 'Y':
2194 case 'y':
2195 {
2196 if (LocaleCompare(keyword,"y") == 0)
2197 {
cristyf2f27272009-12-17 14:48:46 +00002198 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002199 break;
2200 }
2201 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2202 keyword);
2203 break;
2204 }
2205 default:
2206 {
2207 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2208 keyword);
2209 break;
2210 }
2211 }
2212 }
2213 crop_image=CropImage(msl_info->image[n],&geometry,
2214 &msl_info->image[n]->exception);
2215 if (crop_image == (Image *) NULL)
2216 break;
2217 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2218 msl_info->image[n]=crop_image;
2219 break;
2220 }
cristyb988fe72009-09-16 01:01:10 +00002221 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002222 {
cristybb503372010-05-27 20:51:26 +00002223 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002224 display;
2225
2226 /*
2227 Cycle-colormap image.
2228 */
2229 if (msl_info->image[n] == (Image *) NULL)
2230 {
cristyb988fe72009-09-16 01:01:10 +00002231 ThrowMSLException(OptionError,"NoImagesDefined",
2232 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002233 break;
2234 }
2235 display=0;
2236 if (attributes != (const xmlChar **) NULL)
2237 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2238 {
2239 keyword=(const char *) attributes[i++];
2240 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002241 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002242 CloneString(&value,attribute);
2243 switch (*keyword)
2244 {
2245 case 'D':
2246 case 'd':
2247 {
2248 if (LocaleCompare(keyword,"display") == 0)
2249 {
cristyf2f27272009-12-17 14:48:46 +00002250 display=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002251 break;
2252 }
2253 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2254 keyword);
2255 break;
2256 }
2257 default:
2258 {
2259 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2260 keyword);
2261 break;
2262 }
2263 }
2264 }
2265 (void) CycleColormapImage(msl_info->image[n],display);
2266 break;
2267 }
2268 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2269 }
2270 case 'D':
2271 case 'd':
2272 {
cristyb988fe72009-09-16 01:01:10 +00002273 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002274 {
2275 Image
2276 *despeckle_image;
2277
2278 /*
2279 Despeckle image.
2280 */
2281 if (msl_info->image[n] == (Image *) NULL)
2282 {
cristyb988fe72009-09-16 01:01:10 +00002283 ThrowMSLException(OptionError,"NoImagesDefined",
2284 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002285 break;
2286 }
2287 if (attributes != (const xmlChar **) NULL)
2288 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2289 {
2290 keyword=(const char *) attributes[i++];
2291 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002292 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002293 CloneString(&value,attribute);
2294 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2295 }
2296 despeckle_image=DespeckleImage(msl_info->image[n],
2297 &msl_info->image[n]->exception);
2298 if (despeckle_image == (Image *) NULL)
2299 break;
2300 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2301 msl_info->image[n]=despeckle_image;
2302 break;
2303 }
cristyb988fe72009-09-16 01:01:10 +00002304 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002305 {
2306 if (msl_info->image[n] == (Image *) NULL)
2307 {
cristyb988fe72009-09-16 01:01:10 +00002308 ThrowMSLException(OptionError,"NoImagesDefined",
2309 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002310 break;
2311 }
2312 if (attributes != (const xmlChar **) NULL)
2313 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2314 {
2315 keyword=(const char *) attributes[i++];
2316 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002317 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002318 CloneString(&value,attribute);
2319 switch (*keyword)
2320 {
2321 default:
2322 {
2323 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2324 keyword);
2325 break;
2326 }
2327 }
2328 }
2329 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n]);
2330 break;
2331 }
cristyb988fe72009-09-16 01:01:10 +00002332 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002333 {
2334 char
2335 text[MaxTextExtent];
2336
2337 /*
2338 Annotate image.
2339 */
2340 if (msl_info->image[n] == (Image *) NULL)
2341 {
cristyb988fe72009-09-16 01:01:10 +00002342 ThrowMSLException(OptionError,"NoImagesDefined",
2343 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002344 break;
2345 }
2346 draw_info=CloneDrawInfo(msl_info->image_info[n],
2347 msl_info->draw_info[n]);
2348 angle=0.0;
2349 current=draw_info->affine;
2350 GetAffineMatrix(&affine);
2351 if (attributes != (const xmlChar **) NULL)
2352 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2353 {
2354 keyword=(const char *) attributes[i++];
2355 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002356 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002357 CloneString(&value,attribute);
2358 switch (*keyword)
2359 {
2360 case 'A':
2361 case 'a':
2362 {
2363 if (LocaleCompare(keyword,"affine") == 0)
2364 {
2365 char
2366 *p;
2367
2368 p=value;
2369 draw_info->affine.sx=strtod(p,&p);
2370 if (*p ==',')
2371 p++;
2372 draw_info->affine.rx=strtod(p,&p);
2373 if (*p ==',')
2374 p++;
2375 draw_info->affine.ry=strtod(p,&p);
2376 if (*p ==',')
2377 p++;
2378 draw_info->affine.sy=strtod(p,&p);
2379 if (*p ==',')
2380 p++;
2381 draw_info->affine.tx=strtod(p,&p);
2382 if (*p ==',')
2383 p++;
2384 draw_info->affine.ty=strtod(p,&p);
2385 break;
2386 }
2387 if (LocaleCompare(keyword,"align") == 0)
2388 {
2389 option=ParseMagickOption(MagickAlignOptions,MagickFalse,
2390 value);
2391 if (option < 0)
2392 ThrowMSLException(OptionError,"UnrecognizedAlignType",
2393 value);
2394 draw_info->align=(AlignType) option;
2395 break;
2396 }
2397 if (LocaleCompare(keyword,"antialias") == 0)
2398 {
2399 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2400 value);
2401 if (option < 0)
2402 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2403 value);
2404 draw_info->stroke_antialias=(MagickBooleanType) option;
2405 draw_info->text_antialias=(MagickBooleanType) option;
2406 break;
2407 }
2408 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2409 keyword);
2410 break;
2411 }
2412 case 'D':
2413 case 'd':
2414 {
2415 if (LocaleCompare(keyword,"density") == 0)
2416 {
2417 CloneString(&draw_info->density,value);
2418 break;
2419 }
2420 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2421 keyword);
2422 break;
2423 }
2424 case 'E':
2425 case 'e':
2426 {
2427 if (LocaleCompare(keyword,"encoding") == 0)
2428 {
2429 CloneString(&draw_info->encoding,value);
2430 break;
2431 }
2432 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2433 keyword);
2434 break;
2435 }
2436 case 'F':
2437 case 'f':
2438 {
2439 if (LocaleCompare(keyword, "fill") == 0)
2440 {
2441 (void) QueryColorDatabase(value,&draw_info->fill,
2442 &exception);
2443 break;
2444 }
2445 if (LocaleCompare(keyword,"family") == 0)
2446 {
2447 CloneString(&draw_info->family,value);
2448 break;
2449 }
2450 if (LocaleCompare(keyword,"font") == 0)
2451 {
2452 CloneString(&draw_info->font,value);
2453 break;
2454 }
2455 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2456 keyword);
2457 break;
2458 }
2459 case 'G':
2460 case 'g':
2461 {
2462 if (LocaleCompare(keyword,"geometry") == 0)
2463 {
2464 flags=ParsePageGeometry(msl_info->image[n],value,
2465 &geometry,&exception);
2466 if ((flags & HeightValue) == 0)
2467 geometry.height=geometry.width;
2468 break;
2469 }
2470 if (LocaleCompare(keyword,"gravity") == 0)
2471 {
2472 option=ParseMagickOption(MagickGravityOptions,MagickFalse,
2473 value);
2474 if (option < 0)
2475 ThrowMSLException(OptionError,"UnrecognizedGravityType",
2476 value);
2477 draw_info->gravity=(GravityType) option;
2478 break;
2479 }
2480 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2481 keyword);
2482 break;
2483 }
2484 case 'P':
2485 case 'p':
2486 {
2487 if (LocaleCompare(keyword,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002488 {
cristy3ed852e2009-09-05 21:47:34 +00002489 CloneString(&draw_info->primitive,value);
2490 break;
2491 }
2492 if (LocaleCompare(keyword,"pointsize") == 0)
2493 {
cristyf2f27272009-12-17 14:48:46 +00002494 draw_info->pointsize=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002495 break;
2496 }
2497 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2498 keyword);
2499 break;
2500 }
2501 case 'R':
2502 case 'r':
2503 {
2504 if (LocaleCompare(keyword,"rotate") == 0)
2505 {
cristyf2f27272009-12-17 14:48:46 +00002506 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002507 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2508 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2509 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2510 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2511 break;
2512 }
2513 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2514 keyword);
2515 break;
2516 }
2517 case 'S':
2518 case 's':
2519 {
2520 if (LocaleCompare(keyword,"scale") == 0)
2521 {
2522 flags=ParseGeometry(value,&geometry_info);
2523 if ((flags & SigmaValue) == 0)
2524 geometry_info.sigma=1.0;
2525 affine.sx=geometry_info.rho;
2526 affine.sy=geometry_info.sigma;
2527 break;
2528 }
2529 if (LocaleCompare(keyword,"skewX") == 0)
2530 {
cristyf2f27272009-12-17 14:48:46 +00002531 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002532 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2533 break;
2534 }
2535 if (LocaleCompare(keyword,"skewY") == 0)
2536 {
cristyf2f27272009-12-17 14:48:46 +00002537 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002538 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2539 break;
2540 }
2541 if (LocaleCompare(keyword,"stretch") == 0)
2542 {
2543 option=ParseMagickOption(MagickStretchOptions,MagickFalse,
2544 value);
2545 if (option < 0)
2546 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2547 value);
2548 draw_info->stretch=(StretchType) option;
2549 break;
2550 }
2551 if (LocaleCompare(keyword, "stroke") == 0)
2552 {
2553 (void) QueryColorDatabase(value,&draw_info->stroke,
2554 &exception);
2555 break;
2556 }
2557 if (LocaleCompare(keyword,"strokewidth") == 0)
2558 {
cristyf2f27272009-12-17 14:48:46 +00002559 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002560 break;
2561 }
2562 if (LocaleCompare(keyword,"style") == 0)
2563 {
2564 option=ParseMagickOption(MagickStyleOptions,MagickFalse,
2565 value);
2566 if (option < 0)
2567 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2568 value);
2569 draw_info->style=(StyleType) option;
2570 break;
2571 }
2572 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2573 keyword);
2574 break;
2575 }
2576 case 'T':
2577 case 't':
2578 {
2579 if (LocaleCompare(keyword,"text") == 0)
2580 {
2581 CloneString(&draw_info->text,value);
2582 break;
2583 }
2584 if (LocaleCompare(keyword,"translate") == 0)
2585 {
2586 flags=ParseGeometry(value,&geometry_info);
2587 if ((flags & SigmaValue) == 0)
2588 geometry_info.sigma=1.0;
2589 affine.tx=geometry_info.rho;
2590 affine.ty=geometry_info.sigma;
2591 break;
2592 }
2593 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2594 keyword);
2595 break;
2596 }
2597 case 'U':
2598 case 'u':
2599 {
2600 if (LocaleCompare(keyword, "undercolor") == 0)
2601 {
2602 (void) QueryColorDatabase(value,&draw_info->undercolor,
2603 &exception);
2604 break;
2605 }
2606 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2607 keyword);
2608 break;
2609 }
2610 case 'W':
2611 case 'w':
2612 {
2613 if (LocaleCompare(keyword,"weight") == 0)
2614 {
cristyf2f27272009-12-17 14:48:46 +00002615 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002616 break;
2617 }
2618 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2619 keyword);
2620 break;
2621 }
2622 case 'X':
2623 case 'x':
2624 {
2625 if (LocaleCompare(keyword,"x") == 0)
2626 {
cristyf2f27272009-12-17 14:48:46 +00002627 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002628 break;
2629 }
2630 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2631 keyword);
2632 break;
2633 }
2634 case 'Y':
2635 case 'y':
2636 {
2637 if (LocaleCompare(keyword,"y") == 0)
2638 {
cristyf2f27272009-12-17 14:48:46 +00002639 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002640 break;
2641 }
2642 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2643 keyword);
2644 break;
2645 }
2646 default:
2647 {
2648 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2649 keyword);
2650 break;
2651 }
2652 }
2653 }
cristye8c25f92010-06-03 00:53:06 +00002654 (void) FormatMagickString(text,MaxTextExtent,
2655 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2656 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002657 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002658 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2659 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2660 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2661 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2662 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2663 affine.tx;
2664 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2665 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00002666 (void) DrawImage(msl_info->image[n],draw_info);
2667 draw_info=DestroyDrawInfo(draw_info);
2668 break;
2669 }
2670 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2671 }
2672 case 'E':
2673 case 'e':
2674 {
cristyb988fe72009-09-16 01:01:10 +00002675 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002676 {
2677 Image
2678 *edge_image;
2679
2680 /*
2681 Edge image.
2682 */
2683 if (msl_info->image[n] == (Image *) NULL)
2684 {
cristyb988fe72009-09-16 01:01:10 +00002685 ThrowMSLException(OptionError,"NoImagesDefined",
2686 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002687 break;
2688 }
2689 if (attributes != (const xmlChar **) NULL)
2690 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2691 {
2692 keyword=(const char *) attributes[i++];
2693 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002694 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002695 CloneString(&value,attribute);
2696 switch (*keyword)
2697 {
2698 case 'G':
2699 case 'g':
2700 {
2701 if (LocaleCompare(keyword,"geometry") == 0)
2702 {
2703 flags=ParseGeometry(value,&geometry_info);
2704 if ((flags & SigmaValue) == 0)
2705 geometry_info.sigma=1.0;
2706 break;
2707 }
2708 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2709 keyword);
2710 break;
2711 }
2712 case 'R':
2713 case 'r':
2714 {
2715 if (LocaleCompare(keyword,"radius") == 0)
2716 {
cristyf2f27272009-12-17 14:48:46 +00002717 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002718 break;
2719 }
2720 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2721 keyword);
2722 break;
2723 }
2724 default:
2725 {
2726 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2727 keyword);
2728 break;
2729 }
2730 }
2731 }
2732 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
2733 &msl_info->image[n]->exception);
2734 if (edge_image == (Image *) NULL)
2735 break;
2736 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2737 msl_info->image[n]=edge_image;
2738 break;
2739 }
cristyb988fe72009-09-16 01:01:10 +00002740 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002741 {
2742 Image
2743 *emboss_image;
2744
2745 /*
2746 Emboss image.
2747 */
2748 if (msl_info->image[n] == (Image *) NULL)
2749 {
cristyb988fe72009-09-16 01:01:10 +00002750 ThrowMSLException(OptionError,"NoImagesDefined",
2751 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002752 break;
2753 }
2754 if (attributes != (const xmlChar **) NULL)
2755 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2756 {
2757 keyword=(const char *) attributes[i++];
2758 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002759 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002760 CloneString(&value,attribute);
2761 switch (*keyword)
2762 {
2763 case 'G':
2764 case 'g':
2765 {
2766 if (LocaleCompare(keyword,"geometry") == 0)
2767 {
2768 flags=ParseGeometry(value,&geometry_info);
2769 if ((flags & SigmaValue) == 0)
2770 geometry_info.sigma=1.0;
2771 break;
2772 }
2773 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2774 keyword);
2775 break;
2776 }
2777 case 'R':
2778 case 'r':
2779 {
2780 if (LocaleCompare(keyword,"radius") == 0)
2781 {
cristyf2f27272009-12-17 14:48:46 +00002782 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002783 break;
2784 }
2785 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2786 keyword);
2787 break;
2788 }
2789 case 'S':
2790 case 's':
2791 {
2792 if (LocaleCompare(keyword,"sigma") == 0)
2793 {
cristyf2f27272009-12-17 14:48:46 +00002794 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002795 break;
2796 }
2797 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2798 keyword);
2799 break;
2800 }
2801 default:
2802 {
2803 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2804 keyword);
2805 break;
2806 }
2807 }
2808 }
2809 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2810 geometry_info.sigma,&msl_info->image[n]->exception);
2811 if (emboss_image == (Image *) NULL)
2812 break;
2813 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2814 msl_info->image[n]=emboss_image;
2815 break;
2816 }
cristyb988fe72009-09-16 01:01:10 +00002817 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002818 {
2819 Image
2820 *enhance_image;
2821
2822 /*
2823 Enhance image.
2824 */
2825 if (msl_info->image[n] == (Image *) NULL)
2826 {
cristyb988fe72009-09-16 01:01:10 +00002827 ThrowMSLException(OptionError,"NoImagesDefined",
2828 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002829 break;
2830 }
2831 if (attributes != (const xmlChar **) NULL)
2832 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2833 {
2834 keyword=(const char *) attributes[i++];
2835 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002836 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002837 CloneString(&value,attribute);
2838 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2839 }
2840 enhance_image=EnhanceImage(msl_info->image[n],
2841 &msl_info->image[n]->exception);
2842 if (enhance_image == (Image *) NULL)
2843 break;
2844 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2845 msl_info->image[n]=enhance_image;
2846 break;
2847 }
cristyb988fe72009-09-16 01:01:10 +00002848 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002849 {
2850 /*
2851 Equalize image.
2852 */
2853 if (msl_info->image[n] == (Image *) NULL)
2854 {
cristyb988fe72009-09-16 01:01:10 +00002855 ThrowMSLException(OptionError,"NoImagesDefined",
2856 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002857 break;
2858 }
2859 if (attributes != (const xmlChar **) NULL)
2860 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2861 {
2862 keyword=(const char *) attributes[i++];
2863 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002864 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002865 CloneString(&value,attribute);
2866 switch (*keyword)
2867 {
2868 default:
2869 {
2870 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2871 keyword);
2872 break;
2873 }
2874 }
2875 }
2876 (void) EqualizeImage(msl_info->image[n]);
2877 break;
2878 }
2879 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2880 }
2881 case 'F':
2882 case 'f':
2883 {
cristyb988fe72009-09-16 01:01:10 +00002884 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002885 {
2886 if (msl_info->image[n] == (Image *) NULL)
2887 {
cristyb988fe72009-09-16 01:01:10 +00002888 ThrowMSLException(OptionError,"NoImagesDefined",
2889 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002890 break;
2891 }
2892
2893 /* no attributes here */
2894
2895 /* process the image */
2896 {
2897 Image
2898 *newImage;
2899
2900 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2901 &msl_info->image[n]->exception);
2902 if (newImage == (Image *) NULL)
2903 break;
2904 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2905 msl_info->image[n]=newImage;
2906 break;
2907 }
2908 }
cristyb988fe72009-09-16 01:01:10 +00002909 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002910 {
2911 Image
2912 *flip_image;
2913
2914 /*
2915 Flip image.
2916 */
2917 if (msl_info->image[n] == (Image *) NULL)
2918 {
cristyb988fe72009-09-16 01:01:10 +00002919 ThrowMSLException(OptionError,"NoImagesDefined",
2920 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002921 break;
2922 }
2923 if (attributes != (const xmlChar **) NULL)
2924 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2925 {
2926 keyword=(const char *) attributes[i++];
2927 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002928 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002929 CloneString(&value,attribute);
2930 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2931 }
2932 flip_image=FlipImage(msl_info->image[n],
2933 &msl_info->image[n]->exception);
2934 if (flip_image == (Image *) NULL)
2935 break;
2936 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2937 msl_info->image[n]=flip_image;
2938 break;
2939 }
cristyb988fe72009-09-16 01:01:10 +00002940 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002941 {
2942 Image
2943 *flop_image;
2944
2945 /*
2946 Flop image.
2947 */
2948 if (msl_info->image[n] == (Image *) NULL)
2949 {
cristyb988fe72009-09-16 01:01:10 +00002950 ThrowMSLException(OptionError,"NoImagesDefined",
2951 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002952 break;
2953 }
2954 if (attributes != (const xmlChar **) NULL)
2955 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2956 {
2957 keyword=(const char *) attributes[i++];
2958 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002959 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002960 CloneString(&value,attribute);
2961 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2962 }
2963 flop_image=FlopImage(msl_info->image[n],
2964 &msl_info->image[n]->exception);
2965 if (flop_image == (Image *) NULL)
2966 break;
2967 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2968 msl_info->image[n]=flop_image;
2969 break;
2970 }
cristyb988fe72009-09-16 01:01:10 +00002971 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002972 {
2973 FrameInfo
2974 frame_info;
2975
2976 Image
2977 *frame_image;
2978
2979 /*
2980 Frame image.
2981 */
2982 if (msl_info->image[n] == (Image *) NULL)
2983 {
cristyb988fe72009-09-16 01:01:10 +00002984 ThrowMSLException(OptionError,"NoImagesDefined",
2985 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002986 break;
2987 }
2988 SetGeometry(msl_info->image[n],&geometry);
2989 if (attributes != (const xmlChar **) NULL)
2990 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2991 {
2992 keyword=(const char *) attributes[i++];
2993 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002994 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002995 CloneString(&value,attribute);
2996 switch (*keyword)
2997 {
2998 case 'C':
2999 case 'c':
3000 {
3001 if (LocaleCompare(keyword,"compose") == 0)
3002 {
3003 option=ParseMagickOption(MagickComposeOptions,
3004 MagickFalse,value);
3005 if (option < 0)
3006 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3007 value);
3008 msl_info->image[n]->compose=(CompositeOperator) option;
3009 break;
3010 }
3011 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3012 keyword);
3013 break;
3014 }
3015 case 'F':
3016 case 'f':
3017 {
3018 if (LocaleCompare(keyword, "fill") == 0)
3019 {
3020 (void) QueryColorDatabase(value,
3021 &msl_info->image[n]->matte_color,&exception);
3022 break;
3023 }
3024 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3025 keyword);
3026 break;
3027 }
3028 case 'G':
3029 case 'g':
3030 {
3031 if (LocaleCompare(keyword,"geometry") == 0)
3032 {
3033 flags=ParsePageGeometry(msl_info->image[n],value,
3034 &geometry,&exception);
3035 if ((flags & HeightValue) == 0)
3036 geometry.height=geometry.width;
3037 frame_info.width=geometry.width;
3038 frame_info.height=geometry.height;
3039 frame_info.outer_bevel=geometry.x;
3040 frame_info.inner_bevel=geometry.y;
3041 break;
3042 }
3043 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3044 keyword);
3045 break;
3046 }
3047 case 'H':
3048 case 'h':
3049 {
3050 if (LocaleCompare(keyword,"height") == 0)
3051 {
cristyf2f27272009-12-17 14:48:46 +00003052 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003053 break;
3054 }
3055 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3056 keyword);
3057 break;
3058 }
3059 case 'I':
3060 case 'i':
3061 {
3062 if (LocaleCompare(keyword,"inner") == 0)
3063 {
cristyf2f27272009-12-17 14:48:46 +00003064 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003065 break;
3066 }
3067 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3068 keyword);
3069 break;
3070 }
3071 case 'O':
3072 case 'o':
3073 {
3074 if (LocaleCompare(keyword,"outer") == 0)
3075 {
cristyf2f27272009-12-17 14:48:46 +00003076 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003077 break;
3078 }
3079 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3080 keyword);
3081 break;
3082 }
3083 case 'W':
3084 case 'w':
3085 {
3086 if (LocaleCompare(keyword,"width") == 0)
3087 {
cristyf2f27272009-12-17 14:48:46 +00003088 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003089 break;
3090 }
3091 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3092 keyword);
3093 break;
3094 }
3095 default:
3096 {
3097 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3098 keyword);
3099 break;
3100 }
3101 }
3102 }
cristybb503372010-05-27 20:51:26 +00003103 frame_info.x=(ssize_t) frame_info.width;
3104 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003105 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3106 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3107 frame_image=FrameImage(msl_info->image[n],&frame_info,
3108 &msl_info->image[n]->exception);
3109 if (frame_image == (Image *) NULL)
3110 break;
3111 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3112 msl_info->image[n]=frame_image;
3113 break;
3114 }
3115 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3116 }
3117 case 'G':
3118 case 'g':
3119 {
cristyb988fe72009-09-16 01:01:10 +00003120 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003121 {
3122 char
3123 gamma[MaxTextExtent];
3124
3125 MagickPixelPacket
3126 pixel;
3127
3128 /*
3129 Gamma image.
3130 */
3131 if (msl_info->image[n] == (Image *) NULL)
3132 {
cristyb988fe72009-09-16 01:01:10 +00003133 ThrowMSLException(OptionError,"NoImagesDefined",
3134 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003135 break;
3136 }
3137 channel=UndefinedChannel;
3138 pixel.red=0.0;
3139 pixel.green=0.0;
3140 pixel.blue=0.0;
3141 *gamma='\0';
3142 if (attributes != (const xmlChar **) NULL)
3143 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3144 {
3145 keyword=(const char *) attributes[i++];
3146 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003147 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003148 CloneString(&value,attribute);
3149 switch (*keyword)
3150 {
3151 case 'B':
3152 case 'b':
3153 {
3154 if (LocaleCompare(keyword,"blue") == 0)
3155 {
cristyf2f27272009-12-17 14:48:46 +00003156 pixel.blue=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003157 break;
3158 }
3159 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3160 keyword);
3161 break;
3162 }
3163 case 'C':
3164 case 'c':
3165 {
3166 if (LocaleCompare(keyword,"channel") == 0)
3167 {
3168 option=ParseChannelOption(value);
3169 if (option < 0)
3170 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3171 value);
3172 channel=(ChannelType) option;
3173 break;
3174 }
3175 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3176 keyword);
3177 break;
3178 }
3179 case 'G':
3180 case 'g':
3181 {
3182 if (LocaleCompare(keyword,"gamma") == 0)
3183 {
3184 (void) CopyMagickString(gamma,value,MaxTextExtent);
3185 break;
3186 }
3187 if (LocaleCompare(keyword,"green") == 0)
3188 {
cristyf2f27272009-12-17 14:48:46 +00003189 pixel.green=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003190 break;
3191 }
3192 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3193 keyword);
3194 break;
3195 }
3196 case 'R':
3197 case 'r':
3198 {
3199 if (LocaleCompare(keyword,"red") == 0)
3200 {
cristyf2f27272009-12-17 14:48:46 +00003201 pixel.red=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003202 break;
3203 }
3204 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3205 keyword);
3206 break;
3207 }
3208 default:
3209 {
3210 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3211 keyword);
3212 break;
3213 }
3214 }
3215 }
3216 if (*gamma == '\0')
cristye7f51092010-01-17 00:39:37 +00003217 (void) FormatMagickString(gamma,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003218 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb988fe72009-09-16 01:01:10 +00003219 switch (channel)
cristy3ed852e2009-09-05 21:47:34 +00003220 {
3221 default:
3222 {
3223 (void) GammaImage(msl_info->image[n],gamma);
3224 break;
3225 }
3226 case RedChannel:
3227 {
3228 (void) GammaImageChannel(msl_info->image[n],RedChannel,pixel.red);
3229 break;
3230 }
3231 case GreenChannel:
3232 {
3233 (void) GammaImageChannel(msl_info->image[n],GreenChannel,
3234 pixel.green);
3235 break;
3236 }
3237 case BlueChannel:
3238 {
3239 (void) GammaImageChannel(msl_info->image[n],BlueChannel,
3240 pixel.blue);
3241 break;
3242 }
3243 }
3244 break;
3245 }
cristyb988fe72009-09-16 01:01:10 +00003246 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003247 {
3248 if (msl_info->image[n] == (Image *) NULL)
3249 {
cristyb988fe72009-09-16 01:01:10 +00003250 ThrowMSLException(OptionError,"NoImagesDefined",
3251 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003252 break;
3253 }
3254 if (attributes == (const xmlChar **) NULL)
3255 break;
3256 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3257 {
3258 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003259 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003260 (void) CopyMagickString(key,value,MaxTextExtent);
3261 switch (*keyword)
3262 {
3263 case 'H':
3264 case 'h':
3265 {
3266 if (LocaleCompare(keyword,"height") == 0)
3267 {
cristye8c25f92010-06-03 00:53:06 +00003268 (void) FormatMagickString(value,MaxTextExtent,"%.20g",
3269 (double) msl_info->image[n]->rows);
cristy3ed852e2009-09-05 21:47:34 +00003270 (void) SetImageProperty(msl_info->attributes[n],key,value);
3271 break;
3272 }
3273 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3274 }
3275 case 'W':
3276 case 'w':
3277 {
3278 if (LocaleCompare(keyword,"width") == 0)
3279 {
cristye8c25f92010-06-03 00:53:06 +00003280 (void) FormatMagickString(value,MaxTextExtent,"%.20g",
3281 (double) msl_info->image[n]->columns);
cristy3ed852e2009-09-05 21:47:34 +00003282 (void) SetImageProperty(msl_info->attributes[n],key,value);
3283 break;
3284 }
3285 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3286 }
3287 default:
3288 {
3289 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3290 break;
3291 }
3292 }
3293 }
3294 break;
3295 }
cristyb988fe72009-09-16 01:01:10 +00003296 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003297 {
3298 msl_info->number_groups++;
3299 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3300 msl_info->group_info,msl_info->number_groups+1UL,
3301 sizeof(*msl_info->group_info));
3302 break;
3303 }
3304 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3305 }
3306 case 'I':
3307 case 'i':
3308 {
cristyb988fe72009-09-16 01:01:10 +00003309 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003310 {
cristy3ed852e2009-09-05 21:47:34 +00003311 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003312 if (attributes == (const xmlChar **) NULL)
3313 break;
3314 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3315 {
3316 keyword=(const char *) attributes[i++];
3317 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003318 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00003319 switch (*keyword)
3320 {
cristyb988fe72009-09-16 01:01:10 +00003321 case 'C':
3322 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003323 {
cristyb988fe72009-09-16 01:01:10 +00003324 if (LocaleCompare(keyword,"color") == 0)
3325 {
3326 Image
3327 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003328
cristyb988fe72009-09-16 01:01:10 +00003329 (void) CopyMagickString(msl_info->image_info[n]->filename,
3330 "xc:",MaxTextExtent);
3331 (void) ConcatenateMagickString(msl_info->image_info[n]->
3332 filename,value,MaxTextExtent);
3333 next_image=ReadImage(msl_info->image_info[n],&exception);
3334 CatchException(&exception);
3335 if (next_image == (Image *) NULL)
3336 continue;
3337 if (msl_info->image[n] == (Image *) NULL)
3338 msl_info->image[n]=next_image;
3339 else
3340 {
3341 register Image
3342 *p;
cristy3ed852e2009-09-05 21:47:34 +00003343
cristyb988fe72009-09-16 01:01:10 +00003344 /*
3345 Link image into image list.
3346 */
3347 p=msl_info->image[n];
3348 while (p->next != (Image *) NULL)
3349 p=GetNextImageInList(p);
3350 next_image->previous=p;
3351 p->next=next_image;
3352 }
3353 break;
3354 }
cristyb20775d2009-09-16 01:51:41 +00003355 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003356 break;
3357 }
3358 default:
3359 {
cristyb20775d2009-09-16 01:51:41 +00003360 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003361 break;
3362 }
3363 }
3364 }
3365 break;
3366 }
cristyb988fe72009-09-16 01:01:10 +00003367 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003368 {
3369 Image
3370 *implode_image;
3371
3372 /*
3373 Implode image.
3374 */
3375 if (msl_info->image[n] == (Image *) NULL)
3376 {
cristyb988fe72009-09-16 01:01:10 +00003377 ThrowMSLException(OptionError,"NoImagesDefined",
3378 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003379 break;
3380 }
3381 if (attributes != (const xmlChar **) NULL)
3382 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3383 {
3384 keyword=(const char *) attributes[i++];
3385 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003386 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003387 CloneString(&value,attribute);
3388 switch (*keyword)
3389 {
3390 case 'A':
3391 case 'a':
3392 {
3393 if (LocaleCompare(keyword,"amount") == 0)
3394 {
cristyf2f27272009-12-17 14:48:46 +00003395 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003396 break;
3397 }
3398 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3399 keyword);
3400 break;
3401 }
3402 case 'G':
3403 case 'g':
3404 {
3405 if (LocaleCompare(keyword,"geometry") == 0)
3406 {
3407 flags=ParseGeometry(value,&geometry_info);
3408 if ((flags & SigmaValue) == 0)
3409 geometry_info.sigma=1.0;
3410 break;
3411 }
3412 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3413 keyword);
3414 break;
3415 }
3416 default:
3417 {
3418 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3419 keyword);
3420 break;
3421 }
3422 }
3423 }
3424 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3425 &msl_info->image[n]->exception);
3426 if (implode_image == (Image *) NULL)
3427 break;
3428 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3429 msl_info->image[n]=implode_image;
3430 break;
3431 }
3432 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3433 }
3434 case 'L':
3435 case 'l':
3436 {
cristyb988fe72009-09-16 01:01:10 +00003437 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003438 break;
cristyb988fe72009-09-16 01:01:10 +00003439 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003440 {
3441 double
3442 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3443
3444 if (msl_info->image[n] == (Image *) NULL)
3445 {
cristyb988fe72009-09-16 01:01:10 +00003446 ThrowMSLException(OptionError,"NoImagesDefined",
3447 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003448 break;
3449 }
3450 if (attributes == (const xmlChar **) NULL)
3451 break;
3452 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3453 {
3454 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003455 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003456 (void) CopyMagickString(key,value,MaxTextExtent);
3457 switch (*keyword)
3458 {
3459 case 'B':
3460 case 'b':
3461 {
3462 if (LocaleCompare(keyword,"black") == 0)
3463 {
cristyf2f27272009-12-17 14:48:46 +00003464 levelBlack = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00003465 break;
3466 }
3467 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3468 break;
3469 }
3470 case 'G':
3471 case 'g':
3472 {
3473 if (LocaleCompare(keyword,"gamma") == 0)
3474 {
cristyf2f27272009-12-17 14:48:46 +00003475 levelGamma = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00003476 break;
3477 }
3478 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3479 break;
3480 }
3481 case 'W':
3482 case 'w':
3483 {
3484 if (LocaleCompare(keyword,"white") == 0)
3485 {
cristyf2f27272009-12-17 14:48:46 +00003486 levelWhite = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00003487 break;
3488 }
3489 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3490 break;
3491 }
3492 default:
3493 {
3494 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3495 break;
3496 }
3497 }
3498 }
3499
3500 /* process image */
3501 {
3502 char level[MaxTextExtent + 1];
3503 (void) FormatMagickString(level,MaxTextExtent,"%3.6f/%3.6f/%3.6f/",
3504 levelBlack,levelGamma,levelWhite);
3505 LevelImage ( msl_info->image[n], level );
3506 break;
3507 }
3508 }
3509 }
3510 case 'M':
3511 case 'm':
3512 {
cristyb988fe72009-09-16 01:01:10 +00003513 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003514 {
3515 Image
3516 *magnify_image;
3517
3518 /*
3519 Magnify image.
3520 */
3521 if (msl_info->image[n] == (Image *) NULL)
3522 {
cristyb988fe72009-09-16 01:01:10 +00003523 ThrowMSLException(OptionError,"NoImagesDefined",
3524 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003525 break;
3526 }
3527 if (attributes != (const xmlChar **) NULL)
3528 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3529 {
3530 keyword=(const char *) attributes[i++];
3531 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003532 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003533 CloneString(&value,attribute);
3534 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3535 }
3536 magnify_image=MagnifyImage(msl_info->image[n],
3537 &msl_info->image[n]->exception);
3538 if (magnify_image == (Image *) NULL)
3539 break;
3540 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3541 msl_info->image[n]=magnify_image;
3542 break;
3543 }
cristyb988fe72009-09-16 01:01:10 +00003544 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003545 {
3546 Image
3547 *affinity_image;
3548
3549 MagickBooleanType
3550 dither;
3551
3552 QuantizeInfo
3553 *quantize_info;
3554
3555 /*
3556 Map image.
3557 */
3558 if (msl_info->image[n] == (Image *) NULL)
3559 {
cristyb988fe72009-09-16 01:01:10 +00003560 ThrowMSLException(OptionError,"NoImagesDefined",
3561 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003562 break;
3563 }
3564 affinity_image=NewImageList();
3565 dither=MagickFalse;
3566 if (attributes != (const xmlChar **) NULL)
3567 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3568 {
3569 keyword=(const char *) attributes[i++];
3570 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003571 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003572 CloneString(&value,attribute);
3573 switch (*keyword)
3574 {
3575 case 'D':
3576 case 'd':
3577 {
3578 if (LocaleCompare(keyword,"dither") == 0)
3579 {
3580 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
3581 value);
3582 if (option < 0)
3583 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3584 value);
3585 dither=(MagickBooleanType) option;
3586 break;
3587 }
3588 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3589 keyword);
3590 break;
3591 }
3592 case 'I':
3593 case 'i':
3594 {
3595 if (LocaleCompare(keyword,"image") == 0)
3596 for (j=0; j < msl_info->n; j++)
3597 {
3598 const char
3599 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003600
cristy3ed852e2009-09-05 21:47:34 +00003601 attribute=GetImageProperty(msl_info->attributes[j],"id");
3602 if ((attribute != (const char *) NULL) &&
3603 (LocaleCompare(attribute,value) == 0))
3604 {
3605 affinity_image=CloneImage(msl_info->image[j],0,0,
3606 MagickFalse,&exception);
3607 break;
3608 }
3609 }
3610 break;
3611 }
3612 default:
3613 {
3614 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3615 keyword);
3616 break;
3617 }
3618 }
3619 }
3620 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3621 quantize_info->dither=dither;
3622 (void) RemapImages(quantize_info,msl_info->image[n],
3623 affinity_image);
3624 quantize_info=DestroyQuantizeInfo(quantize_info);
3625 affinity_image=DestroyImage(affinity_image);
3626 break;
3627 }
cristyb988fe72009-09-16 01:01:10 +00003628 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003629 {
3630 double
3631 opacity;
3632
3633 MagickPixelPacket
3634 target;
3635
3636 PaintMethod
3637 paint_method;
3638
3639 /*
3640 Matte floodfill image.
3641 */
3642 opacity=0.0;
3643 if (msl_info->image[n] == (Image *) NULL)
3644 {
cristyb988fe72009-09-16 01:01:10 +00003645 ThrowMSLException(OptionError,"NoImagesDefined",
3646 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003647 break;
3648 }
3649 SetGeometry(msl_info->image[n],&geometry);
3650 paint_method=FloodfillMethod;
3651 if (attributes != (const xmlChar **) NULL)
3652 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3653 {
3654 keyword=(const char *) attributes[i++];
3655 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003656 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003657 CloneString(&value,attribute);
3658 switch (*keyword)
3659 {
3660 case 'B':
3661 case 'b':
3662 {
3663 if (LocaleCompare(keyword,"bordercolor") == 0)
3664 {
3665 (void) QueryMagickColor(value,&target,&exception);
3666 paint_method=FillToBorderMethod;
3667 break;
3668 }
3669 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3670 keyword);
3671 break;
3672 }
3673 case 'F':
3674 case 'f':
3675 {
3676 if (LocaleCompare(keyword,"fuzz") == 0)
3677 {
cristyf2f27272009-12-17 14:48:46 +00003678 msl_info->image[n]->fuzz=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003679 break;
3680 }
3681 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3682 keyword);
3683 break;
3684 }
3685 case 'G':
3686 case 'g':
3687 {
3688 if (LocaleCompare(keyword,"geometry") == 0)
3689 {
3690 flags=ParsePageGeometry(msl_info->image[n],value,
3691 &geometry,&exception);
3692 if ((flags & HeightValue) == 0)
3693 geometry.height=geometry.width;
3694 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3695 geometry.x,geometry.y,&target,&exception);
3696 break;
3697 }
3698 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3699 keyword);
3700 break;
3701 }
3702 case 'O':
3703 case 'o':
3704 {
3705 if (LocaleCompare(keyword,"opacity") == 0)
3706 {
cristyf2f27272009-12-17 14:48:46 +00003707 opacity=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003708 break;
3709 }
3710 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3711 keyword);
3712 break;
3713 }
3714 case 'X':
3715 case 'x':
3716 {
3717 if (LocaleCompare(keyword,"x") == 0)
3718 {
cristyf2f27272009-12-17 14:48:46 +00003719 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003720 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3721 geometry.x,geometry.y,&target,&exception);
3722 break;
3723 }
3724 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3725 keyword);
3726 break;
3727 }
3728 case 'Y':
3729 case 'y':
3730 {
3731 if (LocaleCompare(keyword,"y") == 0)
3732 {
cristyf2f27272009-12-17 14:48:46 +00003733 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003734 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3735 geometry.x,geometry.y,&target,&exception);
3736 break;
3737 }
3738 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3739 keyword);
3740 break;
3741 }
3742 default:
3743 {
3744 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3745 keyword);
3746 break;
3747 }
3748 }
3749 }
3750 draw_info=CloneDrawInfo(msl_info->image_info[n],
3751 msl_info->draw_info[n]);
cristyce70c172010-01-07 17:15:30 +00003752 draw_info->fill.opacity=ClampToQuantum(opacity);
cristy3ed852e2009-09-05 21:47:34 +00003753 (void) FloodfillPaintImage(msl_info->image[n],OpacityChannel,
3754 draw_info,&target,geometry.x,geometry.y,
3755 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
3756 draw_info=DestroyDrawInfo(draw_info);
3757 break;
3758 }
cristyb988fe72009-09-16 01:01:10 +00003759 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003760 {
3761 Image
3762 *median_image;
3763
3764 /*
3765 Median-filter image.
3766 */
3767 if (msl_info->image[n] == (Image *) NULL)
3768 {
cristyb988fe72009-09-16 01:01:10 +00003769 ThrowMSLException(OptionError,"NoImagesDefined",
3770 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003771 break;
3772 }
3773 if (attributes != (const xmlChar **) NULL)
3774 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3775 {
3776 keyword=(const char *) attributes[i++];
3777 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003778 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003779 CloneString(&value,attribute);
3780 switch (*keyword)
3781 {
3782 case 'G':
3783 case 'g':
3784 {
3785 if (LocaleCompare(keyword,"geometry") == 0)
3786 {
3787 flags=ParseGeometry(value,&geometry_info);
3788 if ((flags & SigmaValue) == 0)
3789 geometry_info.sigma=1.0;
3790 break;
3791 }
3792 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3793 keyword);
3794 break;
3795 }
3796 case 'R':
3797 case 'r':
3798 {
3799 if (LocaleCompare(keyword,"radius") == 0)
3800 {
cristyf2f27272009-12-17 14:48:46 +00003801 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003802 break;
3803 }
3804 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3805 keyword);
3806 break;
3807 }
3808 default:
3809 {
3810 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3811 keyword);
3812 break;
3813 }
3814 }
3815 }
3816 median_image=MedianFilterImage(msl_info->image[n],geometry_info.rho,
3817 &msl_info->image[n]->exception);
3818 if (median_image == (Image *) NULL)
3819 break;
3820 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3821 msl_info->image[n]=median_image;
3822 break;
3823 }
cristyb988fe72009-09-16 01:01:10 +00003824 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003825 {
3826 Image
3827 *minify_image;
3828
3829 /*
3830 Minify image.
3831 */
3832 if (msl_info->image[n] == (Image *) NULL)
3833 {
cristyb988fe72009-09-16 01:01:10 +00003834 ThrowMSLException(OptionError,"NoImagesDefined",
3835 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003836 break;
3837 }
3838 if (attributes != (const xmlChar **) NULL)
3839 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3840 {
3841 keyword=(const char *) attributes[i++];
3842 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003843 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003844 CloneString(&value,attribute);
3845 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3846 }
3847 minify_image=MinifyImage(msl_info->image[n],
3848 &msl_info->image[n]->exception);
3849 if (minify_image == (Image *) NULL)
3850 break;
3851 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3852 msl_info->image[n]=minify_image;
3853 break;
3854 }
cristyb988fe72009-09-16 01:01:10 +00003855 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003856 break;
cristyb988fe72009-09-16 01:01:10 +00003857 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003858 {
3859 char
3860 modulate[MaxTextExtent];
3861
3862 /*
3863 Modulate image.
3864 */
3865 if (msl_info->image[n] == (Image *) NULL)
3866 {
cristyb988fe72009-09-16 01:01:10 +00003867 ThrowMSLException(OptionError,"NoImagesDefined",
3868 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003869 break;
3870 }
3871 geometry_info.rho=100.0;
3872 geometry_info.sigma=100.0;
3873 geometry_info.xi=100.0;
3874 if (attributes != (const xmlChar **) NULL)
3875 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3876 {
3877 keyword=(const char *) attributes[i++];
3878 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003879 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003880 CloneString(&value,attribute);
3881 switch (*keyword)
3882 {
3883 case 'B':
3884 case 'b':
3885 {
3886 if (LocaleCompare(keyword,"blackness") == 0)
3887 {
cristyf2f27272009-12-17 14:48:46 +00003888 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003889 break;
3890 }
3891 if (LocaleCompare(keyword,"brightness") == 0)
3892 {
cristyf2f27272009-12-17 14:48:46 +00003893 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003894 break;
3895 }
3896 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3897 keyword);
3898 break;
3899 }
3900 case 'F':
3901 case 'f':
3902 {
3903 if (LocaleCompare(keyword,"factor") == 0)
3904 {
3905 flags=ParseGeometry(value,&geometry_info);
3906 break;
3907 }
3908 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3909 keyword);
3910 break;
3911 }
3912 case 'H':
3913 case 'h':
3914 {
3915 if (LocaleCompare(keyword,"hue") == 0)
3916 {
cristyf2f27272009-12-17 14:48:46 +00003917 geometry_info.xi=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003918 break;
3919 }
3920 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3921 keyword);
3922 break;
3923 }
3924 case 'L':
3925 case 'l':
3926 {
3927 if (LocaleCompare(keyword,"lightness") == 0)
3928 {
cristyf2f27272009-12-17 14:48:46 +00003929 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003930 break;
3931 }
3932 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3933 keyword);
3934 break;
3935 }
3936 case 'S':
3937 case 's':
3938 {
3939 if (LocaleCompare(keyword,"saturation") == 0)
3940 {
cristyf2f27272009-12-17 14:48:46 +00003941 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003942 break;
3943 }
3944 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3945 keyword);
3946 break;
3947 }
3948 case 'W':
3949 case 'w':
3950 {
3951 if (LocaleCompare(keyword,"whiteness") == 0)
3952 {
cristyf2f27272009-12-17 14:48:46 +00003953 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003954 break;
3955 }
3956 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3957 keyword);
3958 break;
3959 }
3960 default:
3961 {
3962 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3963 keyword);
3964 break;
3965 }
3966 }
3967 }
cristye7f51092010-01-17 00:39:37 +00003968 (void) FormatMagickString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003969 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
3970 (void) ModulateImage(msl_info->image[n],modulate);
3971 break;
3972 }
3973 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3974 }
3975 case 'N':
3976 case 'n':
3977 {
cristyb988fe72009-09-16 01:01:10 +00003978 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003979 {
3980 MagickBooleanType
3981 gray;
3982
3983 /*
3984 Negate image.
3985 */
3986 if (msl_info->image[n] == (Image *) NULL)
3987 {
cristyb988fe72009-09-16 01:01:10 +00003988 ThrowMSLException(OptionError,"NoImagesDefined",
3989 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003990 break;
3991 }
3992 gray=MagickFalse;
3993 if (attributes != (const xmlChar **) NULL)
3994 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3995 {
3996 keyword=(const char *) attributes[i++];
3997 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003998 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003999 CloneString(&value,attribute);
4000 switch (*keyword)
4001 {
4002 case 'C':
4003 case 'c':
4004 {
4005 if (LocaleCompare(keyword,"channel") == 0)
4006 {
4007 option=ParseChannelOption(value);
4008 if (option < 0)
4009 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4010 value);
4011 channel=(ChannelType) option;
4012 break;
4013 }
4014 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4015 keyword);
4016 break;
4017 }
4018 case 'G':
4019 case 'g':
4020 {
4021 if (LocaleCompare(keyword,"gray") == 0)
4022 {
4023 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4024 value);
4025 if (option < 0)
4026 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4027 value);
4028 gray=(MagickBooleanType) option;
4029 break;
4030 }
4031 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4032 keyword);
4033 break;
4034 }
4035 default:
4036 {
4037 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4038 keyword);
4039 break;
4040 }
4041 }
4042 }
4043 (void) NegateImageChannel(msl_info->image[n],channel,gray);
4044 break;
4045 }
cristyb988fe72009-09-16 01:01:10 +00004046 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004047 {
4048 /*
4049 Normalize image.
4050 */
4051 if (msl_info->image[n] == (Image *) NULL)
4052 {
cristyb988fe72009-09-16 01:01:10 +00004053 ThrowMSLException(OptionError,"NoImagesDefined",
4054 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004055 break;
4056 }
4057 if (attributes != (const xmlChar **) NULL)
4058 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4059 {
4060 keyword=(const char *) attributes[i++];
4061 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004062 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004063 CloneString(&value,attribute);
4064 switch (*keyword)
4065 {
4066 case 'C':
4067 case 'c':
4068 {
4069 if (LocaleCompare(keyword,"channel") == 0)
4070 {
4071 option=ParseChannelOption(value);
4072 if (option < 0)
4073 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4074 value);
4075 channel=(ChannelType) option;
4076 break;
4077 }
4078 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4079 keyword);
4080 break;
4081 }
4082 default:
4083 {
4084 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4085 keyword);
4086 break;
4087 }
4088 }
4089 }
4090 (void) NormalizeImageChannel(msl_info->image[n],channel);
4091 break;
4092 }
4093 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4094 }
4095 case 'O':
4096 case 'o':
4097 {
cristyb988fe72009-09-16 01:01:10 +00004098 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004099 {
4100 Image
4101 *paint_image;
4102
4103 /*
4104 Oil-paint image.
4105 */
4106 if (msl_info->image[n] == (Image *) NULL)
4107 {
cristyb988fe72009-09-16 01:01:10 +00004108 ThrowMSLException(OptionError,"NoImagesDefined",
4109 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004110 break;
4111 }
4112 if (attributes != (const xmlChar **) NULL)
4113 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4114 {
4115 keyword=(const char *) attributes[i++];
4116 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004117 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004118 CloneString(&value,attribute);
4119 switch (*keyword)
4120 {
4121 case 'G':
4122 case 'g':
4123 {
4124 if (LocaleCompare(keyword,"geometry") == 0)
4125 {
4126 flags=ParseGeometry(value,&geometry_info);
4127 if ((flags & SigmaValue) == 0)
4128 geometry_info.sigma=1.0;
4129 break;
4130 }
4131 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4132 keyword);
4133 break;
4134 }
4135 case 'R':
4136 case 'r':
4137 {
4138 if (LocaleCompare(keyword,"radius") == 0)
4139 {
cristyf2f27272009-12-17 14:48:46 +00004140 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004141 break;
4142 }
4143 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4144 keyword);
4145 break;
4146 }
4147 default:
4148 {
4149 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4150 keyword);
4151 break;
4152 }
4153 }
4154 }
4155 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4156 &msl_info->image[n]->exception);
4157 if (paint_image == (Image *) NULL)
4158 break;
4159 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4160 msl_info->image[n]=paint_image;
4161 break;
4162 }
cristyb988fe72009-09-16 01:01:10 +00004163 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004164 {
4165 MagickPixelPacket
4166 fill_color,
4167 target;
4168
4169 /*
4170 Opaque image.
4171 */
4172 if (msl_info->image[n] == (Image *) NULL)
4173 {
cristyb988fe72009-09-16 01:01:10 +00004174 ThrowMSLException(OptionError,"NoImagesDefined",
4175 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004176 break;
4177 }
4178 (void) QueryMagickColor("none",&target,&exception);
4179 (void) QueryMagickColor("none",&fill_color,&exception);
4180 if (attributes != (const xmlChar **) NULL)
4181 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4182 {
4183 keyword=(const char *) attributes[i++];
4184 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004185 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004186 CloneString(&value,attribute);
4187 switch (*keyword)
4188 {
4189 case 'C':
4190 case 'c':
4191 {
4192 if (LocaleCompare(keyword,"channel") == 0)
4193 {
4194 option=ParseChannelOption(value);
4195 if (option < 0)
4196 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4197 value);
4198 channel=(ChannelType) option;
4199 break;
4200 }
4201 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4202 keyword);
4203 break;
4204 }
4205 case 'F':
4206 case 'f':
4207 {
4208 if (LocaleCompare(keyword,"fill") == 0)
4209 {
4210 (void) QueryMagickColor(value,&fill_color,&exception);
4211 break;
4212 }
4213 if (LocaleCompare(keyword,"fuzz") == 0)
4214 {
cristyf2f27272009-12-17 14:48:46 +00004215 msl_info->image[n]->fuzz=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004216 break;
4217 }
4218 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4219 keyword);
4220 break;
4221 }
4222 default:
4223 {
4224 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4225 keyword);
4226 break;
4227 }
4228 }
4229 }
4230 (void) OpaquePaintImageChannel(msl_info->image[n],channel,
4231 &target,&fill_color,MagickFalse);
4232 break;
4233 }
4234 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4235 }
4236 case 'P':
4237 case 'p':
4238 {
cristyb988fe72009-09-16 01:01:10 +00004239 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004240 {
4241 if (attributes == (const xmlChar **) NULL)
4242 break;
4243 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4244 {
4245 keyword=(const char *) attributes[i++];
4246 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004247 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004248 CloneString(&value,attribute);
4249 switch (*keyword)
4250 {
4251 case 'O':
4252 case 'o':
4253 {
4254 if (LocaleCompare(keyword,"output") == 0)
4255 {
4256 (void) fprintf(stdout,"%s",value);
4257 break;
4258 }
4259 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4260 break;
4261 }
4262 default:
4263 {
4264 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4265 break;
4266 }
4267 }
4268 }
4269 break;
4270 }
cristy4fa36e42009-09-18 14:24:06 +00004271 if (LocaleCompare((const char *) tag, "profile") == 0)
4272 {
cristy4fa36e42009-09-18 14:24:06 +00004273 if (msl_info->image[n] == (Image *) NULL)
4274 {
4275 ThrowMSLException(OptionError,"NoImagesDefined",
4276 (const char *) tag);
4277 break;
4278 }
4279 if (attributes == (const xmlChar **) NULL)
4280 break;
4281 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4282 {
4283 const char
4284 *name;
4285
4286 const StringInfo
4287 *profile;
4288
4289 Image
4290 *profile_image;
4291
4292 ImageInfo
4293 *profile_info;
4294
4295 keyword=(const char *) attributes[i++];
4296 attribute=InterpretImageProperties(msl_info->image_info[n],
4297 msl_info->attributes[n],(const char *) attributes[i]);
4298 CloneString(&value,attribute);
4299 if (*keyword == '+')
4300 {
4301 /*
4302 Remove a profile from the image.
4303 */
4304 (void) ProfileImage(msl_info->image[n],keyword,
4305 (const unsigned char *) NULL,0,MagickTrue);
4306 continue;
4307 }
4308 /*
4309 Associate a profile with the image.
4310 */
4311 profile_info=CloneImageInfo(msl_info->image_info[n]);
4312 profile=GetImageProfile(msl_info->image[n],"iptc");
4313 if (profile != (StringInfo *) NULL)
4314 profile_info->profile=(void *) CloneStringInfo(profile);
4315 profile_image=GetImageCache(profile_info,keyword,&exception);
4316 profile_info=DestroyImageInfo(profile_info);
4317 if (profile_image == (Image *) NULL)
4318 {
4319 char
4320 name[MaxTextExtent],
4321 filename[MaxTextExtent];
4322
4323 register char
4324 *p;
4325
4326 StringInfo
4327 *profile;
4328
4329 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4330 (void) CopyMagickString(name,keyword,MaxTextExtent);
4331 for (p=filename; *p != '\0'; p++)
4332 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4333 (IsPathAccessible(keyword) == MagickFalse))
4334 {
4335 register char
4336 *q;
4337
4338 /*
4339 Look for profile name (e.g. name:profile).
4340 */
4341 (void) CopyMagickString(name,filename,(size_t)
4342 (p-filename+1));
4343 for (q=filename; *q != '\0'; q++)
4344 *q=(*++p);
4345 break;
4346 }
4347 profile=FileToStringInfo(filename,~0UL,&exception);
4348 if (profile != (StringInfo *) NULL)
4349 {
4350 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004351 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004352 GetStringInfoLength(profile),MagickFalse);
4353 profile=DestroyStringInfo(profile);
4354 }
4355 continue;
4356 }
4357 ResetImageProfileIterator(profile_image);
4358 name=GetNextImageProfile(profile_image);
4359 while (name != (const char *) NULL)
4360 {
4361 profile=GetImageProfile(profile_image,name);
4362 if (profile != (StringInfo *) NULL)
4363 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004364 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004365 GetStringInfoLength(profile),MagickFalse);
4366 name=GetNextImageProfile(profile_image);
4367 }
4368 profile_image=DestroyImage(profile_image);
4369 }
4370 break;
4371 }
cristy3ed852e2009-09-05 21:47:34 +00004372 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4373 }
4374 case 'Q':
4375 case 'q':
4376 {
cristyb988fe72009-09-16 01:01:10 +00004377 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004378 {
4379 QuantizeInfo
4380 quantize_info;
4381
4382 /*
4383 Quantize image.
4384 */
4385 if (msl_info->image[n] == (Image *) NULL)
4386 {
cristyb988fe72009-09-16 01:01:10 +00004387 ThrowMSLException(OptionError,"NoImagesDefined",
4388 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004389 break;
4390 }
4391 GetQuantizeInfo(&quantize_info);
4392 if (attributes != (const xmlChar **) NULL)
4393 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4394 {
4395 keyword=(const char *) attributes[i++];
4396 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004397 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004398 CloneString(&value,attribute);
4399 switch (*keyword)
4400 {
4401 case 'C':
4402 case 'c':
4403 {
4404 if (LocaleCompare(keyword,"colors") == 0)
4405 {
cristyf2f27272009-12-17 14:48:46 +00004406 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004407 break;
4408 }
4409 if (LocaleCompare(keyword,"colorspace") == 0)
4410 {
4411 option=ParseMagickOption(MagickColorspaceOptions,
4412 MagickFalse,value);
4413 if (option < 0)
4414 ThrowMSLException(OptionError,
4415 "UnrecognizedColorspaceType",value);
4416 quantize_info.colorspace=(ColorspaceType) option;
4417 break;
4418 }
4419 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4420 keyword);
4421 break;
4422 }
4423 case 'D':
4424 case 'd':
4425 {
4426 if (LocaleCompare(keyword,"dither") == 0)
4427 {
4428 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4429 value);
4430 if (option < 0)
4431 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4432 value);
4433 quantize_info.dither=(MagickBooleanType) option;
4434 break;
4435 }
4436 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4437 keyword);
4438 break;
4439 }
4440 case 'M':
4441 case 'm':
4442 {
4443 if (LocaleCompare(keyword,"measure") == 0)
4444 {
4445 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4446 value);
4447 if (option < 0)
4448 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4449 value);
4450 quantize_info.measure_error=(MagickBooleanType) option;
4451 break;
4452 }
4453 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4454 keyword);
4455 break;
4456 }
4457 case 'T':
4458 case 't':
4459 {
4460 if (LocaleCompare(keyword,"treedepth") == 0)
4461 {
cristyf2f27272009-12-17 14:48:46 +00004462 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004463 break;
4464 }
4465 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4466 keyword);
4467 break;
4468 }
4469 default:
4470 {
4471 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4472 keyword);
4473 break;
4474 }
4475 }
4476 }
4477 (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4478 break;
4479 }
cristyb988fe72009-09-16 01:01:10 +00004480 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004481 {
4482 char
4483 text[MaxTextExtent];
4484
4485 MagickBooleanType
4486 status;
4487
4488 TypeMetric
4489 metrics;
4490
4491 /*
4492 Query font metrics.
4493 */
4494 draw_info=CloneDrawInfo(msl_info->image_info[n],
4495 msl_info->draw_info[n]);
4496 angle=0.0;
4497 current=draw_info->affine;
4498 GetAffineMatrix(&affine);
4499 if (attributes != (const xmlChar **) NULL)
4500 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4501 {
4502 keyword=(const char *) attributes[i++];
4503 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004504 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004505 CloneString(&value,attribute);
4506 switch (*keyword)
4507 {
4508 case 'A':
4509 case 'a':
4510 {
4511 if (LocaleCompare(keyword,"affine") == 0)
4512 {
4513 char
4514 *p;
4515
4516 p=value;
4517 draw_info->affine.sx=strtod(p,&p);
4518 if (*p ==',')
4519 p++;
4520 draw_info->affine.rx=strtod(p,&p);
4521 if (*p ==',')
4522 p++;
4523 draw_info->affine.ry=strtod(p,&p);
4524 if (*p ==',')
4525 p++;
4526 draw_info->affine.sy=strtod(p,&p);
4527 if (*p ==',')
4528 p++;
4529 draw_info->affine.tx=strtod(p,&p);
4530 if (*p ==',')
4531 p++;
4532 draw_info->affine.ty=strtod(p,&p);
4533 break;
4534 }
4535 if (LocaleCompare(keyword,"align") == 0)
4536 {
4537 option=ParseMagickOption(MagickAlignOptions,MagickFalse,
4538 value);
4539 if (option < 0)
4540 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4541 value);
4542 draw_info->align=(AlignType) option;
4543 break;
4544 }
4545 if (LocaleCompare(keyword,"antialias") == 0)
4546 {
4547 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4548 value);
4549 if (option < 0)
4550 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4551 value);
4552 draw_info->stroke_antialias=(MagickBooleanType) option;
4553 draw_info->text_antialias=(MagickBooleanType) option;
4554 break;
4555 }
4556 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4557 keyword);
4558 break;
4559 }
4560 case 'D':
4561 case 'd':
4562 {
4563 if (LocaleCompare(keyword,"density") == 0)
4564 {
4565 CloneString(&draw_info->density,value);
4566 break;
4567 }
4568 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4569 keyword);
4570 break;
4571 }
4572 case 'E':
4573 case 'e':
4574 {
4575 if (LocaleCompare(keyword,"encoding") == 0)
4576 {
4577 CloneString(&draw_info->encoding,value);
4578 break;
4579 }
4580 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4581 keyword);
4582 break;
4583 }
4584 case 'F':
4585 case 'f':
4586 {
4587 if (LocaleCompare(keyword, "fill") == 0)
4588 {
4589 (void) QueryColorDatabase(value,&draw_info->fill,
4590 &exception);
4591 break;
4592 }
4593 if (LocaleCompare(keyword,"family") == 0)
4594 {
4595 CloneString(&draw_info->family,value);
4596 break;
4597 }
4598 if (LocaleCompare(keyword,"font") == 0)
4599 {
4600 CloneString(&draw_info->font,value);
4601 break;
4602 }
4603 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4604 keyword);
4605 break;
4606 }
4607 case 'G':
4608 case 'g':
4609 {
4610 if (LocaleCompare(keyword,"geometry") == 0)
4611 {
4612 flags=ParsePageGeometry(msl_info->image[n],value,
4613 &geometry,&exception);
4614 if ((flags & HeightValue) == 0)
4615 geometry.height=geometry.width;
4616 break;
4617 }
4618 if (LocaleCompare(keyword,"gravity") == 0)
4619 {
4620 option=ParseMagickOption(MagickGravityOptions,MagickFalse,
4621 value);
4622 if (option < 0)
4623 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4624 value);
4625 draw_info->gravity=(GravityType) option;
4626 break;
4627 }
4628 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4629 keyword);
4630 break;
4631 }
4632 case 'P':
4633 case 'p':
4634 {
4635 if (LocaleCompare(keyword,"pointsize") == 0)
4636 {
cristyf2f27272009-12-17 14:48:46 +00004637 draw_info->pointsize=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004638 break;
4639 }
4640 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4641 keyword);
4642 break;
4643 }
4644 case 'R':
4645 case 'r':
4646 {
4647 if (LocaleCompare(keyword,"rotate") == 0)
4648 {
cristyf2f27272009-12-17 14:48:46 +00004649 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004650 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4651 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4652 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4653 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4654 break;
4655 }
4656 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4657 keyword);
4658 break;
4659 }
4660 case 'S':
4661 case 's':
4662 {
4663 if (LocaleCompare(keyword,"scale") == 0)
4664 {
4665 flags=ParseGeometry(value,&geometry_info);
4666 if ((flags & SigmaValue) == 0)
4667 geometry_info.sigma=1.0;
4668 affine.sx=geometry_info.rho;
4669 affine.sy=geometry_info.sigma;
4670 break;
4671 }
4672 if (LocaleCompare(keyword,"skewX") == 0)
4673 {
cristyf2f27272009-12-17 14:48:46 +00004674 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004675 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4676 break;
4677 }
4678 if (LocaleCompare(keyword,"skewY") == 0)
4679 {
cristyf2f27272009-12-17 14:48:46 +00004680 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004681 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4682 break;
4683 }
4684 if (LocaleCompare(keyword,"stretch") == 0)
4685 {
4686 option=ParseMagickOption(MagickStretchOptions,MagickFalse,
4687 value);
4688 if (option < 0)
4689 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4690 value);
4691 draw_info->stretch=(StretchType) option;
4692 break;
4693 }
4694 if (LocaleCompare(keyword, "stroke") == 0)
4695 {
4696 (void) QueryColorDatabase(value,&draw_info->stroke,
4697 &exception);
4698 break;
4699 }
4700 if (LocaleCompare(keyword,"strokewidth") == 0)
4701 {
cristyf2f27272009-12-17 14:48:46 +00004702 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004703 break;
4704 }
4705 if (LocaleCompare(keyword,"style") == 0)
4706 {
4707 option=ParseMagickOption(MagickStyleOptions,MagickFalse,
4708 value);
4709 if (option < 0)
4710 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4711 value);
4712 draw_info->style=(StyleType) option;
4713 break;
4714 }
4715 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4716 keyword);
4717 break;
4718 }
4719 case 'T':
4720 case 't':
4721 {
4722 if (LocaleCompare(keyword,"text") == 0)
4723 {
4724 CloneString(&draw_info->text,value);
4725 break;
4726 }
4727 if (LocaleCompare(keyword,"translate") == 0)
4728 {
4729 flags=ParseGeometry(value,&geometry_info);
4730 if ((flags & SigmaValue) == 0)
4731 geometry_info.sigma=1.0;
4732 affine.tx=geometry_info.rho;
4733 affine.ty=geometry_info.sigma;
4734 break;
4735 }
4736 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4737 keyword);
4738 break;
4739 }
4740 case 'U':
4741 case 'u':
4742 {
4743 if (LocaleCompare(keyword, "undercolor") == 0)
4744 {
4745 (void) QueryColorDatabase(value,&draw_info->undercolor,
4746 &exception);
4747 break;
4748 }
4749 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4750 keyword);
4751 break;
4752 }
4753 case 'W':
4754 case 'w':
4755 {
4756 if (LocaleCompare(keyword,"weight") == 0)
4757 {
cristyf2f27272009-12-17 14:48:46 +00004758 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004759 break;
4760 }
4761 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4762 keyword);
4763 break;
4764 }
4765 case 'X':
4766 case 'x':
4767 {
4768 if (LocaleCompare(keyword,"x") == 0)
4769 {
cristyf2f27272009-12-17 14:48:46 +00004770 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004771 break;
4772 }
4773 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4774 keyword);
4775 break;
4776 }
4777 case 'Y':
4778 case 'y':
4779 {
4780 if (LocaleCompare(keyword,"y") == 0)
4781 {
cristyf2f27272009-12-17 14:48:46 +00004782 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004783 break;
4784 }
4785 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4786 keyword);
4787 break;
4788 }
4789 default:
4790 {
4791 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4792 keyword);
4793 break;
4794 }
4795 }
4796 }
cristye8c25f92010-06-03 00:53:06 +00004797 (void) FormatMagickString(text,MaxTextExtent,
4798 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4799 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004800 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004801 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4802 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4803 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4804 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4805 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4806 affine.tx;
4807 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4808 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00004809 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4810 if (status != MagickFalse)
4811 {
4812 Image
4813 *image;
4814
4815 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004816 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004817 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004818 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004819 "%g",metrics.pixels_per_em.y);
4820 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004821 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004822 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004823 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004824 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004825 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004826 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004827 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004828 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004829 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004830 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004831 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004832 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004833 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004834 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004835 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004836 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004837 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004838 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004839 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004840 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004841 metrics.origin.y);
4842 }
4843 draw_info=DestroyDrawInfo(draw_info);
4844 break;
4845 }
4846 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4847 }
4848 case 'R':
4849 case 'r':
4850 {
cristyb988fe72009-09-16 01:01:10 +00004851 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004852 {
4853 MagickBooleanType
4854 raise;
4855
4856 /*
4857 Raise image.
4858 */
4859 if (msl_info->image[n] == (Image *) NULL)
4860 {
cristyb988fe72009-09-16 01:01:10 +00004861 ThrowMSLException(OptionError,"NoImagesDefined",
4862 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004863 break;
4864 }
4865 raise=MagickFalse;
4866 SetGeometry(msl_info->image[n],&geometry);
4867 if (attributes != (const xmlChar **) NULL)
4868 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4869 {
4870 keyword=(const char *) attributes[i++];
4871 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004872 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004873 CloneString(&value,attribute);
4874 switch (*keyword)
4875 {
4876 case 'G':
4877 case 'g':
4878 {
4879 if (LocaleCompare(keyword,"geometry") == 0)
4880 {
4881 flags=ParsePageGeometry(msl_info->image[n],value,
4882 &geometry,&exception);
4883 if ((flags & HeightValue) == 0)
4884 geometry.height=geometry.width;
4885 break;
4886 }
4887 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4888 keyword);
4889 break;
4890 }
4891 case 'H':
4892 case 'h':
4893 {
4894 if (LocaleCompare(keyword,"height") == 0)
4895 {
cristyf2f27272009-12-17 14:48:46 +00004896 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004897 break;
4898 }
4899 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4900 keyword);
4901 break;
4902 }
4903 case 'R':
4904 case 'r':
4905 {
4906 if (LocaleCompare(keyword,"raise") == 0)
4907 {
4908 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4909 value);
4910 if (option < 0)
4911 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4912 value);
4913 raise=(MagickBooleanType) option;
4914 break;
4915 }
4916 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4917 keyword);
4918 break;
4919 }
4920 case 'W':
4921 case 'w':
4922 {
4923 if (LocaleCompare(keyword,"width") == 0)
4924 {
cristyf2f27272009-12-17 14:48:46 +00004925 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004926 break;
4927 }
4928 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4929 keyword);
4930 break;
4931 }
4932 default:
4933 {
4934 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4935 keyword);
4936 break;
4937 }
4938 }
4939 }
4940 (void) RaiseImage(msl_info->image[n],&geometry,raise);
4941 break;
4942 }
cristyb988fe72009-09-16 01:01:10 +00004943 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004944 {
4945 if (attributes == (const xmlChar **) NULL)
4946 break;
4947 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4948 {
4949 keyword=(const char *) attributes[i++];
4950 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004951 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00004952 switch (*keyword)
4953 {
4954 case 'F':
4955 case 'f':
4956 {
4957 if (LocaleCompare(keyword,"filename") == 0)
4958 {
4959 Image
4960 *image;
4961
4962 (void) CopyMagickString(msl_info->image_info[n]->filename,
4963 value,MaxTextExtent);
4964 image=ReadImage(msl_info->image_info[n],&exception);
4965 CatchException(&exception);
4966 if (image == (Image *) NULL)
4967 continue;
4968 AppendImageToList(&msl_info->image[n],image);
4969 break;
4970 }
cristy4582cbb2009-09-23 00:35:43 +00004971 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004972 break;
4973 }
4974 default:
4975 {
cristy4582cbb2009-09-23 00:35:43 +00004976 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004977 break;
4978 }
4979 }
4980 }
4981 break;
4982 }
cristyb988fe72009-09-16 01:01:10 +00004983 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004984 {
4985 Image
4986 *paint_image;
4987
4988 /*
4989 Reduce-noise image.
4990 */
4991 if (msl_info->image[n] == (Image *) NULL)
4992 {
cristyb988fe72009-09-16 01:01:10 +00004993 ThrowMSLException(OptionError,"NoImagesDefined",
4994 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004995 break;
4996 }
4997 if (attributes != (const xmlChar **) NULL)
4998 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4999 {
5000 keyword=(const char *) attributes[i++];
5001 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005002 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005003 CloneString(&value,attribute);
5004 switch (*keyword)
5005 {
5006 case 'G':
5007 case 'g':
5008 {
5009 if (LocaleCompare(keyword,"geometry") == 0)
5010 {
5011 flags=ParseGeometry(value,&geometry_info);
5012 if ((flags & SigmaValue) == 0)
5013 geometry_info.sigma=1.0;
5014 break;
5015 }
5016 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5017 keyword);
5018 break;
5019 }
5020 case 'R':
5021 case 'r':
5022 {
5023 if (LocaleCompare(keyword,"radius") == 0)
5024 {
cristyf2f27272009-12-17 14:48:46 +00005025 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005026 break;
5027 }
5028 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5029 keyword);
5030 break;
5031 }
5032 default:
5033 {
5034 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5035 keyword);
5036 break;
5037 }
5038 }
5039 }
5040 paint_image=ReduceNoiseImage(msl_info->image[n],geometry_info.rho,
5041 &msl_info->image[n]->exception);
5042 if (paint_image == (Image *) NULL)
5043 break;
5044 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5045 msl_info->image[n]=paint_image;
5046 break;
5047 }
cristyb988fe72009-09-16 01:01:10 +00005048 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005049 {
5050 /* init the values */
5051 width=msl_info->image[n]->page.width;
5052 height=msl_info->image[n]->page.height;
5053 x=msl_info->image[n]->page.x;
5054 y=msl_info->image[n]->page.y;
5055
5056 if (msl_info->image[n] == (Image *) NULL)
5057 {
cristyb988fe72009-09-16 01:01:10 +00005058 ThrowMSLException(OptionError,"NoImagesDefined",
5059 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005060 break;
5061 }
5062 if (attributes == (const xmlChar **) NULL)
5063 break;
5064 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5065 {
5066 keyword=(const char *) attributes[i++];
5067 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005068 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005069 switch (*keyword)
5070 {
5071 case 'G':
5072 case 'g':
5073 {
5074 if (LocaleCompare(keyword,"geometry") == 0)
5075 {
5076 int
5077 flags;
5078
5079 RectangleInfo
5080 geometry;
5081
5082 flags=ParseAbsoluteGeometry(value,&geometry);
5083 if ((flags & WidthValue) != 0)
5084 {
5085 if ((flags & HeightValue) == 0)
5086 geometry.height=geometry.width;
5087 width=geometry.width;
5088 height=geometry.height;
5089 }
5090 if ((flags & AspectValue) != 0)
5091 {
5092 if ((flags & XValue) != 0)
5093 x+=geometry.x;
5094 if ((flags & YValue) != 0)
5095 y+=geometry.y;
5096 }
5097 else
5098 {
5099 if ((flags & XValue) != 0)
5100 {
5101 x=geometry.x;
5102 if ((width == 0) && (geometry.x > 0))
5103 width=msl_info->image[n]->columns+geometry.x;
5104 }
5105 if ((flags & YValue) != 0)
5106 {
5107 y=geometry.y;
5108 if ((height == 0) && (geometry.y > 0))
5109 height=msl_info->image[n]->rows+geometry.y;
5110 }
5111 }
5112 break;
5113 }
5114 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5115 break;
5116 }
5117 case 'H':
5118 case 'h':
5119 {
5120 if (LocaleCompare(keyword,"height") == 0)
5121 {
cristyf2f27272009-12-17 14:48:46 +00005122 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005123 break;
5124 }
5125 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5126 break;
5127 }
5128 case 'W':
5129 case 'w':
5130 {
5131 if (LocaleCompare(keyword,"width") == 0)
5132 {
cristyf2f27272009-12-17 14:48:46 +00005133 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005134 break;
5135 }
5136 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5137 break;
5138 }
5139 case 'X':
5140 case 'x':
5141 {
5142 if (LocaleCompare(keyword,"x") == 0)
5143 {
cristyf2f27272009-12-17 14:48:46 +00005144 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005145 break;
5146 }
5147 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5148 break;
5149 }
5150 case 'Y':
5151 case 'y':
5152 {
5153 if (LocaleCompare(keyword,"y") == 0)
5154 {
cristyf2f27272009-12-17 14:48:46 +00005155 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005156 break;
5157 }
5158 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5159 break;
5160 }
5161 default:
5162 {
5163 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5164 break;
5165 }
5166 }
5167 }
5168
cristyb988fe72009-09-16 01:01:10 +00005169 msl_info->image[n]->page.width=width;
5170 msl_info->image[n]->page.height=height;
5171 msl_info->image[n]->page.x=x;
5172 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005173 break;
5174 }
cristyb988fe72009-09-16 01:01:10 +00005175 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005176 {
5177 double
5178 x_resolution,
5179 y_resolution;
5180
5181 if (msl_info->image[n] == (Image *) NULL)
5182 {
cristyb988fe72009-09-16 01:01:10 +00005183 ThrowMSLException(OptionError,"NoImagesDefined",
5184 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005185 break;
5186 }
5187 if (attributes == (const xmlChar **) NULL)
5188 break;
5189 x_resolution=DefaultResolution;
5190 y_resolution=DefaultResolution;
5191 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5192 {
5193 keyword=(const char *) attributes[i++];
5194 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005195 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005196 switch (*keyword)
5197 {
5198 case 'b':
5199 {
5200 if (LocaleCompare(keyword,"blur") == 0)
5201 {
cristyf2f27272009-12-17 14:48:46 +00005202 msl_info->image[n]->blur=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005203 break;
5204 }
5205 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5206 break;
5207 }
5208 case 'G':
5209 case 'g':
5210 {
5211 if (LocaleCompare(keyword,"geometry") == 0)
5212 {
cristybb503372010-05-27 20:51:26 +00005213 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005214 flags;
5215
5216 flags=ParseGeometry(value,&geometry_info);
5217 if ((flags & SigmaValue) == 0)
5218 geometry_info.sigma*=geometry_info.rho;
5219 x_resolution=geometry_info.rho;
5220 y_resolution=geometry_info.sigma;
5221 break;
5222 }
5223 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5224 break;
5225 }
5226 case 'X':
5227 case 'x':
5228 {
5229 if (LocaleCompare(keyword,"x-resolution") == 0)
5230 {
cristyf2f27272009-12-17 14:48:46 +00005231 x_resolution=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005232 break;
5233 }
5234 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5235 break;
5236 }
5237 case 'Y':
5238 case 'y':
5239 {
5240 if (LocaleCompare(keyword,"y-resolution") == 0)
5241 {
cristyf2f27272009-12-17 14:48:46 +00005242 y_resolution=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005243 break;
5244 }
5245 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5246 break;
5247 }
5248 default:
5249 {
5250 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5251 break;
5252 }
5253 }
5254 }
5255 /*
5256 Resample image.
5257 */
5258 {
5259 double
5260 factor;
5261
5262 Image
5263 *resample_image;
5264
5265 factor=1.0;
5266 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5267 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005268 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy3ed852e2009-09-05 21:47:34 +00005269 (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5270 msl_info->image[n]->x_resolution))+0.5);
cristybb503372010-05-27 20:51:26 +00005271 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy3ed852e2009-09-05 21:47:34 +00005272 (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5273 msl_info->image[n]->y_resolution))+0.5);
5274 resample_image=ResizeImage(msl_info->image[n],width,height,
5275 msl_info->image[n]->filter,msl_info->image[n]->blur,
5276 &msl_info->image[n]->exception);
5277 if (resample_image == (Image *) NULL)
5278 break;
5279 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5280 msl_info->image[n]=resample_image;
5281 }
5282 break;
5283 }
cristyb988fe72009-09-16 01:01:10 +00005284 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005285 {
5286 double
5287 blur;
5288
5289 FilterTypes
5290 filter;
5291
5292 Image
5293 *resize_image;
5294
5295 /*
5296 Resize image.
5297 */
5298 if (msl_info->image[n] == (Image *) NULL)
5299 {
cristyb988fe72009-09-16 01:01:10 +00005300 ThrowMSLException(OptionError,"NoImagesDefined",
5301 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005302 break;
5303 }
5304 filter=UndefinedFilter;
5305 blur=1.0;
5306 if (attributes != (const xmlChar **) NULL)
5307 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5308 {
5309 keyword=(const char *) attributes[i++];
5310 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005311 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005312 CloneString(&value,attribute);
5313 switch (*keyword)
5314 {
5315 case 'F':
5316 case 'f':
5317 {
5318 if (LocaleCompare(keyword,"filter") == 0)
5319 {
5320 option=ParseMagickOption(MagickFilterOptions,MagickFalse,
5321 value);
5322 if (option < 0)
5323 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5324 value);
5325 filter=(FilterTypes) option;
5326 break;
5327 }
5328 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5329 keyword);
5330 break;
5331 }
5332 case 'G':
5333 case 'g':
5334 {
5335 if (LocaleCompare(keyword,"geometry") == 0)
5336 {
5337 flags=ParseRegionGeometry(msl_info->image[n],value,
5338 &geometry,&exception);
5339 break;
5340 }
5341 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5342 keyword);
5343 break;
5344 }
5345 case 'H':
5346 case 'h':
5347 {
5348 if (LocaleCompare(keyword,"height") == 0)
5349 {
cristye27293e2009-12-18 02:53:20 +00005350 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005351 break;
5352 }
5353 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5354 keyword);
5355 break;
5356 }
5357 case 'S':
5358 case 's':
5359 {
5360 if (LocaleCompare(keyword,"support") == 0)
5361 {
cristyf2f27272009-12-17 14:48:46 +00005362 blur=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005363 break;
5364 }
5365 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5366 keyword);
5367 break;
5368 }
5369 case 'W':
5370 case 'w':
5371 {
5372 if (LocaleCompare(keyword,"width") == 0)
5373 {
cristyf2f27272009-12-17 14:48:46 +00005374 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005375 break;
5376 }
5377 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5378 keyword);
5379 break;
5380 }
5381 default:
5382 {
5383 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5384 keyword);
5385 break;
5386 }
5387 }
5388 }
5389 resize_image=ResizeImage(msl_info->image[n],geometry.width,
5390 geometry.height,filter,blur,&msl_info->image[n]->exception);
5391 if (resize_image == (Image *) NULL)
5392 break;
5393 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5394 msl_info->image[n]=resize_image;
5395 break;
5396 }
cristyb988fe72009-09-16 01:01:10 +00005397 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005398 {
5399 Image
5400 *roll_image;
5401
5402 /*
5403 Roll image.
5404 */
5405 if (msl_info->image[n] == (Image *) NULL)
5406 {
cristyb988fe72009-09-16 01:01:10 +00005407 ThrowMSLException(OptionError,"NoImagesDefined",
5408 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005409 break;
5410 }
5411 SetGeometry(msl_info->image[n],&geometry);
5412 if (attributes != (const xmlChar **) NULL)
5413 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5414 {
5415 keyword=(const char *) attributes[i++];
5416 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005417 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005418 CloneString(&value,attribute);
5419 switch (*keyword)
5420 {
5421 case 'G':
5422 case 'g':
5423 {
5424 if (LocaleCompare(keyword,"geometry") == 0)
5425 {
5426 flags=ParsePageGeometry(msl_info->image[n],value,
5427 &geometry,&exception);
5428 if ((flags & HeightValue) == 0)
5429 geometry.height=geometry.width;
5430 break;
5431 }
5432 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5433 keyword);
5434 break;
5435 }
5436 case 'X':
5437 case 'x':
5438 {
5439 if (LocaleCompare(keyword,"x") == 0)
5440 {
cristyf2f27272009-12-17 14:48:46 +00005441 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005442 break;
5443 }
5444 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5445 keyword);
5446 break;
5447 }
5448 case 'Y':
5449 case 'y':
5450 {
5451 if (LocaleCompare(keyword,"y") == 0)
5452 {
cristyf2f27272009-12-17 14:48:46 +00005453 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005454 break;
5455 }
5456 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5457 keyword);
5458 break;
5459 }
5460 default:
5461 {
5462 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5463 keyword);
5464 break;
5465 }
5466 }
5467 }
5468 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5469 &msl_info->image[n]->exception);
5470 if (roll_image == (Image *) NULL)
5471 break;
5472 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5473 msl_info->image[n]=roll_image;
5474 break;
5475 }
cristyb988fe72009-09-16 01:01:10 +00005476 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005477 {
5478 /* init the values */
5479 width=msl_info->image[n]->columns;
5480 height=msl_info->image[n]->rows;
5481 x = y = 0;
5482
5483 if (msl_info->image[n] == (Image *) NULL)
5484 {
cristyb988fe72009-09-16 01:01:10 +00005485 ThrowMSLException(OptionError,"NoImagesDefined",
5486 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005487 break;
5488 }
5489 if (attributes == (const xmlChar **) NULL)
5490 break;
5491 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5492 {
5493 keyword=(const char *) attributes[i++];
5494 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005495 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005496 switch (*keyword)
5497 {
5498 case 'G':
5499 case 'g':
5500 {
5501 if (LocaleCompare(keyword,"geometry") == 0)
5502 {
5503 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5504 break;
5505 }
5506 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5507 break;
5508 }
5509 case 'X':
5510 case 'x':
5511 {
5512 if (LocaleCompare(keyword,"x") == 0)
5513 {
cristyf2f27272009-12-17 14:48:46 +00005514 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005515 break;
5516 }
5517 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5518 break;
5519 }
5520 case 'Y':
5521 case 'y':
5522 {
5523 if (LocaleCompare(keyword,"y") == 0)
5524 {
cristyf2f27272009-12-17 14:48:46 +00005525 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005526 break;
5527 }
5528 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5529 break;
5530 }
5531 default:
5532 {
5533 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5534 break;
5535 }
5536 }
5537 }
5538
5539 /*
5540 process image.
5541 */
5542 {
5543 Image
5544 *newImage;
5545
5546 newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5547 if (newImage == (Image *) NULL)
5548 break;
5549 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5550 msl_info->image[n]=newImage;
5551 }
5552
5553 break;
5554 }
cristyb988fe72009-09-16 01:01:10 +00005555 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005556 {
5557 Image
5558 *rotate_image;
5559
5560 /*
5561 Rotate image.
5562 */
5563 if (msl_info->image[n] == (Image *) NULL)
5564 {
cristyb988fe72009-09-16 01:01:10 +00005565 ThrowMSLException(OptionError,"NoImagesDefined",
5566 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005567 break;
5568 }
5569 if (attributes != (const xmlChar **) NULL)
5570 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5571 {
5572 keyword=(const char *) attributes[i++];
5573 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005574 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005575 CloneString(&value,attribute);
5576 switch (*keyword)
5577 {
5578 case 'D':
5579 case 'd':
5580 {
5581 if (LocaleCompare(keyword,"degrees") == 0)
5582 {
cristyf2f27272009-12-17 14:48:46 +00005583 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005584 break;
5585 }
5586 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5587 keyword);
5588 break;
5589 }
5590 case 'G':
5591 case 'g':
5592 {
5593 if (LocaleCompare(keyword,"geometry") == 0)
5594 {
5595 flags=ParseGeometry(value,&geometry_info);
5596 if ((flags & SigmaValue) == 0)
5597 geometry_info.sigma=1.0;
5598 break;
5599 }
5600 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5601 keyword);
5602 break;
5603 }
5604 default:
5605 {
5606 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5607 keyword);
5608 break;
5609 }
5610 }
5611 }
5612 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5613 &msl_info->image[n]->exception);
5614 if (rotate_image == (Image *) NULL)
5615 break;
5616 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5617 msl_info->image[n]=rotate_image;
5618 break;
5619 }
cristyb988fe72009-09-16 01:01:10 +00005620 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005621 {
5622 /* init the values */
5623 double degrees = 0;
5624
5625 if (msl_info->image[n] == (Image *) NULL)
5626 {
cristyb988fe72009-09-16 01:01:10 +00005627 ThrowMSLException(OptionError,"NoImagesDefined",
5628 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005629 break;
5630 }
5631 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005632 break;
cristy3ed852e2009-09-05 21:47:34 +00005633 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5634 {
5635 keyword=(const char *) attributes[i++];
5636 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005637 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005638 switch (*keyword)
5639 {
5640 case 'D':
5641 case 'd':
5642 {
5643 if (LocaleCompare(keyword,"degrees") == 0)
5644 {
cristyf2f27272009-12-17 14:48:46 +00005645 degrees = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00005646 break;
5647 }
5648 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5649 break;
5650 }
5651 default:
5652 {
5653 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5654 break;
5655 }
5656 }
5657 }
5658
5659 /*
5660 process image.
5661 */
5662 {
5663 Image
5664 *newImage;
5665
5666 newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5667 if (newImage == (Image *) NULL)
5668 break;
5669 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5670 msl_info->image[n]=newImage;
5671 }
5672
5673 break;
5674 }
5675 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5676 }
5677 case 'S':
5678 case 's':
5679 {
cristyb988fe72009-09-16 01:01:10 +00005680 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005681 {
5682 Image
5683 *sample_image;
5684
5685 /*
5686 Sample image.
5687 */
5688 if (msl_info->image[n] == (Image *) NULL)
5689 {
cristyb988fe72009-09-16 01:01:10 +00005690 ThrowMSLException(OptionError,"NoImagesDefined",
5691 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005692 break;
5693 }
5694 if (attributes != (const xmlChar **) NULL)
5695 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5696 {
5697 keyword=(const char *) attributes[i++];
5698 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005699 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005700 CloneString(&value,attribute);
5701 switch (*keyword)
5702 {
5703 case 'G':
5704 case 'g':
5705 {
5706 if (LocaleCompare(keyword,"geometry") == 0)
5707 {
5708 flags=ParseRegionGeometry(msl_info->image[n],value,
5709 &geometry,&exception);
5710 break;
5711 }
5712 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5713 keyword);
5714 break;
5715 }
5716 case 'H':
5717 case 'h':
5718 {
5719 if (LocaleCompare(keyword,"height") == 0)
5720 {
cristye27293e2009-12-18 02:53:20 +00005721 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005722 break;
5723 }
5724 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5725 keyword);
5726 break;
5727 }
5728 case 'W':
5729 case 'w':
5730 {
5731 if (LocaleCompare(keyword,"width") == 0)
5732 {
cristyf2f27272009-12-17 14:48:46 +00005733 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005734 break;
5735 }
5736 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5737 keyword);
5738 break;
5739 }
5740 default:
5741 {
5742 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5743 keyword);
5744 break;
5745 }
5746 }
5747 }
5748 sample_image=SampleImage(msl_info->image[n],geometry.width,
5749 geometry.height,&msl_info->image[n]->exception);
5750 if (sample_image == (Image *) NULL)
5751 break;
5752 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5753 msl_info->image[n]=sample_image;
5754 break;
5755 }
cristyb988fe72009-09-16 01:01:10 +00005756 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005757 {
5758 Image
5759 *scale_image;
5760
5761 /*
5762 Scale image.
5763 */
5764 if (msl_info->image[n] == (Image *) NULL)
5765 {
cristyb988fe72009-09-16 01:01:10 +00005766 ThrowMSLException(OptionError,"NoImagesDefined",
5767 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005768 break;
5769 }
5770 if (attributes != (const xmlChar **) NULL)
5771 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5772 {
5773 keyword=(const char *) attributes[i++];
5774 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005775 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005776 CloneString(&value,attribute);
5777 switch (*keyword)
5778 {
5779 case 'G':
5780 case 'g':
5781 {
5782 if (LocaleCompare(keyword,"geometry") == 0)
5783 {
5784 flags=ParseRegionGeometry(msl_info->image[n],value,
5785 &geometry,&exception);
5786 break;
5787 }
5788 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5789 keyword);
5790 break;
5791 }
5792 case 'H':
5793 case 'h':
5794 {
5795 if (LocaleCompare(keyword,"height") == 0)
5796 {
cristye27293e2009-12-18 02:53:20 +00005797 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005798 break;
5799 }
5800 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5801 keyword);
5802 break;
5803 }
5804 case 'W':
5805 case 'w':
5806 {
5807 if (LocaleCompare(keyword,"width") == 0)
5808 {
cristyf2f27272009-12-17 14:48:46 +00005809 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005810 break;
5811 }
5812 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5813 keyword);
5814 break;
5815 }
5816 default:
5817 {
5818 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5819 keyword);
5820 break;
5821 }
5822 }
5823 }
5824 scale_image=ScaleImage(msl_info->image[n],geometry.width,
5825 geometry.height,&msl_info->image[n]->exception);
5826 if (scale_image == (Image *) NULL)
5827 break;
5828 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5829 msl_info->image[n]=scale_image;
5830 break;
5831 }
cristyb988fe72009-09-16 01:01:10 +00005832 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005833 {
5834 ColorspaceType
5835 colorspace;
5836
5837 MagickBooleanType
5838 verbose;
cristyb988fe72009-09-16 01:01:10 +00005839
cristy3ed852e2009-09-05 21:47:34 +00005840 /*
5841 Segment image.
5842 */
5843 if (msl_info->image[n] == (Image *) NULL)
5844 {
cristyb988fe72009-09-16 01:01:10 +00005845 ThrowMSLException(OptionError,"NoImagesDefined",
5846 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005847 break;
5848 }
5849 geometry_info.rho=1.0;
5850 geometry_info.sigma=1.5;
5851 colorspace=RGBColorspace;
5852 verbose=MagickFalse;
5853 if (attributes != (const xmlChar **) NULL)
5854 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5855 {
5856 keyword=(const char *) attributes[i++];
5857 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005858 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005859 CloneString(&value,attribute);
5860 switch (*keyword)
5861 {
5862 case 'C':
5863 case 'c':
5864 {
5865 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5866 {
cristyf2f27272009-12-17 14:48:46 +00005867 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005868 break;
5869 }
5870 if (LocaleCompare(keyword,"colorspace") == 0)
5871 {
5872 option=ParseMagickOption(MagickColorspaceOptions,
5873 MagickFalse,value);
5874 if (option < 0)
5875 ThrowMSLException(OptionError,
5876 "UnrecognizedColorspaceType",value);
5877 colorspace=(ColorspaceType) option;
5878 break;
5879 }
5880 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5881 keyword);
5882 break;
5883 }
5884 case 'G':
5885 case 'g':
5886 {
5887 if (LocaleCompare(keyword,"geometry") == 0)
5888 {
5889 flags=ParseGeometry(value,&geometry_info);
5890 if ((flags & SigmaValue) == 0)
5891 geometry_info.sigma=1.5;
5892 break;
5893 }
5894 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5895 keyword);
5896 break;
5897 }
5898 case 'S':
5899 case 's':
5900 {
5901 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5902 {
cristyf2f27272009-12-17 14:48:46 +00005903 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005904 break;
5905 }
5906 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5907 keyword);
5908 break;
5909 }
5910 default:
5911 {
5912 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5913 keyword);
5914 break;
5915 }
5916 }
5917 }
5918 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5919 geometry_info.rho,geometry_info.sigma);
5920 break;
5921 }
cristyb988fe72009-09-16 01:01:10 +00005922 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005923 {
5924 if (msl_info->image[n] == (Image *) NULL)
5925 {
cristyb988fe72009-09-16 01:01:10 +00005926 ThrowMSLException(OptionError,"NoImagesDefined",
5927 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005928 break;
5929 }
5930
5931 if (attributes == (const xmlChar **) NULL)
5932 break;
5933 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5934 {
5935 keyword=(const char *) attributes[i++];
5936 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005937 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005938 switch (*keyword)
5939 {
cristy3ed852e2009-09-05 21:47:34 +00005940 case 'C':
5941 case 'c':
5942 {
5943 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005944 {
cristy2c8b6312009-09-16 02:37:23 +00005945 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005946 {
cristy2c8b6312009-09-16 02:37:23 +00005947 const char
5948 *property;
5949
5950 property=GetImageProperty(msl_info->attributes[j],"id");
5951 if (LocaleCompare(property,value) == 0)
5952 {
5953 SetImageMask(msl_info->image[n],msl_info->image[j]);
5954 break;
5955 }
cristy3ed852e2009-09-05 21:47:34 +00005956 }
cristy2c8b6312009-09-16 02:37:23 +00005957 break;
cristy3ed852e2009-09-05 21:47:34 +00005958 }
cristy3ed852e2009-09-05 21:47:34 +00005959 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005960 {
cristy2c8b6312009-09-16 02:37:23 +00005961 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005962 {
cristy2c8b6312009-09-16 02:37:23 +00005963 const char
5964 *property;
5965
5966 property=GetImageProperty(msl_info->attributes[j],"id");
5967 if (LocaleCompare(property,value) == 0)
5968 {
5969 SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5970 break;
5971 }
cristy3ed852e2009-09-05 21:47:34 +00005972 }
cristy2c8b6312009-09-16 02:37:23 +00005973 break;
cristy3ed852e2009-09-05 21:47:34 +00005974 }
cristy2c8b6312009-09-16 02:37:23 +00005975 if (LocaleCompare(keyword,"colorspace") == 0)
5976 {
cristybb503372010-05-27 20:51:26 +00005977 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00005978 colorspace;
5979
5980 colorspace=(ColorspaceType) ParseMagickOption(
cristy7e9e6fa2010-11-21 17:06:24 +00005981 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00005982 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00005983 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00005984 value);
5985 (void) TransformImageColorspace(msl_info->image[n],
5986 (ColorspaceType) colorspace);
5987 break;
5988 }
5989 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005990 break;
5991 }
5992 case 'D':
5993 case 'd':
5994 {
cristy2c8b6312009-09-16 02:37:23 +00005995 if (LocaleCompare(keyword,"density") == 0)
5996 {
5997 flags=ParseGeometry(value,&geometry_info);
5998 msl_info->image[n]->x_resolution=geometry_info.rho;
5999 msl_info->image[n]->y_resolution=geometry_info.sigma;
6000 if ((flags & SigmaValue) == 0)
6001 msl_info->image[n]->y_resolution=
6002 msl_info->image[n]->x_resolution;
6003 break;
6004 }
6005 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006006 break;
6007 }
6008 case 'O':
6009 case 'o':
6010 {
6011 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006012 {
cristybb503372010-05-27 20:51:26 +00006013 ssize_t opac = OpaqueOpacity,
6014 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006015
cristy2c8b6312009-09-16 02:37:23 +00006016 if (value[len-1] == '%') {
6017 char tmp[100];
6018 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006019 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006020 opac = (int)(QuantumRange * ((float)opac/100));
6021 } else
cristyf2f27272009-12-17 14:48:46 +00006022 opac = StringToLong( value );
cristy2c8b6312009-09-16 02:37:23 +00006023 (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6024 break;
cristy3ed852e2009-09-05 21:47:34 +00006025 }
cristy2c8b6312009-09-16 02:37:23 +00006026 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006027 break;
6028 }
6029 case 'P':
6030 case 'p':
6031 {
6032 if (LocaleCompare(keyword, "page") == 0)
6033 {
6034 char
6035 page[MaxTextExtent];
6036
6037 const char
6038 *image_option;
6039
6040 MagickStatusType
6041 flags;
6042
6043 RectangleInfo
6044 geometry;
6045
6046 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6047 image_option=GetImageOption(msl_info->image_info[n],"page");
6048 if (image_option != (const char *) NULL)
6049 flags=ParseAbsoluteGeometry(image_option,&geometry);
6050 flags=ParseAbsoluteGeometry(value,&geometry);
cristye8c25f92010-06-03 00:53:06 +00006051 (void) FormatMagickString(page,MaxTextExtent,"%.20gx%.20g",
6052 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006053 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristyf2faecf2010-05-28 19:19:36 +00006054 (void) FormatMagickString(page,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00006055 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6056 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006057 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006058 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6059 msl_info->image_info[n]->page=GetPageGeometry(page);
6060 break;
6061 }
cristy2c8b6312009-09-16 02:37:23 +00006062 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006063 break;
6064 }
6065 default:
6066 {
cristy2c8b6312009-09-16 02:37:23 +00006067 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006068 break;
6069 }
6070 }
6071 }
6072 break;
6073 }
cristyb988fe72009-09-16 01:01:10 +00006074 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006075 {
6076 Image
6077 *shade_image;
6078
6079 MagickBooleanType
6080 gray;
6081
6082 /*
6083 Shade image.
6084 */
6085 if (msl_info->image[n] == (Image *) NULL)
6086 {
cristyb988fe72009-09-16 01:01:10 +00006087 ThrowMSLException(OptionError,"NoImagesDefined",
6088 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006089 break;
6090 }
6091 gray=MagickFalse;
6092 if (attributes != (const xmlChar **) NULL)
6093 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6094 {
6095 keyword=(const char *) attributes[i++];
6096 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006097 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006098 CloneString(&value,attribute);
6099 switch (*keyword)
6100 {
6101 case 'A':
6102 case 'a':
6103 {
6104 if (LocaleCompare(keyword,"azimuth") == 0)
6105 {
cristyf2f27272009-12-17 14:48:46 +00006106 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006107 break;
6108 }
6109 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6110 keyword);
6111 break;
6112 }
6113 case 'E':
6114 case 'e':
6115 {
6116 if (LocaleCompare(keyword,"elevation") == 0)
6117 {
cristyf2f27272009-12-17 14:48:46 +00006118 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006119 break;
6120 }
6121 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6122 keyword);
6123 break;
6124 }
6125 case 'G':
6126 case 'g':
6127 {
6128 if (LocaleCompare(keyword,"geometry") == 0)
6129 {
6130 flags=ParseGeometry(value,&geometry_info);
6131 if ((flags & SigmaValue) == 0)
6132 geometry_info.sigma=1.0;
6133 break;
6134 }
6135 if (LocaleCompare(keyword,"gray") == 0)
6136 {
6137 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
6138 value);
6139 if (option < 0)
6140 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6141 value);
6142 gray=(MagickBooleanType) option;
6143 break;
6144 }
6145 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6146 keyword);
6147 break;
6148 }
6149 default:
6150 {
6151 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6152 keyword);
6153 break;
6154 }
6155 }
6156 }
6157 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6158 geometry_info.sigma,&msl_info->image[n]->exception);
6159 if (shade_image == (Image *) NULL)
6160 break;
6161 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6162 msl_info->image[n]=shade_image;
6163 break;
6164 }
cristyb988fe72009-09-16 01:01:10 +00006165 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006166 {
6167 Image
6168 *shadow_image;
6169
6170 /*
6171 Shear image.
6172 */
6173 if (msl_info->image[n] == (Image *) NULL)
6174 {
cristyb988fe72009-09-16 01:01:10 +00006175 ThrowMSLException(OptionError,"NoImagesDefined",
6176 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006177 break;
6178 }
6179 if (attributes != (const xmlChar **) NULL)
6180 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6181 {
6182 keyword=(const char *) attributes[i++];
6183 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006184 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006185 CloneString(&value,attribute);
6186 switch (*keyword)
6187 {
6188 case 'G':
6189 case 'g':
6190 {
6191 if (LocaleCompare(keyword,"geometry") == 0)
6192 {
6193 flags=ParseGeometry(value,&geometry_info);
6194 if ((flags & SigmaValue) == 0)
6195 geometry_info.sigma=1.0;
6196 break;
6197 }
6198 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6199 keyword);
6200 break;
6201 }
6202 case 'O':
6203 case 'o':
6204 {
6205 if (LocaleCompare(keyword,"opacity") == 0)
6206 {
cristyf2f27272009-12-17 14:48:46 +00006207 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006208 break;
6209 }
6210 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6211 keyword);
6212 break;
6213 }
6214 case 'S':
6215 case 's':
6216 {
6217 if (LocaleCompare(keyword,"sigma") == 0)
6218 {
cristyf2f27272009-12-17 14:48:46 +00006219 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006220 break;
6221 }
6222 break;
6223 }
6224 case 'X':
6225 case 'x':
6226 {
6227 if (LocaleCompare(keyword,"x") == 0)
6228 {
cristyf2f27272009-12-17 14:48:46 +00006229 geometry_info.xi=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006230 break;
6231 }
6232 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6233 keyword);
6234 break;
6235 }
6236 case 'Y':
6237 case 'y':
6238 {
6239 if (LocaleCompare(keyword,"y") == 0)
6240 {
cristyf2f27272009-12-17 14:48:46 +00006241 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006242 break;
6243 }
6244 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6245 keyword);
6246 break;
6247 }
6248 default:
6249 {
6250 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6251 keyword);
6252 break;
6253 }
6254 }
6255 }
6256 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristybb503372010-05-27 20:51:26 +00006257 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
cristy0534a6b2010-03-18 01:19:38 +00006258 ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006259 if (shadow_image == (Image *) NULL)
6260 break;
6261 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6262 msl_info->image[n]=shadow_image;
6263 break;
6264 }
cristyb988fe72009-09-16 01:01:10 +00006265 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006266 {
6267 double radius = 0.0,
6268 sigma = 1.0;
6269
6270 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006271 {
6272 ThrowMSLException(OptionError,"NoImagesDefined",
6273 (const char *) tag);
6274 break;
6275 }
cristy3ed852e2009-09-05 21:47:34 +00006276 /*
6277 NOTE: sharpen can have no attributes, since we use all the defaults!
6278 */
6279 if (attributes != (const xmlChar **) NULL)
6280 {
6281 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6282 {
6283 keyword=(const char *) attributes[i++];
6284 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006285 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006286 switch (*keyword)
6287 {
6288 case 'R':
6289 case 'r':
6290 {
6291 if (LocaleCompare(keyword, "radius") == 0)
6292 {
cristyf2f27272009-12-17 14:48:46 +00006293 radius = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00006294 break;
6295 }
6296 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6297 break;
6298 }
6299 case 'S':
6300 case 's':
6301 {
6302 if (LocaleCompare(keyword,"sigma") == 0)
6303 {
cristyf2f27272009-12-17 14:48:46 +00006304 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006305 break;
6306 }
6307 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6308 break;
6309 }
6310 default:
6311 {
6312 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6313 break;
6314 }
6315 }
6316 }
6317 }
6318
6319 /*
6320 sharpen image.
6321 */
6322 {
6323 Image
6324 *newImage;
6325
6326 newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6327 if (newImage == (Image *) NULL)
6328 break;
6329 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6330 msl_info->image[n]=newImage;
6331 break;
6332 }
6333 }
cristyb988fe72009-09-16 01:01:10 +00006334 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006335 {
6336 /* init the values */
6337 width = height = 0;
6338 x = y = 0;
6339
6340 if (msl_info->image[n] == (Image *) NULL)
6341 {
cristyb988fe72009-09-16 01:01:10 +00006342 ThrowMSLException(OptionError,"NoImagesDefined",
6343 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006344 break;
6345 }
6346 if (attributes == (const xmlChar **) NULL)
6347 break;
6348 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6349 {
6350 keyword=(const char *) attributes[i++];
6351 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006352 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006353 switch (*keyword)
6354 {
6355 case 'G':
6356 case 'g':
6357 {
6358 if (LocaleCompare(keyword,"geometry") == 0)
6359 {
6360 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6361 break;
6362 }
6363 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6364 break;
6365 }
6366 case 'H':
6367 case 'h':
6368 {
6369 if (LocaleCompare(keyword,"height") == 0)
6370 {
cristyf2f27272009-12-17 14:48:46 +00006371 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006372 break;
6373 }
6374 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6375 break;
6376 }
6377 case 'W':
6378 case 'w':
6379 {
6380 if (LocaleCompare(keyword,"width") == 0)
6381 {
cristyf2f27272009-12-17 14:48:46 +00006382 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006383 break;
6384 }
6385 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6386 break;
6387 }
6388 default:
6389 {
6390 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6391 break;
6392 }
6393 }
6394 }
6395
6396 /*
6397 process image.
6398 */
6399 {
6400 Image
6401 *newImage;
6402 RectangleInfo
6403 rectInfo;
6404
6405 rectInfo.height = height;
6406 rectInfo.width = width;
6407 rectInfo.x = x;
6408 rectInfo.y = y;
6409
6410
6411 newImage=ShaveImage(msl_info->image[n], &rectInfo,
6412 &msl_info->image[n]->exception);
6413 if (newImage == (Image *) NULL)
6414 break;
6415 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6416 msl_info->image[n]=newImage;
6417 }
6418
6419 break;
6420 }
cristyb988fe72009-09-16 01:01:10 +00006421 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006422 {
6423 Image
6424 *shear_image;
6425
6426 /*
6427 Shear image.
6428 */
6429 if (msl_info->image[n] == (Image *) NULL)
6430 {
cristyb988fe72009-09-16 01:01:10 +00006431 ThrowMSLException(OptionError,"NoImagesDefined",
6432 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006433 break;
6434 }
6435 if (attributes != (const xmlChar **) NULL)
6436 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6437 {
6438 keyword=(const char *) attributes[i++];
6439 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006440 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006441 CloneString(&value,attribute);
6442 switch (*keyword)
6443 {
6444 case 'F':
6445 case 'f':
6446 {
6447 if (LocaleCompare(keyword, "fill") == 0)
6448 {
6449 (void) QueryColorDatabase(value,
6450 &msl_info->image[n]->background_color,&exception);
6451 break;
6452 }
6453 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6454 keyword);
6455 break;
6456 }
6457 case 'G':
6458 case 'g':
6459 {
6460 if (LocaleCompare(keyword,"geometry") == 0)
6461 {
6462 flags=ParseGeometry(value,&geometry_info);
6463 if ((flags & SigmaValue) == 0)
6464 geometry_info.sigma=1.0;
6465 break;
6466 }
6467 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6468 keyword);
6469 break;
6470 }
6471 case 'X':
6472 case 'x':
6473 {
6474 if (LocaleCompare(keyword,"x") == 0)
6475 {
cristyf2f27272009-12-17 14:48:46 +00006476 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006477 break;
6478 }
6479 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6480 keyword);
6481 break;
6482 }
6483 case 'Y':
6484 case 'y':
6485 {
6486 if (LocaleCompare(keyword,"y") == 0)
6487 {
cristyf2f27272009-12-17 14:48:46 +00006488 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006489 break;
6490 }
6491 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6492 keyword);
6493 break;
6494 }
6495 default:
6496 {
6497 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6498 keyword);
6499 break;
6500 }
6501 }
6502 }
6503 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6504 geometry_info.sigma,&msl_info->image[n]->exception);
6505 if (shear_image == (Image *) NULL)
6506 break;
6507 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6508 msl_info->image[n]=shear_image;
6509 break;
6510 }
cristyb988fe72009-09-16 01:01:10 +00006511 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006512 {
6513 /*
6514 Signature image.
6515 */
6516 if (msl_info->image[n] == (Image *) NULL)
6517 {
cristyb988fe72009-09-16 01:01:10 +00006518 ThrowMSLException(OptionError,"NoImagesDefined",
6519 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006520 break;
6521 }
6522 if (attributes != (const xmlChar **) NULL)
6523 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6524 {
6525 keyword=(const char *) attributes[i++];
6526 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006527 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006528 CloneString(&value,attribute);
6529 switch (*keyword)
6530 {
6531 default:
6532 {
6533 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6534 keyword);
6535 break;
6536 }
6537 }
6538 }
6539 (void) SignatureImage(msl_info->image[n]);
6540 break;
6541 }
cristyb988fe72009-09-16 01:01:10 +00006542 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006543 {
6544 /*
6545 Solarize image.
6546 */
6547 if (msl_info->image[n] == (Image *) NULL)
6548 {
cristyb988fe72009-09-16 01:01:10 +00006549 ThrowMSLException(OptionError,"NoImagesDefined",
6550 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006551 break;
6552 }
6553 geometry_info.rho=QuantumRange/2.0;
6554 if (attributes != (const xmlChar **) NULL)
6555 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6556 {
6557 keyword=(const char *) attributes[i++];
6558 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006559 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006560 CloneString(&value,attribute);
6561 switch (*keyword)
6562 {
6563 case 'G':
6564 case 'g':
6565 {
6566 if (LocaleCompare(keyword,"geometry") == 0)
6567 {
6568 flags=ParseGeometry(value,&geometry_info);
6569 break;
6570 }
6571 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6572 keyword);
6573 break;
6574 }
6575 case 'T':
6576 case 't':
6577 {
6578 if (LocaleCompare(keyword,"threshold") == 0)
6579 {
cristyf2f27272009-12-17 14:48:46 +00006580 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006581 break;
6582 }
6583 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6584 keyword);
6585 break;
6586 }
6587 default:
6588 {
6589 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6590 keyword);
6591 break;
6592 }
6593 }
6594 }
6595 (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6596 break;
6597 }
cristyb988fe72009-09-16 01:01:10 +00006598 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006599 {
6600 Image
6601 *spread_image;
6602
6603 /*
6604 Spread image.
6605 */
6606 if (msl_info->image[n] == (Image *) NULL)
6607 {
cristyb988fe72009-09-16 01:01:10 +00006608 ThrowMSLException(OptionError,"NoImagesDefined",
6609 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006610 break;
6611 }
6612 if (attributes != (const xmlChar **) NULL)
6613 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6614 {
6615 keyword=(const char *) attributes[i++];
6616 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006617 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006618 CloneString(&value,attribute);
6619 switch (*keyword)
6620 {
6621 case 'G':
6622 case 'g':
6623 {
6624 if (LocaleCompare(keyword,"geometry") == 0)
6625 {
6626 flags=ParseGeometry(value,&geometry_info);
6627 if ((flags & SigmaValue) == 0)
6628 geometry_info.sigma=1.0;
6629 break;
6630 }
6631 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6632 keyword);
6633 break;
6634 }
6635 case 'R':
6636 case 'r':
6637 {
6638 if (LocaleCompare(keyword,"radius") == 0)
6639 {
cristyf2f27272009-12-17 14:48:46 +00006640 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006641 break;
6642 }
6643 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6644 keyword);
6645 break;
6646 }
6647 default:
6648 {
6649 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6650 keyword);
6651 break;
6652 }
6653 }
6654 }
6655 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6656 &msl_info->image[n]->exception);
6657 if (spread_image == (Image *) NULL)
6658 break;
6659 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6660 msl_info->image[n]=spread_image;
6661 break;
6662 }
cristyb988fe72009-09-16 01:01:10 +00006663 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006664 {
6665 Image *
6666 watermark = (Image*)NULL;
6667
6668 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006669 {
6670 ThrowMSLException(OptionError,"NoImagesDefined",
6671 (const char *) tag);
6672 break;
6673 }
cristy3ed852e2009-09-05 21:47:34 +00006674 if (attributes == (const xmlChar **) NULL)
6675 break;
6676 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6677 {
6678 keyword=(const char *) attributes[i++];
6679 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006680 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006681 switch (*keyword)
6682 {
6683 case 'I':
6684 case 'i':
6685 {
6686 if (LocaleCompare(keyword,"image") == 0)
6687 {
6688 for (j=0; j<msl_info->n;j++)
6689 {
6690 const char *
6691 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6692 if (theAttr && LocaleCompare(theAttr, value) == 0)
6693 {
6694 watermark = msl_info->image[j];
6695 break;
6696 }
6697 }
6698 break;
6699 }
6700 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6701 break;
6702 }
6703 default:
6704 {
6705 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6706 break;
6707 }
6708 }
6709 }
6710
6711 /*
6712 process image.
6713 */
6714 if ( watermark != (Image*) NULL )
6715 {
6716 Image
6717 *newImage;
6718
6719 newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6720 if (newImage == (Image *) NULL)
6721 break;
6722 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6723 msl_info->image[n]=newImage;
6724 break;
6725 } else
6726 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6727 }
cristyb988fe72009-09-16 01:01:10 +00006728 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006729 {
6730 Image *
6731 stereoImage = (Image*)NULL;
6732
6733 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006734 {
6735 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6736 break;
6737 }
cristy3ed852e2009-09-05 21:47:34 +00006738 if (attributes == (const xmlChar **) NULL)
6739 break;
6740 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6741 {
6742 keyword=(const char *) attributes[i++];
6743 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006744 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006745 switch (*keyword)
6746 {
6747 case 'I':
6748 case 'i':
6749 {
6750 if (LocaleCompare(keyword,"image") == 0)
6751 {
6752 for (j=0; j<msl_info->n;j++)
6753 {
6754 const char *
6755 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6756 if (theAttr && LocaleCompare(theAttr, value) == 0)
6757 {
6758 stereoImage = msl_info->image[j];
6759 break;
6760 }
6761 }
6762 break;
6763 }
6764 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6765 break;
6766 }
6767 default:
6768 {
6769 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6770 break;
6771 }
6772 }
6773 }
6774
6775 /*
6776 process image.
6777 */
6778 if ( stereoImage != (Image*) NULL )
6779 {
6780 Image
6781 *newImage;
6782
6783 newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6784 if (newImage == (Image *) NULL)
6785 break;
6786 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6787 msl_info->image[n]=newImage;
6788 break;
6789 } else
6790 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6791 }
cristyb988fe72009-09-16 01:01:10 +00006792 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006793 {
6794 Image
6795 *p,
6796 *q,
6797 *swap;
6798
cristybb503372010-05-27 20:51:26 +00006799 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006800 index,
6801 swap_index;
6802
6803 if (msl_info->image[n] == (Image *) NULL)
6804 {
cristyb988fe72009-09-16 01:01:10 +00006805 ThrowMSLException(OptionError,"NoImagesDefined",
6806 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006807 break;
6808 }
6809 index=(-1);
6810 swap_index=(-2);
6811 if (attributes != (const xmlChar **) NULL)
6812 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6813 {
6814 keyword=(const char *) attributes[i++];
6815 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006816 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006817 CloneString(&value,attribute);
6818 switch (*keyword)
6819 {
6820 case 'G':
6821 case 'g':
6822 {
6823 if (LocaleCompare(keyword,"indexes") == 0)
6824 {
6825 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006826 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006827 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006828 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006829 break;
6830 }
6831 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6832 keyword);
6833 break;
6834 }
6835 default:
6836 {
6837 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6838 keyword);
6839 break;
6840 }
6841 }
6842 }
6843 /*
6844 Swap images.
6845 */
6846 p=GetImageFromList(msl_info->image[n],index);
6847 q=GetImageFromList(msl_info->image[n],swap_index);
6848 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6849 {
cristyb988fe72009-09-16 01:01:10 +00006850 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006851 break;
6852 }
6853 swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6854 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6855 ReplaceImageInList(&q,swap);
6856 msl_info->image[n]=GetFirstImageInList(q);
6857 break;
6858 }
cristyb988fe72009-09-16 01:01:10 +00006859 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006860 {
6861 Image
6862 *swirl_image;
6863
6864 /*
6865 Swirl image.
6866 */
6867 if (msl_info->image[n] == (Image *) NULL)
6868 {
cristyb988fe72009-09-16 01:01:10 +00006869 ThrowMSLException(OptionError,"NoImagesDefined",
6870 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006871 break;
6872 }
6873 if (attributes != (const xmlChar **) NULL)
6874 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6875 {
6876 keyword=(const char *) attributes[i++];
6877 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006878 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006879 CloneString(&value,attribute);
6880 switch (*keyword)
6881 {
6882 case 'D':
6883 case 'd':
6884 {
6885 if (LocaleCompare(keyword,"degrees") == 0)
6886 {
cristyf2f27272009-12-17 14:48:46 +00006887 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006888 break;
6889 }
6890 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6891 keyword);
6892 break;
6893 }
6894 case 'G':
6895 case 'g':
6896 {
6897 if (LocaleCompare(keyword,"geometry") == 0)
6898 {
6899 flags=ParseGeometry(value,&geometry_info);
6900 if ((flags & SigmaValue) == 0)
6901 geometry_info.sigma=1.0;
6902 break;
6903 }
6904 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6905 keyword);
6906 break;
6907 }
6908 default:
6909 {
6910 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6911 keyword);
6912 break;
6913 }
6914 }
6915 }
6916 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6917 &msl_info->image[n]->exception);
6918 if (swirl_image == (Image *) NULL)
6919 break;
6920 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6921 msl_info->image[n]=swirl_image;
6922 break;
6923 }
cristyb988fe72009-09-16 01:01:10 +00006924 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006925 {
6926 /*
6927 Sync image.
6928 */
6929 if (msl_info->image[n] == (Image *) NULL)
6930 {
cristyb988fe72009-09-16 01:01:10 +00006931 ThrowMSLException(OptionError,"NoImagesDefined",
6932 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006933 break;
6934 }
6935 if (attributes != (const xmlChar **) NULL)
6936 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6937 {
6938 keyword=(const char *) attributes[i++];
6939 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006940 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006941 CloneString(&value,attribute);
6942 switch (*keyword)
6943 {
6944 default:
6945 {
6946 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6947 keyword);
6948 break;
6949 }
6950 }
6951 }
6952 (void) SyncImage(msl_info->image[n]);
6953 break;
6954 }
6955 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6956 }
6957 case 'T':
6958 case 't':
6959 {
cristyb988fe72009-09-16 01:01:10 +00006960 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006961 {
6962 Image
6963 *texture_image;
6964
6965 /*
6966 Texture image.
6967 */
6968 if (msl_info->image[n] == (Image *) NULL)
6969 {
cristyb988fe72009-09-16 01:01:10 +00006970 ThrowMSLException(OptionError,"NoImagesDefined",
6971 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006972 break;
6973 }
6974 texture_image=NewImageList();
6975 if (attributes != (const xmlChar **) NULL)
6976 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6977 {
6978 keyword=(const char *) attributes[i++];
6979 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006980 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006981 CloneString(&value,attribute);
6982 switch (*keyword)
6983 {
6984 case 'I':
6985 case 'i':
6986 {
6987 if (LocaleCompare(keyword,"image") == 0)
6988 for (j=0; j < msl_info->n; j++)
6989 {
6990 const char
6991 *attribute;
cristyb988fe72009-09-16 01:01:10 +00006992
cristy3ed852e2009-09-05 21:47:34 +00006993 attribute=GetImageProperty(msl_info->attributes[j],"id");
6994 if ((attribute != (const char *) NULL) &&
6995 (LocaleCompare(attribute,value) == 0))
6996 {
6997 texture_image=CloneImage(msl_info->image[j],0,0,
6998 MagickFalse,&exception);
6999 break;
7000 }
7001 }
7002 break;
7003 }
7004 default:
7005 {
7006 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7007 keyword);
7008 break;
7009 }
7010 }
7011 }
7012 (void) TextureImage(msl_info->image[n],texture_image);
7013 texture_image=DestroyImage(texture_image);
7014 break;
7015 }
cristyb988fe72009-09-16 01:01:10 +00007016 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007017 {
7018 /* init the values */
7019 double threshold = 0;
7020
7021 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007022 {
7023 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7024 break;
7025 }
cristy3ed852e2009-09-05 21:47:34 +00007026 if (attributes == (const xmlChar **) NULL)
7027 break;
7028 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7029 {
7030 keyword=(const char *) attributes[i++];
7031 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007032 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007033 switch (*keyword)
7034 {
7035 case 'T':
7036 case 't':
7037 {
7038 if (LocaleCompare(keyword,"threshold") == 0)
7039 {
cristyf2f27272009-12-17 14:48:46 +00007040 threshold = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00007041 break;
7042 }
7043 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7044 break;
7045 }
7046 default:
7047 {
7048 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7049 break;
7050 }
7051 }
7052 }
7053
7054 /*
7055 process image.
7056 */
7057 {
7058 BilevelImageChannel(msl_info->image[n],
cristybb503372010-05-27 20:51:26 +00007059 (ChannelType) ((ssize_t) (AllChannels &~ (ssize_t) OpacityChannel)),
cristy3ed852e2009-09-05 21:47:34 +00007060 threshold);
7061 break;
7062 }
7063 }
cristyb988fe72009-09-16 01:01:10 +00007064 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007065 {
7066 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007067 {
7068 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7069 break;
7070 }
cristy3ed852e2009-09-05 21:47:34 +00007071 if (attributes == (const xmlChar **) NULL)
7072 break;
7073 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7074 {
7075 keyword=(const char *) attributes[i++];
7076 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007077 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007078 switch (*keyword)
7079 {
7080 case 'C':
7081 case 'c':
7082 {
7083 if (LocaleCompare(keyword,"color") == 0)
7084 {
7085 MagickPixelPacket
7086 target;
7087
7088 (void) QueryMagickColor(value,&target,&exception);
7089 (void) TransparentPaintImage(msl_info->image[n],&target,
7090 TransparentOpacity,MagickFalse);
7091 break;
7092 }
7093 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7094 break;
7095 }
7096 default:
7097 {
7098 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7099 break;
7100 }
7101 }
7102 }
7103 break;
7104 }
cristyb988fe72009-09-16 01:01:10 +00007105 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007106 {
7107 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007108 {
7109 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7110 break;
7111 }
cristy3ed852e2009-09-05 21:47:34 +00007112
7113 /* no attributes here */
7114
7115 /* process the image */
7116 {
7117 Image
7118 *newImage;
7119 RectangleInfo
7120 rectInfo;
7121
7122 /* all zeros on a crop == trim edges! */
7123 rectInfo.height = rectInfo.width = 0;
7124 rectInfo.x = rectInfo.y = 0;
7125
7126 newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7127 if (newImage == (Image *) NULL)
7128 break;
7129 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7130 msl_info->image[n]=newImage;
7131 break;
7132 }
7133 }
7134 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7135 }
7136 case 'W':
7137 case 'w':
7138 {
cristyb988fe72009-09-16 01:01:10 +00007139 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007140 {
7141 if (msl_info->image[n] == (Image *) NULL)
7142 {
cristyb988fe72009-09-16 01:01:10 +00007143 ThrowMSLException(OptionError,"NoImagesDefined",
7144 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007145 break;
7146 }
7147 if (attributes == (const xmlChar **) NULL)
7148 break;
7149 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7150 {
7151 keyword=(const char *) attributes[i++];
7152 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007153 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007154 switch (*keyword)
7155 {
7156 case 'F':
7157 case 'f':
7158 {
7159 if (LocaleCompare(keyword,"filename") == 0)
7160 {
7161 (void) CopyMagickString(msl_info->image[n]->filename,value,
7162 MaxTextExtent);
7163 break;
7164 }
cristy4582cbb2009-09-23 00:35:43 +00007165 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007166 }
7167 default:
7168 {
cristy4582cbb2009-09-23 00:35:43 +00007169 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007170 break;
7171 }
7172 }
7173 }
7174
7175 /* process */
7176 {
7177 (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7178 break;
7179 }
7180 }
7181 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7182 }
7183 default:
7184 {
7185 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7186 break;
7187 }
7188 }
7189 if ( value != NULL )
7190 value=DestroyString(value);
7191 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7192}
7193
7194static void MSLEndElement(void *context,const xmlChar *tag)
7195{
cristybb503372010-05-27 20:51:26 +00007196 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007197 n;
7198
7199 MSLInfo
7200 *msl_info;
7201
7202 /*
7203 Called when the end of an element has been detected.
7204 */
7205 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7206 tag);
7207 msl_info=(MSLInfo *) context;
7208 n=msl_info->n;
7209 switch (*tag)
7210 {
7211 case 'C':
7212 case 'c':
7213 {
cristyb988fe72009-09-16 01:01:10 +00007214 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007215 {
7216 (void) DeleteImageProperty(msl_info->image[n],"comment");
7217 if (msl_info->content == (char *) NULL)
7218 break;
7219 StripString(msl_info->content);
7220 (void) SetImageProperty(msl_info->image[n],"comment",
7221 msl_info->content);
7222 break;
7223 }
7224 break;
7225 }
7226 case 'G':
7227 case 'g':
7228 {
cristyb988fe72009-09-16 01:01:10 +00007229 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007230 {
7231 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7232 {
cristybb503372010-05-27 20:51:26 +00007233 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007234 (msl_info->group_info[msl_info->number_groups-1].numImages);
7235 while ( i-- )
7236 {
7237 if (msl_info->image[msl_info->n] != (Image *) NULL)
7238 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7239 msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7240 msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7241 msl_info->n--;
7242 }
7243 }
7244 msl_info->number_groups--;
7245 }
7246 break;
7247 }
7248 case 'I':
7249 case 'i':
7250 {
cristyb988fe72009-09-16 01:01:10 +00007251 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007252 MSLPopImage(msl_info);
7253 break;
7254 }
7255 case 'L':
7256 case 'l':
7257 {
cristyb988fe72009-09-16 01:01:10 +00007258 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007259 {
7260 (void) DeleteImageProperty(msl_info->image[n],"label");
7261 if (msl_info->content == (char *) NULL)
7262 break;
7263 StripString(msl_info->content);
7264 (void) SetImageProperty(msl_info->image[n],"label",
7265 msl_info->content);
7266 break;
7267 }
7268 break;
7269 }
7270 case 'M':
7271 case 'm':
7272 {
cristyb988fe72009-09-16 01:01:10 +00007273 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007274 {
7275 /*
7276 This our base element.
7277 at the moment we don't do anything special
7278 but someday we might!
7279 */
7280 }
7281 break;
7282 }
7283 default:
7284 break;
7285 }
7286 if (msl_info->content != (char *) NULL)
7287 msl_info->content=DestroyString(msl_info->content);
7288}
7289
7290static void MSLCharacters(void *context,const xmlChar *c,int length)
7291{
7292 MSLInfo
7293 *msl_info;
7294
7295 register char
7296 *p;
7297
cristybb503372010-05-27 20:51:26 +00007298 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007299 i;
7300
7301 /*
7302 Receiving some characters from the parser.
7303 */
7304 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7305 " SAX.characters(%s,%d)",c,length);
7306 msl_info=(MSLInfo *) context;
7307 if (msl_info->content != (char *) NULL)
7308 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7309 strlen(msl_info->content)+length+MaxTextExtent,
7310 sizeof(*msl_info->content));
7311 else
7312 {
7313 msl_info->content=(char *) NULL;
7314 if (~length >= MaxTextExtent)
7315 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7316 sizeof(*msl_info->content));
7317 if (msl_info->content != (char *) NULL)
7318 *msl_info->content='\0';
7319 }
7320 if (msl_info->content == (char *) NULL)
7321 return;
7322 p=msl_info->content+strlen(msl_info->content);
7323 for (i=0; i < length; i++)
7324 *p++=c[i];
7325 *p='\0';
7326}
7327
7328static void MSLReference(void *context,const xmlChar *name)
7329{
7330 MSLInfo
7331 *msl_info;
7332
7333 xmlParserCtxtPtr
7334 parser;
7335
7336 /*
7337 Called when an entity reference is detected.
7338 */
7339 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7340 " SAX.reference(%s)",name);
7341 msl_info=(MSLInfo *) context;
7342 parser=msl_info->parser;
7343 if (*name == '#')
7344 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7345 else
7346 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7347}
7348
7349static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7350{
7351 MSLInfo
7352 *msl_info;
7353
7354 /*
7355 Receiving some ignorable whitespaces from the parser.
7356 */
7357 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7358 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7359 msl_info=(MSLInfo *) context;
7360}
7361
7362static void MSLProcessingInstructions(void *context,const xmlChar *target,
7363 const xmlChar *data)
7364{
7365 MSLInfo
7366 *msl_info;
7367
7368 /*
7369 A processing instruction has been parsed.
7370 */
7371 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7372 " SAX.processingInstruction(%s, %s)",
7373 target,data);
7374 msl_info=(MSLInfo *) context;
7375}
7376
7377static void MSLComment(void *context,const xmlChar *value)
7378{
7379 MSLInfo
7380 *msl_info;
7381
7382 /*
7383 A comment has been parsed.
7384 */
7385 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7386 " SAX.comment(%s)",value);
7387 msl_info=(MSLInfo *) context;
7388}
7389
7390static void MSLWarning(void *context,const char *format,...)
7391{
7392 char
7393 *message,
7394 reason[MaxTextExtent];
7395
7396 MSLInfo
7397 *msl_info;
7398
7399 va_list
7400 operands;
7401
7402 /**
7403 Display and format a warning messages, gives file, line, position and
7404 extra parameters.
7405 */
7406 va_start(operands,format);
7407 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7408 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7409 msl_info=(MSLInfo *) context;
7410#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7411 (void) vsprintf(reason,format,operands);
7412#else
7413 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7414#endif
7415 message=GetExceptionMessage(errno);
7416 ThrowMSLException(CoderError,reason,message);
7417 message=DestroyString(message);
7418 va_end(operands);
7419}
7420
7421static void MSLError(void *context,const char *format,...)
7422{
7423 char
7424 reason[MaxTextExtent];
7425
7426 MSLInfo
7427 *msl_info;
7428
7429 va_list
7430 operands;
7431
7432 /*
7433 Display and format a error formats, gives file, line, position and
7434 extra parameters.
7435 */
7436 va_start(operands,format);
7437 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7438 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7439 msl_info=(MSLInfo *) context;
7440#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7441 (void) vsprintf(reason,format,operands);
7442#else
7443 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7444#endif
7445 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7446 va_end(operands);
7447}
7448
7449static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7450{
7451 MSLInfo
7452 *msl_info;
7453
7454 xmlNodePtr
7455 child;
7456
7457 xmlParserCtxtPtr
7458 parser;
7459
7460 /*
7461 Called when a pcdata block has been parsed.
7462 */
7463 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7464 " SAX.pcdata(%s, %d)",value,length);
7465 msl_info=(MSLInfo *) context;
7466 parser=msl_info->parser;
7467 child=xmlGetLastChild(parser->node);
7468 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7469 {
7470 xmlTextConcat(child,value,length);
7471 return;
7472 }
7473 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7474}
7475
7476static void MSLExternalSubset(void *context,const xmlChar *name,
7477 const xmlChar *external_id,const xmlChar *system_id)
7478{
7479 MSLInfo
7480 *msl_info;
7481
7482 xmlParserCtxt
7483 parser_context;
7484
7485 xmlParserCtxtPtr
7486 parser;
7487
7488 xmlParserInputPtr
7489 input;
7490
7491 /*
7492 Does this document has an external subset?
7493 */
7494 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7495 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007496 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7497 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007498 msl_info=(MSLInfo *) context;
7499 parser=msl_info->parser;
7500 if (((external_id == NULL) && (system_id == NULL)) ||
7501 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7502 (msl_info->document == 0)))
7503 return;
7504 input=MSLResolveEntity(context,external_id,system_id);
7505 if (input == NULL)
7506 return;
7507 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7508 parser_context=(*parser);
7509 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7510 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7511 {
7512 parser->errNo=XML_ERR_NO_MEMORY;
7513 parser->input=parser_context.input;
7514 parser->inputNr=parser_context.inputNr;
7515 parser->inputMax=parser_context.inputMax;
7516 parser->inputTab=parser_context.inputTab;
7517 return;
7518 }
7519 parser->inputNr=0;
7520 parser->inputMax=5;
7521 parser->input=NULL;
7522 xmlPushInput(parser,input);
7523 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7524 if (input->filename == (char *) NULL)
7525 input->filename=(char *) xmlStrdup(system_id);
7526 input->line=1;
7527 input->col=1;
7528 input->base=parser->input->cur;
7529 input->cur=parser->input->cur;
7530 input->free=NULL;
7531 xmlParseExternalSubset(parser,external_id,system_id);
7532 while (parser->inputNr > 1)
7533 (void) xmlPopInput(parser);
7534 xmlFreeInputStream(parser->input);
7535 xmlFree(parser->inputTab);
7536 parser->input=parser_context.input;
7537 parser->inputNr=parser_context.inputNr;
7538 parser->inputMax=parser_context.inputMax;
7539 parser->inputTab=parser_context.inputTab;
7540}
7541
7542#if defined(__cplusplus) || defined(c_plusplus)
7543}
7544#endif
7545
7546static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7547 ExceptionInfo *exception)
7548{
cristy3ed852e2009-09-05 21:47:34 +00007549 char
7550 message[MaxTextExtent];
7551
7552 Image
7553 *msl_image;
7554
7555 int
7556 status;
7557
cristybb503372010-05-27 20:51:26 +00007558 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007559 n;
7560
7561 MSLInfo
7562 msl_info;
7563
cristy5f6f01c2009-11-19 19:36:42 +00007564 xmlSAXHandler
7565 sax_modules;
7566
cristy3ed852e2009-09-05 21:47:34 +00007567 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007568 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007569
7570 /*
7571 Open image file.
7572 */
7573 assert(image_info != (const ImageInfo *) NULL);
7574 assert(image_info->signature == MagickSignature);
7575 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007576 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7577 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007578 assert(image != (Image **) NULL);
7579 msl_image=AcquireImage(image_info);
7580 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7581 if (status == MagickFalse)
7582 {
7583 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7584 msl_image->filename);
7585 msl_image=DestroyImageList(msl_image);
7586 return(MagickFalse);
7587 }
7588 msl_image->columns=1;
7589 msl_image->rows=1;
7590 /*
7591 Parse MSL file.
7592 */
7593 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7594 msl_info.exception=exception;
7595 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7596 sizeof(*msl_info.image_info));
7597 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7598 sizeof(*msl_info.draw_info));
7599 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007600 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007601 msl_info.attributes=(Image **) AcquireMagickMemory(
7602 sizeof(*msl_info.attributes));
7603 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7604 sizeof(*msl_info.group_info));
7605 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7606 (msl_info.image == (Image **) NULL) ||
7607 (msl_info.attributes == (Image **) NULL) ||
7608 (msl_info.group_info == (MSLGroupInfo *) NULL))
7609 ThrowFatalException(ResourceLimitFatalError,
7610 "UnableToInterpretMSLImage");
7611 *msl_info.image_info=CloneImageInfo(image_info);
7612 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7613 *msl_info.attributes=AcquireImage(image_info);
7614 msl_info.group_info[0].numImages=0;
7615 /* the first slot is used to point to the MSL file image */
7616 *msl_info.image=msl_image;
7617 if (*image != (Image *) NULL)
7618 MSLPushImage(&msl_info,*image);
7619 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007620 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7621 sax_modules.internalSubset=MSLInternalSubset;
7622 sax_modules.isStandalone=MSLIsStandalone;
7623 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7624 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7625 sax_modules.resolveEntity=MSLResolveEntity;
7626 sax_modules.getEntity=MSLGetEntity;
7627 sax_modules.entityDecl=MSLEntityDeclaration;
7628 sax_modules.notationDecl=MSLNotationDeclaration;
7629 sax_modules.attributeDecl=MSLAttributeDeclaration;
7630 sax_modules.elementDecl=MSLElementDeclaration;
7631 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7632 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7633 sax_modules.startDocument=MSLStartDocument;
7634 sax_modules.endDocument=MSLEndDocument;
7635 sax_modules.startElement=MSLStartElement;
7636 sax_modules.endElement=MSLEndElement;
7637 sax_modules.reference=MSLReference;
7638 sax_modules.characters=MSLCharacters;
7639 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7640 sax_modules.processingInstruction=MSLProcessingInstructions;
7641 sax_modules.comment=MSLComment;
7642 sax_modules.warning=MSLWarning;
7643 sax_modules.error=MSLError;
7644 sax_modules.fatalError=MSLError;
7645 sax_modules.getParameterEntity=MSLGetParameterEntity;
7646 sax_modules.cdataBlock=MSLCDataBlock;
7647 sax_modules.externalSubset=MSLExternalSubset;
7648 sax_handler=(&sax_modules);
7649 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007650 msl_image->filename);
7651 while (ReadBlobString(msl_image,message) != (char *) NULL)
7652 {
cristybb503372010-05-27 20:51:26 +00007653 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007654 if (n == 0)
7655 continue;
7656 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7657 if (status != 0)
7658 break;
7659 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7660 if (msl_info.exception->severity >= ErrorException)
7661 break;
7662 }
7663 if (msl_info.exception->severity == UndefinedException)
7664 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7665 xmlFreeParserCtxt(msl_info.parser);
7666 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7667 xmlCleanupParser();
7668 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7669 msl_info.group_info);
7670 if (*image == (Image *) NULL)
7671 *image=(*msl_info.image);
cristy5f6f01c2009-11-19 19:36:42 +00007672 if ((*msl_info.image)->exception.severity != UndefinedException)
7673 return(MagickFalse);
7674 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007675}
7676
7677static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7678{
7679 Image
7680 *image;
7681
7682 /*
7683 Open image file.
7684 */
7685 assert(image_info != (const ImageInfo *) NULL);
7686 assert(image_info->signature == MagickSignature);
7687 if (image_info->debug != MagickFalse)
7688 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7689 image_info->filename);
7690 assert(exception != (ExceptionInfo *) NULL);
7691 assert(exception->signature == MagickSignature);
7692 image=(Image *) NULL;
7693 (void) ProcessMSLScript(image_info,&image,exception);
7694 return(GetFirstImageInList(image));
7695}
7696#endif
7697
7698/*
7699%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7700% %
7701% %
7702% %
7703% R e g i s t e r M S L I m a g e %
7704% %
7705% %
7706% %
7707%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7708%
7709% RegisterMSLImage() adds attributes for the MSL image format to
7710% the list of supported formats. The attributes include the image format
7711% tag, a method to read and/or write the format, whether the format
7712% supports the saving of more than one frame to the same file or blob,
7713% whether the format supports native in-memory I/O, and a brief
7714% description of the format.
7715%
7716% The format of the RegisterMSLImage method is:
7717%
cristybb503372010-05-27 20:51:26 +00007718% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007719%
7720*/
cristybb503372010-05-27 20:51:26 +00007721ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007722{
7723 MagickInfo
7724 *entry;
7725
7726 entry=SetMagickInfo("MSL");
7727#if defined(MAGICKCORE_XML_DELEGATE)
7728 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7729 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7730#endif
7731 entry->description=ConstantString("Magick Scripting Language");
7732 entry->module=ConstantString("MSL");
7733 (void) RegisterMagickInfo(entry);
7734 return(MagickImageCoderSignature);
7735}
7736
cristy6b9f7ed2010-04-24 01:08:02 +00007737#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007738/*
7739%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7740% %
7741% %
7742% %
cristyb988fe72009-09-16 01:01:10 +00007743% S e t M S L A t t r i b u t e s %
7744% %
7745% %
7746% %
7747%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7748%
7749% SetMSLAttributes() ...
7750%
7751% The format of the SetMSLAttributes method is:
7752%
7753% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007754% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007755%
7756% A description of each parameter follows:
7757%
7758% o msl_info: the MSL info.
7759%
cristyb20775d2009-09-16 01:51:41 +00007760% o keyword: the keyword.
7761%
7762% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007763%
7764*/
cristyb20775d2009-09-16 01:51:41 +00007765static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7766 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007767{
cristy4582cbb2009-09-23 00:35:43 +00007768 Image
7769 *attributes;
7770
cristyb20775d2009-09-16 01:51:41 +00007771 DrawInfo
7772 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007773
7774 ExceptionInfo
7775 *exception;
7776
cristy4582cbb2009-09-23 00:35:43 +00007777 GeometryInfo
7778 geometry_info;
7779
cristy4fa36e42009-09-18 14:24:06 +00007780 Image
7781 *image;
7782
cristyb20775d2009-09-16 01:51:41 +00007783 ImageInfo
7784 *image_info;
7785
cristy4582cbb2009-09-23 00:35:43 +00007786 int
7787 flags;
7788
cristybb503372010-05-27 20:51:26 +00007789 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007790 n;
7791
cristyb988fe72009-09-16 01:01:10 +00007792 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007793 if (keyword == (const char *) NULL)
7794 return(MagickTrue);
7795 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007796 return(MagickTrue);
7797 exception=msl_info->exception;
7798 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007799 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007800 image_info=msl_info->image_info[n];
7801 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007802 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007803 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007804 {
cristyfb758a52009-09-16 14:36:08 +00007805 case 'A':
7806 case 'a':
7807 {
7808 if (LocaleCompare(keyword,"adjoin") == 0)
7809 {
cristybb503372010-05-27 20:51:26 +00007810 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007811 adjoin;
7812
7813 adjoin=ParseMagickOption(MagickBooleanOptions,MagickFalse,value);
7814 if (adjoin < 0)
7815 ThrowMSLException(OptionError,"UnrecognizedType",value);
7816 image_info->adjoin=(MagickBooleanType) adjoin;
7817 break;
7818 }
cristy4fa36e42009-09-18 14:24:06 +00007819 if (LocaleCompare(keyword,"alpha") == 0)
7820 {
cristybb503372010-05-27 20:51:26 +00007821 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007822 alpha;
7823
7824 alpha=ParseMagickOption(MagickAlphaOptions,MagickFalse,value);
7825 if (alpha < 0)
7826 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007827 if (image != (Image *) NULL)
7828 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha);
7829 break;
7830 }
7831 if (LocaleCompare(keyword,"antialias") == 0)
7832 {
cristybb503372010-05-27 20:51:26 +00007833 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007834 antialias;
7835
7836 antialias=ParseMagickOption(MagickBooleanOptions,MagickFalse,value);
7837 if (antialias < 0)
7838 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7839 image_info->antialias=(MagickBooleanType) antialias;
7840 break;
7841 }
7842 if (LocaleCompare(keyword,"area-limit") == 0)
7843 {
7844 MagickSizeType
7845 limit;
7846
7847 limit=MagickResourceInfinity;
7848 if (LocaleCompare(value,"unlimited") != 0)
cristyf2f27272009-12-17 14:48:46 +00007849 limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007850 (void) SetMagickResourceLimit(AreaResource,limit);
7851 break;
7852 }
7853 if (LocaleCompare(keyword,"attenuate") == 0)
7854 {
7855 (void) SetImageOption(image_info,keyword,value);
7856 break;
7857 }
7858 if (LocaleCompare(keyword,"authenticate") == 0)
7859 {
7860 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007861 break;
7862 }
cristyfb758a52009-09-16 14:36:08 +00007863 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7864 break;
7865 }
cristyb20775d2009-09-16 01:51:41 +00007866 case 'B':
7867 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007868 {
cristyb20775d2009-09-16 01:51:41 +00007869 if (LocaleCompare(keyword,"background") == 0)
7870 {
cristy2c8b6312009-09-16 02:37:23 +00007871 (void) QueryColorDatabase(value,&image_info->background_color,
cristyb20775d2009-09-16 01:51:41 +00007872 exception);
7873 break;
7874 }
cristy4582cbb2009-09-23 00:35:43 +00007875 if (LocaleCompare(keyword,"bias") == 0)
7876 {
7877 if (image == (Image *) NULL)
7878 break;
cristyf2f27272009-12-17 14:48:46 +00007879 image->bias=SiPrefixToDouble(value,QuantumRange);
cristy4582cbb2009-09-23 00:35:43 +00007880 break;
7881 }
7882 if (LocaleCompare(keyword,"blue-primary") == 0)
7883 {
7884 if (image == (Image *) NULL)
7885 break;
7886 flags=ParseGeometry(value,&geometry_info);
7887 image->chromaticity.blue_primary.x=geometry_info.rho;
7888 image->chromaticity.blue_primary.y=geometry_info.sigma;
7889 if ((flags & SigmaValue) == 0)
7890 image->chromaticity.blue_primary.y=
7891 image->chromaticity.blue_primary.x;
7892 break;
7893 }
cristy2c8b6312009-09-16 02:37:23 +00007894 if (LocaleCompare(keyword,"bordercolor") == 0)
7895 {
7896 (void) QueryColorDatabase(value,&image_info->border_color,
7897 exception);
7898 break;
7899 }
7900 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7901 break;
7902 }
7903 case 'D':
7904 case 'd':
7905 {
7906 if (LocaleCompare(keyword,"density") == 0)
7907 {
7908 (void) CloneString(&image_info->density,value);
7909 (void) CloneString(&draw_info->density,value);
7910 break;
7911 }
cristyb20775d2009-09-16 01:51:41 +00007912 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7913 break;
7914 }
7915 case 'F':
7916 case 'f':
7917 {
7918 if (LocaleCompare(keyword,"fill") == 0)
7919 {
cristy2c8b6312009-09-16 02:37:23 +00007920 (void) QueryColorDatabase(value,&draw_info->fill,exception);
cristya30afaf2009-09-22 13:42:12 +00007921 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00007922 break;
7923 }
cristy4582cbb2009-09-23 00:35:43 +00007924 if (LocaleCompare(keyword,"filename") == 0)
7925 {
7926 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7927 break;
7928 }
7929 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7930 break;
7931 }
7932 case 'G':
7933 case 'g':
7934 {
7935 if (LocaleCompare(keyword,"gravity") == 0)
7936 {
cristybb503372010-05-27 20:51:26 +00007937 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007938 gravity;
7939
7940 gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,value);
7941 if (gravity < 0)
7942 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7943 (void) SetImageOption(image_info,keyword,value);
7944 break;
7945 }
cristyb20775d2009-09-16 01:51:41 +00007946 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7947 break;
7948 }
7949 case 'I':
7950 case 'i':
7951 {
7952 if (LocaleCompare(keyword,"id") == 0)
7953 {
cristy4582cbb2009-09-23 00:35:43 +00007954 (void) SetImageProperty(attributes,keyword,value);
cristy2c8b6312009-09-16 02:37:23 +00007955 break;
7956 }
7957 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7958 break;
7959 }
7960 case 'M':
7961 case 'm':
7962 {
7963 if (LocaleCompare(keyword,"magick") == 0)
7964 {
7965 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
7966 break;
7967 }
cristy2c8b6312009-09-16 02:37:23 +00007968 if (LocaleCompare(keyword,"mattecolor") == 0)
7969 {
7970 (void) QueryColorDatabase(value,&image_info->matte_color,
7971 exception);
cristyb20775d2009-09-16 01:51:41 +00007972 break;
7973 }
7974 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7975 break;
7976 }
7977 case 'P':
7978 case 'p':
7979 {
7980 if (LocaleCompare(keyword,"pointsize") == 0)
7981 {
cristyf2f27272009-12-17 14:48:46 +00007982 image_info->pointsize=StringToDouble(value);
7983 draw_info->pointsize=StringToDouble(value);
cristyb20775d2009-09-16 01:51:41 +00007984 break;
7985 }
7986 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7987 break;
7988 }
cristy4582cbb2009-09-23 00:35:43 +00007989 case 'Q':
7990 case 'q':
7991 {
7992 if (LocaleCompare(keyword,"quality") == 0)
7993 {
cristyf2f27272009-12-17 14:48:46 +00007994 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00007995 if (image == (Image *) NULL)
7996 break;
cristyf2f27272009-12-17 14:48:46 +00007997 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00007998 break;
7999 }
8000 break;
8001 }
cristyb20775d2009-09-16 01:51:41 +00008002 case 'S':
8003 case 's':
8004 {
8005 if (LocaleCompare(keyword,"size") == 0)
8006 {
cristy2c8b6312009-09-16 02:37:23 +00008007 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008008 break;
8009 }
8010 if (LocaleCompare(keyword,"stroke") == 0)
8011 {
cristy2c8b6312009-09-16 02:37:23 +00008012 (void) QueryColorDatabase(value,&draw_info->stroke,exception);
cristya30afaf2009-09-22 13:42:12 +00008013 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008014 break;
8015 }
8016 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8017 break;
8018 }
8019 default:
8020 {
8021 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8022 break;
cristyb988fe72009-09-16 01:01:10 +00008023 }
8024 }
8025 return(MagickTrue);
8026}
cristy6b9f7ed2010-04-24 01:08:02 +00008027#endif
cristyb988fe72009-09-16 01:01:10 +00008028
8029/*
8030%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8031% %
8032% %
8033% %
cristy3ed852e2009-09-05 21:47:34 +00008034% U n r e g i s t e r M S L I m a g e %
8035% %
8036% %
8037% %
8038%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8039%
8040% UnregisterMSLImage() removes format registrations made by the
8041% MSL module from the list of supported formats.
8042%
8043% The format of the UnregisterMSLImage method is:
8044%
8045% UnregisterMSLImage(void)
8046%
8047*/
8048ModuleExport void UnregisterMSLImage(void)
8049{
8050 (void) UnregisterMagickInfo("MSL");
8051}
8052
8053#if defined(MAGICKCORE_XML_DELEGATE)
8054/*
8055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8056% %
8057% %
8058% %
8059% W r i t e M S L I m a g e %
8060% %
8061% %
8062% %
8063%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8064%
8065% WriteMSLImage() writes an image to a file in MVG image format.
8066%
8067% The format of the WriteMSLImage method is:
8068%
8069% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8070%
8071% A description of each parameter follows.
8072%
8073% o image_info: the image info.
8074%
8075% o image: The image.
8076%
8077*/
8078static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8079{
8080 assert(image_info != (const ImageInfo *) NULL);
8081 assert(image_info->signature == MagickSignature);
8082 assert(image != (Image *) NULL);
8083 assert(image->signature == MagickSignature);
8084 if (image->debug != MagickFalse)
8085 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8086 (void) ReferenceImage(image);
8087 (void) ProcessMSLScript(image_info,&image,&image->exception);
8088 return(MagickTrue);
8089}
8090#endif