blob: aa85eac13c882dfe64aa89fd54071a1aec0448c9 [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% %
cristy16af1cb2009-12-11 21:38:29 +000022% Copyright 1999-2010 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)
91# if defined(__WINDOWS__)
92# 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{
116 unsigned long
117 numImages; /* how many images are in this group */
118} MSLGroupInfo;
119
120typedef struct _MSLInfo
121{
122 ExceptionInfo
123 *exception;
124
125 long
126 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{
548 long
549 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
632 long
633 option,
634 j,
635 n,
636 x,
637 y;
638
639 MSLInfo
640 *msl_info;
641
642 RectangleInfo
643 geometry;
644
645 register long
646 i;
647
648 unsigned long
649 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 }
1064 (void) FormatMagickString(text,MaxTextExtent,"%lux%lu%+ld%+ld",
1065 geometry.width,geometry.height,geometry.x,geometry.y);
1066 CloneString(&draw_info->geometry,text);
1067 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
1068 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
1069 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
1070 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
1071 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
1072 current.tx;
1073 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
1074 current.ty;
1075 (void) AnnotateImage(msl_info->image[n],draw_info);
1076 draw_info=DestroyDrawInfo(draw_info);
1077 break;
1078 }
cristyb988fe72009-09-16 01:01:10 +00001079 if (LocaleCompare((const char *) tag,"append") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001080 {
1081 Image
1082 *append_image;
1083
1084 MagickBooleanType
1085 stack;
cristyb988fe72009-09-16 01:01:10 +00001086
cristy3ed852e2009-09-05 21:47:34 +00001087 if (msl_info->image[n] == (Image *) NULL)
1088 {
cristyb988fe72009-09-16 01:01:10 +00001089 ThrowMSLException(OptionError,"NoImagesDefined",
1090 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001091 break;
1092 }
1093 stack=MagickFalse;
1094 if (attributes != (const xmlChar **) NULL)
1095 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1096 {
1097 keyword=(const char *) attributes[i++];
1098 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001099 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001100 CloneString(&value,attribute);
1101 switch (*keyword)
1102 {
1103 case 'S':
1104 case 's':
1105 {
1106 if (LocaleCompare(keyword,"stack") == 0)
1107 {
1108 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
1109 value);
1110 if (option < 0)
1111 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1112 value);
1113 stack=(MagickBooleanType) option;
1114 break;
1115 }
1116 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1117 keyword);
1118 break;
1119 }
1120 default:
1121 {
1122 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1123 keyword);
1124 break;
1125 }
1126 }
1127 }
1128 append_image=AppendImages(msl_info->image[n],stack,
1129 &msl_info->image[n]->exception);
1130 if (append_image == (Image *) NULL)
1131 break;
1132 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1133 msl_info->image[n]=append_image;
1134 break;
1135 }
1136 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1137 break;
1138 }
1139 case 'B':
1140 case 'b':
1141 {
cristyb988fe72009-09-16 01:01:10 +00001142 if (LocaleCompare((const char *) tag,"blur") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001143 {
1144 Image
1145 *blur_image;
1146
1147 /*
1148 Blur image.
1149 */
1150 if (msl_info->image[n] == (Image *) NULL)
1151 {
cristyb988fe72009-09-16 01:01:10 +00001152 ThrowMSLException(OptionError,"NoImagesDefined",
1153 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001154 break;
1155 }
1156 if (attributes != (const xmlChar **) NULL)
1157 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1158 {
1159 keyword=(const char *) attributes[i++];
1160 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001161 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001162 CloneString(&value,attribute);
1163 switch (*keyword)
1164 {
1165 case 'C':
1166 case 'c':
1167 {
1168 if (LocaleCompare(keyword,"channel") == 0)
1169 {
1170 option=ParseChannelOption(value);
1171 if (option < 0)
1172 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1173 value);
1174 channel=(ChannelType) option;
1175 break;
1176 }
1177 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1178 keyword);
1179 break;
1180 }
1181 case 'G':
1182 case 'g':
1183 {
1184 if (LocaleCompare(keyword,"geometry") == 0)
1185 {
1186 flags=ParseGeometry(value,&geometry_info);
1187 if ((flags & SigmaValue) == 0)
1188 geometry_info.sigma=1.0;
1189 break;
1190 }
1191 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1192 keyword);
1193 break;
1194 }
1195 case 'R':
1196 case 'r':
1197 {
1198 if (LocaleCompare(keyword,"radius") == 0)
1199 {
cristyf2f27272009-12-17 14:48:46 +00001200 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00001201 break;
1202 }
1203 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1204 keyword);
1205 break;
1206 }
1207 case 'S':
1208 case 's':
1209 {
1210 if (LocaleCompare(keyword,"sigma") == 0)
1211 {
cristyf2f27272009-12-17 14:48:46 +00001212 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001213 break;
1214 }
1215 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1216 keyword);
1217 break;
1218 }
1219 default:
1220 {
1221 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1222 keyword);
1223 break;
1224 }
1225 }
1226 }
1227 blur_image=BlurImageChannel(msl_info->image[n],channel,
1228 geometry_info.rho,geometry_info.sigma,
1229 &msl_info->image[n]->exception);
1230 if (blur_image == (Image *) NULL)
1231 break;
1232 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1233 msl_info->image[n]=blur_image;
1234 break;
1235 }
cristyb988fe72009-09-16 01:01:10 +00001236 if (LocaleCompare((const char *) tag,"border") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001237 {
1238 Image
1239 *border_image;
1240
1241 /*
1242 Border image.
1243 */
1244 if (msl_info->image[n] == (Image *) NULL)
1245 {
cristyb988fe72009-09-16 01:01:10 +00001246 ThrowMSLException(OptionError,"NoImagesDefined",
1247 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001248 break;
1249 }
1250 SetGeometry(msl_info->image[n],&geometry);
1251 if (attributes != (const xmlChar **) NULL)
1252 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1253 {
1254 keyword=(const char *) attributes[i++];
1255 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001256 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001257 CloneString(&value,attribute);
1258 switch (*keyword)
1259 {
1260 case 'C':
1261 case 'c':
1262 {
1263 if (LocaleCompare(keyword,"compose") == 0)
1264 {
1265 option=ParseMagickOption(MagickComposeOptions,MagickFalse,
1266 value);
1267 if (option < 0)
1268 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1269 value);
1270 msl_info->image[n]->compose=(CompositeOperator) option;
1271 break;
1272 }
1273 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1274 keyword);
1275 break;
1276 }
1277 case 'F':
1278 case 'f':
1279 {
1280 if (LocaleCompare(keyword, "fill") == 0)
1281 {
1282 (void) QueryColorDatabase(value,
1283 &msl_info->image[n]->border_color,&exception);
1284 break;
1285 }
1286 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1287 keyword);
1288 break;
1289 }
1290 case 'G':
1291 case 'g':
1292 {
1293 if (LocaleCompare(keyword,"geometry") == 0)
1294 {
1295 flags=ParsePageGeometry(msl_info->image[n],value,
1296 &geometry,&exception);
1297 if ((flags & HeightValue) == 0)
1298 geometry.height=geometry.width;
1299 break;
1300 }
1301 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1302 keyword);
1303 break;
1304 }
1305 case 'H':
1306 case 'h':
1307 {
1308 if (LocaleCompare(keyword,"height") == 0)
1309 {
cristyf2f27272009-12-17 14:48:46 +00001310 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001311 break;
1312 }
1313 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1314 keyword);
1315 break;
1316 }
1317 case 'W':
1318 case 'w':
1319 {
1320 if (LocaleCompare(keyword,"width") == 0)
1321 {
cristyf2f27272009-12-17 14:48:46 +00001322 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001323 break;
1324 }
1325 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1326 keyword);
1327 break;
1328 }
1329 default:
1330 {
1331 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1332 keyword);
1333 break;
1334 }
1335 }
1336 }
1337 border_image=BorderImage(msl_info->image[n],&geometry,
1338 &msl_info->image[n]->exception);
1339 if (border_image == (Image *) NULL)
1340 break;
1341 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1342 msl_info->image[n]=border_image;
1343 break;
1344 }
1345 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1346 }
1347 case 'C':
1348 case 'c':
1349 {
cristyb988fe72009-09-16 01:01:10 +00001350 if (LocaleCompare((const char *) tag,"colorize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001351 {
1352 char
1353 opacity[MaxTextExtent];
1354
1355 Image
1356 *colorize_image;
1357
1358 PixelPacket
1359 target;
1360
1361 /*
1362 Add noise image.
1363 */
1364 if (msl_info->image[n] == (Image *) NULL)
1365 {
cristyb988fe72009-09-16 01:01:10 +00001366 ThrowMSLException(OptionError,"NoImagesDefined",
1367 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001368 break;
1369 }
1370 target=msl_info->image[n]->background_color;
1371 (void) CopyMagickString(opacity,"100",MaxTextExtent);
1372 if (attributes != (const xmlChar **) NULL)
1373 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1374 {
1375 keyword=(const char *) attributes[i++];
1376 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001377 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001378 CloneString(&value,attribute);
1379 switch (*keyword)
1380 {
1381 case 'F':
1382 case 'f':
1383 {
1384 if (LocaleCompare(keyword,"fill") == 0)
1385 {
1386 (void) QueryColorDatabase(value,&target,
1387 &msl_info->image[n]->exception);
1388 break;
1389 }
1390 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1391 keyword);
1392 break;
1393 }
1394 case 'O':
1395 case 'o':
1396 {
1397 if (LocaleCompare(keyword,"opacity") == 0)
1398 {
1399 (void) CopyMagickString(opacity,value,MaxTextExtent);
1400 break;
1401 }
1402 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1403 keyword);
1404 break;
1405 }
1406 default:
1407 {
1408 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1409 keyword);
1410 break;
1411 }
1412 }
1413 }
1414 colorize_image=ColorizeImage(msl_info->image[n],opacity,target,
1415 &msl_info->image[n]->exception);
1416 if (colorize_image == (Image *) NULL)
1417 break;
1418 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1419 msl_info->image[n]=colorize_image;
1420 break;
1421 }
cristyb988fe72009-09-16 01:01:10 +00001422 if (LocaleCompare((const char *) tag, "charcoal") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001423 {
1424 double radius = 0.0,
1425 sigma = 1.0;
1426
1427 if (msl_info->image[n] == (Image *) NULL)
1428 {
cristyb988fe72009-09-16 01:01:10 +00001429 ThrowMSLException(OptionError,"NoImagesDefined",
1430 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001431 break;
1432 }
1433 /*
1434 NOTE: charcoal can have no attributes, since we use all the defaults!
1435 */
1436 if (attributes != (const xmlChar **) NULL)
1437 {
1438 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1439 {
1440 keyword=(const char *) attributes[i++];
1441 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001442 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00001443 switch (*keyword)
1444 {
1445 case 'R':
1446 case 'r':
1447 {
1448 if (LocaleCompare(keyword, "radius") == 0)
1449 {
cristyf2f27272009-12-17 14:48:46 +00001450 radius = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00001451 break;
1452 }
1453 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1454 break;
1455 }
1456 case 'S':
1457 case 's':
1458 {
1459 if (LocaleCompare(keyword,"sigma") == 0)
1460 {
cristyf2f27272009-12-17 14:48:46 +00001461 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00001462 break;
1463 }
1464 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1465 break;
1466 }
1467 default:
1468 {
1469 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1470 break;
1471 }
1472 }
1473 }
1474 }
1475
1476 /*
1477 charcoal image.
1478 */
1479 {
1480 Image
1481 *newImage;
1482
1483 newImage=CharcoalImage(msl_info->image[n],radius,sigma,
1484 &msl_info->image[n]->exception);
1485 if (newImage == (Image *) NULL)
1486 break;
1487 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1488 msl_info->image[n]=newImage;
1489 break;
1490 }
1491 }
cristyb988fe72009-09-16 01:01:10 +00001492 if (LocaleCompare((const char *) tag,"chop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001493 {
1494 Image
1495 *chop_image;
1496
1497 /*
1498 Chop image.
1499 */
1500 if (msl_info->image[n] == (Image *) NULL)
1501 {
cristyb988fe72009-09-16 01:01:10 +00001502 ThrowMSLException(OptionError,"NoImagesDefined",
1503 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001504 break;
1505 }
1506 SetGeometry(msl_info->image[n],&geometry);
1507 if (attributes != (const xmlChar **) NULL)
1508 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1509 {
1510 keyword=(const char *) attributes[i++];
1511 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001512 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001513 CloneString(&value,attribute);
1514 switch (*keyword)
1515 {
1516 case 'G':
1517 case 'g':
1518 {
1519 if (LocaleCompare(keyword,"geometry") == 0)
1520 {
1521 flags=ParsePageGeometry(msl_info->image[n],value,
1522 &geometry,&exception);
1523 if ((flags & HeightValue) == 0)
1524 geometry.height=geometry.width;
1525 break;
1526 }
1527 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1528 keyword);
1529 break;
1530 }
1531 case 'H':
1532 case 'h':
1533 {
1534 if (LocaleCompare(keyword,"height") == 0)
1535 {
cristyf2f27272009-12-17 14:48:46 +00001536 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001537 break;
1538 }
1539 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1540 keyword);
1541 break;
1542 }
1543 case 'W':
1544 case 'w':
1545 {
1546 if (LocaleCompare(keyword,"width") == 0)
1547 {
cristyf2f27272009-12-17 14:48:46 +00001548 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001549 break;
1550 }
1551 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1552 keyword);
1553 break;
1554 }
1555 case 'X':
1556 case 'x':
1557 {
1558 if (LocaleCompare(keyword,"x") == 0)
1559 {
cristyf2f27272009-12-17 14:48:46 +00001560 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001561 break;
1562 }
1563 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1564 keyword);
1565 break;
1566 }
1567 case 'Y':
1568 case 'y':
1569 {
1570 if (LocaleCompare(keyword,"y") == 0)
1571 {
cristyf2f27272009-12-17 14:48:46 +00001572 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001573 break;
1574 }
1575 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1576 keyword);
1577 break;
1578 }
1579 default:
1580 {
1581 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1582 keyword);
1583 break;
1584 }
1585 }
1586 }
1587 chop_image=ChopImage(msl_info->image[n],&geometry,
1588 &msl_info->image[n]->exception);
1589 if (chop_image == (Image *) NULL)
1590 break;
1591 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1592 msl_info->image[n]=chop_image;
1593 break;
1594 }
cristyb988fe72009-09-16 01:01:10 +00001595 if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001596 {
1597 PaintMethod
1598 paint_method;
1599
1600 MagickPixelPacket
1601 target;
1602
1603 /*
1604 Color floodfill image.
1605 */
1606 if (msl_info->image[n] == (Image *) NULL)
1607 {
cristyb988fe72009-09-16 01:01:10 +00001608 ThrowMSLException(OptionError,"NoImagesDefined",
1609 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001610 break;
1611 }
1612 draw_info=CloneDrawInfo(msl_info->image_info[n],
1613 msl_info->draw_info[n]);
1614 SetGeometry(msl_info->image[n],&geometry);
1615 paint_method=FloodfillMethod;
1616 if (attributes != (const xmlChar **) NULL)
1617 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1618 {
1619 keyword=(const char *) attributes[i++];
1620 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001621 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001622 CloneString(&value,attribute);
1623 switch (*keyword)
1624 {
1625 case 'B':
1626 case 'b':
1627 {
1628 if (LocaleCompare(keyword,"bordercolor") == 0)
1629 {
1630 (void) QueryMagickColor(value,&target,&exception);
1631 paint_method=FillToBorderMethod;
1632 break;
1633 }
1634 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1635 keyword);
1636 break;
1637 }
1638 case 'F':
1639 case 'f':
1640 {
1641 if (LocaleCompare(keyword,"fill") == 0)
1642 {
1643 (void) QueryColorDatabase(value,&draw_info->fill,
1644 &exception);
1645 break;
1646 }
1647 if (LocaleCompare(keyword,"fuzz") == 0)
1648 {
cristyf2f27272009-12-17 14:48:46 +00001649 msl_info->image[n]->fuzz=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00001650 break;
1651 }
1652 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1653 keyword);
1654 break;
1655 }
1656 case 'G':
1657 case 'g':
1658 {
1659 if (LocaleCompare(keyword,"geometry") == 0)
1660 {
1661 flags=ParsePageGeometry(msl_info->image[n],value,
1662 &geometry,&exception);
1663 if ((flags & HeightValue) == 0)
1664 geometry.height=geometry.width;
1665 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1666 geometry.x,geometry.y,&target,&exception);
1667 break;
1668 }
1669 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1670 keyword);
1671 break;
1672 }
1673 case 'X':
1674 case 'x':
1675 {
1676 if (LocaleCompare(keyword,"x") == 0)
1677 {
cristyf2f27272009-12-17 14:48:46 +00001678 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001679 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1680 geometry.x,geometry.y,&target,&exception);
1681 break;
1682 }
1683 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1684 keyword);
1685 break;
1686 }
1687 case 'Y':
1688 case 'y':
1689 {
1690 if (LocaleCompare(keyword,"y") == 0)
1691 {
cristyf2f27272009-12-17 14:48:46 +00001692 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001693 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1694 geometry.x,geometry.y,&target,&exception);
1695 break;
1696 }
1697 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1698 keyword);
1699 break;
1700 }
1701 default:
1702 {
1703 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1704 keyword);
1705 break;
1706 }
1707 }
1708 }
1709 (void) FloodfillPaintImage(msl_info->image[n],DefaultChannels,
1710 draw_info,&target,geometry.x,geometry.y,
1711 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
1712 draw_info=DestroyDrawInfo(draw_info);
1713 break;
1714 }
cristyb988fe72009-09-16 01:01:10 +00001715 if (LocaleCompare((const char *) tag,"comment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001716 break;
cristyb988fe72009-09-16 01:01:10 +00001717 if (LocaleCompare((const char *) tag,"composite") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001718 {
1719 char
1720 composite_geometry[MaxTextExtent];
1721
1722 CompositeOperator
1723 compose;
1724
1725 Image
1726 *composite_image,
1727 *rotate_image;
1728
1729 PixelPacket
1730 target;
1731
1732 /*
1733 Composite image.
1734 */
1735 if (msl_info->image[n] == (Image *) NULL)
1736 {
cristyb988fe72009-09-16 01:01:10 +00001737 ThrowMSLException(OptionError,"NoImagesDefined",
1738 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001739 break;
1740 }
1741 composite_image=NewImageList();
1742 compose=OverCompositeOp;
1743 if (attributes != (const xmlChar **) NULL)
1744 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1745 {
1746 keyword=(const char *) attributes[i++];
1747 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001748 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001749 CloneString(&value,attribute);
1750 switch (*keyword)
1751 {
1752 case 'C':
1753 case 'c':
1754 {
1755 if (LocaleCompare(keyword,"compose") == 0)
1756 {
1757 option=ParseMagickOption(MagickComposeOptions,MagickFalse,
1758 value);
1759 if (option < 0)
1760 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1761 value);
1762 compose=(CompositeOperator) option;
1763 break;
1764 }
1765 break;
1766 }
1767 case 'I':
1768 case 'i':
1769 {
1770 if (LocaleCompare(keyword,"image") == 0)
1771 for (j=0; j < msl_info->n; j++)
1772 {
1773 const char
1774 *attribute;
cristyb988fe72009-09-16 01:01:10 +00001775
cristy3ed852e2009-09-05 21:47:34 +00001776 attribute=GetImageProperty(msl_info->attributes[j],"id");
1777 if ((attribute != (const char *) NULL) &&
1778 (LocaleCompare(attribute,value) == 0))
1779 {
1780 composite_image=CloneImage(msl_info->image[j],0,0,
1781 MagickFalse,&exception);
1782 break;
1783 }
1784 }
1785 break;
1786 }
1787 default:
1788 break;
1789 }
1790 }
1791 if (composite_image == (Image *) NULL)
1792 break;
1793 rotate_image=NewImageList();
1794 SetGeometry(msl_info->image[n],&geometry);
1795 if (attributes != (const xmlChar **) NULL)
1796 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1797 {
1798 keyword=(const char *) attributes[i++];
1799 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001800 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001801 CloneString(&value,attribute);
1802 switch (*keyword)
1803 {
1804 case 'B':
1805 case 'b':
1806 {
1807 if (LocaleCompare(keyword,"blend") == 0)
1808 {
1809 (void) SetImageArtifact(composite_image,
1810 "compose:args",value);
1811 break;
1812 }
1813 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1814 keyword);
1815 break;
1816 }
1817 case 'C':
1818 case 'c':
1819 {
1820 if (LocaleCompare(keyword,"channel") == 0)
1821 {
1822 option=ParseChannelOption(value);
1823 if (option < 0)
1824 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1825 value);
1826 channel=(ChannelType) option;
1827 break;
1828 }
1829 if (LocaleCompare(keyword, "color") == 0)
1830 {
1831 (void) QueryColorDatabase(value,
1832 &composite_image->background_color,&exception);
1833 break;
1834 }
1835 if (LocaleCompare(keyword,"compose") == 0)
1836 break;
1837 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1838 keyword);
1839 break;
1840 }
1841 case 'G':
1842 case 'g':
1843 {
1844 if (LocaleCompare(keyword,"geometry") == 0)
1845 {
1846 flags=ParsePageGeometry(msl_info->image[n],value,
1847 &geometry,&exception);
1848 if ((flags & HeightValue) == 0)
1849 geometry.height=geometry.width;
1850 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
1851 geometry.y,&target,&exception);
1852 break;
1853 }
1854 if (LocaleCompare(keyword,"gravity") == 0)
1855 {
1856 option=ParseMagickOption(MagickGravityOptions,MagickFalse,
1857 value);
1858 if (option < 0)
1859 ThrowMSLException(OptionError,"UnrecognizedGravityType",
1860 value);
1861 msl_info->image[n]->gravity=(GravityType) option;
1862 break;
1863 }
1864 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1865 keyword);
1866 break;
1867 }
1868 case 'I':
1869 case 'i':
1870 {
1871 if (LocaleCompare(keyword,"image") == 0)
1872 break;
1873 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1874 keyword);
1875 break;
1876 }
1877 case 'M':
1878 case 'm':
1879 {
1880 if (LocaleCompare(keyword,"mask") == 0)
1881 for (j=0; j < msl_info->n; j++)
1882 {
1883 const char
1884 *attribute;
1885
1886 attribute=GetImageProperty(msl_info->attributes[j],"id");
1887 if ((attribute != (const char *) NULL) &&
1888 (LocaleCompare(value,value) == 0))
1889 {
1890 SetImageType(composite_image,TrueColorMatteType);
1891 (void) CompositeImage(composite_image,
1892 CopyOpacityCompositeOp,msl_info->image[j],0,0);
1893 break;
1894 }
1895 }
1896 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1897 keyword);
1898 break;
1899 }
1900 case 'O':
1901 case 'o':
1902 {
1903 if (LocaleCompare(keyword,"opacity") == 0)
1904 {
1905 long
1906 opacity,
1907 y;
cristyb988fe72009-09-16 01:01:10 +00001908
cristy3ed852e2009-09-05 21:47:34 +00001909 register long
1910 x;
cristyb988fe72009-09-16 01:01:10 +00001911
cristy3ed852e2009-09-05 21:47:34 +00001912 register PixelPacket
1913 *q;
cristyb988fe72009-09-16 01:01:10 +00001914
cristy3ed852e2009-09-05 21:47:34 +00001915 CacheView
1916 *composite_view;
1917
cristyf2f27272009-12-17 14:48:46 +00001918 opacity=QuantumRange-StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001919 if (compose != DissolveCompositeOp)
1920 {
cristyb988fe72009-09-16 01:01:10 +00001921 (void) SetImageOpacity(composite_image,(Quantum)
1922 opacity);
cristy3ed852e2009-09-05 21:47:34 +00001923 break;
1924 }
1925 (void) SetImageArtifact(msl_info->image[n],
1926 "compose:args",value);
1927 if (composite_image->matte != MagickTrue)
1928 (void) SetImageOpacity(composite_image,OpaqueOpacity);
1929 composite_view=AcquireCacheView(composite_image);
1930 for (y=0; y < (long) composite_image->rows ; y++)
cristyb988fe72009-09-16 01:01:10 +00001931 {
cristy3ed852e2009-09-05 21:47:34 +00001932 q=GetCacheViewAuthenticPixels(composite_view,0,y,(long)
1933 composite_image->columns,1,&exception);
1934 for (x=0; x < (long) composite_image->columns; x++)
cristyb988fe72009-09-16 01:01:10 +00001935 {
cristy3ed852e2009-09-05 21:47:34 +00001936 if (q->opacity == OpaqueOpacity)
cristyce70c172010-01-07 17:15:30 +00001937 q->opacity=ClampToQuantum(opacity);
cristy3ed852e2009-09-05 21:47:34 +00001938 q++;
1939 }
1940 if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1941 break;
1942 }
1943 composite_view=DestroyCacheView(composite_view);
1944 break;
1945 }
1946 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1947 keyword);
1948 break;
1949 }
1950 case 'R':
1951 case 'r':
1952 {
1953 if (LocaleCompare(keyword,"rotate") == 0)
1954 {
cristyf2f27272009-12-17 14:48:46 +00001955 rotate_image=RotateImage(composite_image,StringToDouble(value),
cristy3ed852e2009-09-05 21:47:34 +00001956 &exception);
1957 break;
1958 }
1959 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1960 keyword);
1961 break;
1962 }
1963 case 'T':
1964 case 't':
1965 {
1966 if (LocaleCompare(keyword,"tile") == 0)
1967 {
1968 MagickBooleanType
1969 tile;
1970
1971 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
1972 value);
1973 if (option < 0)
1974 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1975 value);
1976 tile=(MagickBooleanType) option;
1977 if (rotate_image != (Image *) NULL)
1978 (void) SetImageArtifact(rotate_image,
1979 "compose:outside-overlay","false");
1980 else
1981 (void) SetImageArtifact(composite_image,
1982 "compose:outside-overlay","false");
1983 image=msl_info->image[n];
1984 height=composite_image->rows;
1985 width=composite_image->columns;
1986 for (y=0; y < (long) image->rows; y+=height)
1987 for (x=0; x < (long) image->columns; x+=width)
1988 {
1989 if (rotate_image != (Image *) NULL)
1990 (void) CompositeImage(image,compose,rotate_image,
1991 x,y);
1992 else
1993 (void) CompositeImage(image,compose,
1994 composite_image,x,y);
1995 }
1996 if (rotate_image != (Image *) NULL)
1997 rotate_image=DestroyImage(rotate_image);
1998 break;
1999 }
2000 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2001 keyword);
2002 break;
2003 }
2004 case 'X':
2005 case 'x':
2006 {
2007 if (LocaleCompare(keyword,"x") == 0)
2008 {
cristyf2f27272009-12-17 14:48:46 +00002009 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002010 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2011 geometry.y,&target,&exception);
2012 break;
2013 }
2014 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2015 keyword);
2016 break;
2017 }
2018 case 'Y':
2019 case 'y':
2020 {
2021 if (LocaleCompare(keyword,"y") == 0)
2022 {
cristyf2f27272009-12-17 14:48:46 +00002023 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002024 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2025 geometry.y,&target,&exception);
2026 break;
2027 }
2028 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2029 keyword);
2030 break;
2031 }
2032 default:
2033 {
2034 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2035 keyword);
2036 break;
2037 }
2038 }
2039 }
2040 image=msl_info->image[n];
2041 (void) FormatMagickString(composite_geometry,MaxTextExtent,
2042 "%lux%lu%+ld%+ld",composite_image->columns,composite_image->rows,
2043 geometry.x,geometry.y);
2044 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2045 &exception);
2046 if (rotate_image == (Image *) NULL)
2047 CompositeImageChannel(image,channel,compose,composite_image,
2048 geometry.x,geometry.y);
2049 else
2050 {
2051 /*
2052 Rotate image.
2053 */
2054 geometry.x-=(long) (rotate_image->columns-
2055 composite_image->columns)/2;
2056 geometry.y-=(long) (rotate_image->rows-composite_image->rows)/2;
2057 CompositeImageChannel(image,channel,compose,rotate_image,
2058 geometry.x,geometry.y);
2059 rotate_image=DestroyImage(rotate_image);
2060 }
2061 composite_image=DestroyImage(composite_image);
2062 break;
2063 }
cristyb988fe72009-09-16 01:01:10 +00002064 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002065 {
2066 MagickBooleanType
2067 sharpen;
2068
2069 /*
2070 Contrast image.
2071 */
2072 if (msl_info->image[n] == (Image *) NULL)
2073 {
cristyb988fe72009-09-16 01:01:10 +00002074 ThrowMSLException(OptionError,"NoImagesDefined",
2075 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002076 break;
2077 }
2078 sharpen=MagickFalse;
2079 if (attributes != (const xmlChar **) NULL)
2080 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2081 {
2082 keyword=(const char *) attributes[i++];
2083 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002084 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002085 CloneString(&value,attribute);
2086 switch (*keyword)
2087 {
2088 case 'S':
2089 case 's':
2090 {
2091 if (LocaleCompare(keyword,"sharpen") == 0)
2092 {
2093 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2094 value);
2095 if (option < 0)
2096 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2097 value);
2098 sharpen=(MagickBooleanType) option;
2099 break;
2100 }
2101 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2102 keyword);
2103 break;
2104 }
2105 default:
2106 {
2107 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2108 keyword);
2109 break;
2110 }
2111 }
2112 }
2113 (void) ContrastImage(msl_info->image[n],sharpen);
2114 break;
2115 }
cristyb988fe72009-09-16 01:01:10 +00002116 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002117 {
2118 Image
2119 *crop_image;
2120
2121 /*
2122 Crop image.
2123 */
2124 if (msl_info->image[n] == (Image *) NULL)
2125 {
cristyb988fe72009-09-16 01:01:10 +00002126 ThrowMSLException(OptionError,"NoImagesDefined",
2127 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002128 break;
2129 }
2130 SetGeometry(msl_info->image[n],&geometry);
2131 if (attributes != (const xmlChar **) NULL)
2132 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2133 {
2134 keyword=(const char *) attributes[i++];
2135 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002136 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002137 CloneString(&value,attribute);
2138 switch (*keyword)
2139 {
2140 case 'G':
2141 case 'g':
2142 {
2143 if (LocaleCompare(keyword,"geometry") == 0)
2144 {
2145 flags=ParsePageGeometry(msl_info->image[n],value,
2146 &geometry,&exception);
2147 if ((flags & HeightValue) == 0)
2148 geometry.height=geometry.width;
2149 break;
2150 }
2151 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2152 keyword);
2153 break;
2154 }
2155 case 'H':
2156 case 'h':
2157 {
2158 if (LocaleCompare(keyword,"height") == 0)
2159 {
cristyf2f27272009-12-17 14:48:46 +00002160 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002161 break;
2162 }
2163 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2164 keyword);
2165 break;
2166 }
2167 case 'W':
2168 case 'w':
2169 {
2170 if (LocaleCompare(keyword,"width") == 0)
2171 {
cristyf2f27272009-12-17 14:48:46 +00002172 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002173 break;
2174 }
2175 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2176 keyword);
2177 break;
2178 }
2179 case 'X':
2180 case 'x':
2181 {
2182 if (LocaleCompare(keyword,"x") == 0)
2183 {
cristyf2f27272009-12-17 14:48:46 +00002184 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002185 break;
2186 }
2187 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2188 keyword);
2189 break;
2190 }
2191 case 'Y':
2192 case 'y':
2193 {
2194 if (LocaleCompare(keyword,"y") == 0)
2195 {
cristyf2f27272009-12-17 14:48:46 +00002196 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002197 break;
2198 }
2199 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2200 keyword);
2201 break;
2202 }
2203 default:
2204 {
2205 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2206 keyword);
2207 break;
2208 }
2209 }
2210 }
2211 crop_image=CropImage(msl_info->image[n],&geometry,
2212 &msl_info->image[n]->exception);
2213 if (crop_image == (Image *) NULL)
2214 break;
2215 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2216 msl_info->image[n]=crop_image;
2217 break;
2218 }
cristyb988fe72009-09-16 01:01:10 +00002219 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002220 {
2221 long
2222 display;
2223
2224 /*
2225 Cycle-colormap image.
2226 */
2227 if (msl_info->image[n] == (Image *) NULL)
2228 {
cristyb988fe72009-09-16 01:01:10 +00002229 ThrowMSLException(OptionError,"NoImagesDefined",
2230 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002231 break;
2232 }
2233 display=0;
2234 if (attributes != (const xmlChar **) NULL)
2235 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2236 {
2237 keyword=(const char *) attributes[i++];
2238 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002239 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002240 CloneString(&value,attribute);
2241 switch (*keyword)
2242 {
2243 case 'D':
2244 case 'd':
2245 {
2246 if (LocaleCompare(keyword,"display") == 0)
2247 {
cristyf2f27272009-12-17 14:48:46 +00002248 display=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002249 break;
2250 }
2251 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2252 keyword);
2253 break;
2254 }
2255 default:
2256 {
2257 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2258 keyword);
2259 break;
2260 }
2261 }
2262 }
2263 (void) CycleColormapImage(msl_info->image[n],display);
2264 break;
2265 }
2266 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2267 }
2268 case 'D':
2269 case 'd':
2270 {
cristyb988fe72009-09-16 01:01:10 +00002271 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002272 {
2273 Image
2274 *despeckle_image;
2275
2276 /*
2277 Despeckle image.
2278 */
2279 if (msl_info->image[n] == (Image *) NULL)
2280 {
cristyb988fe72009-09-16 01:01:10 +00002281 ThrowMSLException(OptionError,"NoImagesDefined",
2282 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002283 break;
2284 }
2285 if (attributes != (const xmlChar **) NULL)
2286 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2287 {
2288 keyword=(const char *) attributes[i++];
2289 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002290 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002291 CloneString(&value,attribute);
2292 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2293 }
2294 despeckle_image=DespeckleImage(msl_info->image[n],
2295 &msl_info->image[n]->exception);
2296 if (despeckle_image == (Image *) NULL)
2297 break;
2298 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2299 msl_info->image[n]=despeckle_image;
2300 break;
2301 }
cristyb988fe72009-09-16 01:01:10 +00002302 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002303 {
2304 if (msl_info->image[n] == (Image *) NULL)
2305 {
cristyb988fe72009-09-16 01:01:10 +00002306 ThrowMSLException(OptionError,"NoImagesDefined",
2307 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002308 break;
2309 }
2310 if (attributes != (const xmlChar **) NULL)
2311 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2312 {
2313 keyword=(const char *) attributes[i++];
2314 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002315 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002316 CloneString(&value,attribute);
2317 switch (*keyword)
2318 {
2319 default:
2320 {
2321 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2322 keyword);
2323 break;
2324 }
2325 }
2326 }
2327 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n]);
2328 break;
2329 }
cristyb988fe72009-09-16 01:01:10 +00002330 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002331 {
2332 char
2333 text[MaxTextExtent];
2334
2335 /*
2336 Annotate image.
2337 */
2338 if (msl_info->image[n] == (Image *) NULL)
2339 {
cristyb988fe72009-09-16 01:01:10 +00002340 ThrowMSLException(OptionError,"NoImagesDefined",
2341 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002342 break;
2343 }
2344 draw_info=CloneDrawInfo(msl_info->image_info[n],
2345 msl_info->draw_info[n]);
2346 angle=0.0;
2347 current=draw_info->affine;
2348 GetAffineMatrix(&affine);
2349 if (attributes != (const xmlChar **) NULL)
2350 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2351 {
2352 keyword=(const char *) attributes[i++];
2353 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002354 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002355 CloneString(&value,attribute);
2356 switch (*keyword)
2357 {
2358 case 'A':
2359 case 'a':
2360 {
2361 if (LocaleCompare(keyword,"affine") == 0)
2362 {
2363 char
2364 *p;
2365
2366 p=value;
2367 draw_info->affine.sx=strtod(p,&p);
2368 if (*p ==',')
2369 p++;
2370 draw_info->affine.rx=strtod(p,&p);
2371 if (*p ==',')
2372 p++;
2373 draw_info->affine.ry=strtod(p,&p);
2374 if (*p ==',')
2375 p++;
2376 draw_info->affine.sy=strtod(p,&p);
2377 if (*p ==',')
2378 p++;
2379 draw_info->affine.tx=strtod(p,&p);
2380 if (*p ==',')
2381 p++;
2382 draw_info->affine.ty=strtod(p,&p);
2383 break;
2384 }
2385 if (LocaleCompare(keyword,"align") == 0)
2386 {
2387 option=ParseMagickOption(MagickAlignOptions,MagickFalse,
2388 value);
2389 if (option < 0)
2390 ThrowMSLException(OptionError,"UnrecognizedAlignType",
2391 value);
2392 draw_info->align=(AlignType) option;
2393 break;
2394 }
2395 if (LocaleCompare(keyword,"antialias") == 0)
2396 {
2397 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2398 value);
2399 if (option < 0)
2400 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2401 value);
2402 draw_info->stroke_antialias=(MagickBooleanType) option;
2403 draw_info->text_antialias=(MagickBooleanType) option;
2404 break;
2405 }
2406 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2407 keyword);
2408 break;
2409 }
2410 case 'D':
2411 case 'd':
2412 {
2413 if (LocaleCompare(keyword,"density") == 0)
2414 {
2415 CloneString(&draw_info->density,value);
2416 break;
2417 }
2418 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2419 keyword);
2420 break;
2421 }
2422 case 'E':
2423 case 'e':
2424 {
2425 if (LocaleCompare(keyword,"encoding") == 0)
2426 {
2427 CloneString(&draw_info->encoding,value);
2428 break;
2429 }
2430 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2431 keyword);
2432 break;
2433 }
2434 case 'F':
2435 case 'f':
2436 {
2437 if (LocaleCompare(keyword, "fill") == 0)
2438 {
2439 (void) QueryColorDatabase(value,&draw_info->fill,
2440 &exception);
2441 break;
2442 }
2443 if (LocaleCompare(keyword,"family") == 0)
2444 {
2445 CloneString(&draw_info->family,value);
2446 break;
2447 }
2448 if (LocaleCompare(keyword,"font") == 0)
2449 {
2450 CloneString(&draw_info->font,value);
2451 break;
2452 }
2453 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2454 keyword);
2455 break;
2456 }
2457 case 'G':
2458 case 'g':
2459 {
2460 if (LocaleCompare(keyword,"geometry") == 0)
2461 {
2462 flags=ParsePageGeometry(msl_info->image[n],value,
2463 &geometry,&exception);
2464 if ((flags & HeightValue) == 0)
2465 geometry.height=geometry.width;
2466 break;
2467 }
2468 if (LocaleCompare(keyword,"gravity") == 0)
2469 {
2470 option=ParseMagickOption(MagickGravityOptions,MagickFalse,
2471 value);
2472 if (option < 0)
2473 ThrowMSLException(OptionError,"UnrecognizedGravityType",
2474 value);
2475 draw_info->gravity=(GravityType) option;
2476 break;
2477 }
2478 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2479 keyword);
2480 break;
2481 }
2482 case 'P':
2483 case 'p':
2484 {
2485 if (LocaleCompare(keyword,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002486 {
cristy3ed852e2009-09-05 21:47:34 +00002487 CloneString(&draw_info->primitive,value);
2488 break;
2489 }
2490 if (LocaleCompare(keyword,"pointsize") == 0)
2491 {
cristyf2f27272009-12-17 14:48:46 +00002492 draw_info->pointsize=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002493 break;
2494 }
2495 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2496 keyword);
2497 break;
2498 }
2499 case 'R':
2500 case 'r':
2501 {
2502 if (LocaleCompare(keyword,"rotate") == 0)
2503 {
cristyf2f27272009-12-17 14:48:46 +00002504 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002505 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2506 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2507 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2508 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2509 break;
2510 }
2511 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2512 keyword);
2513 break;
2514 }
2515 case 'S':
2516 case 's':
2517 {
2518 if (LocaleCompare(keyword,"scale") == 0)
2519 {
2520 flags=ParseGeometry(value,&geometry_info);
2521 if ((flags & SigmaValue) == 0)
2522 geometry_info.sigma=1.0;
2523 affine.sx=geometry_info.rho;
2524 affine.sy=geometry_info.sigma;
2525 break;
2526 }
2527 if (LocaleCompare(keyword,"skewX") == 0)
2528 {
cristyf2f27272009-12-17 14:48:46 +00002529 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002530 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2531 break;
2532 }
2533 if (LocaleCompare(keyword,"skewY") == 0)
2534 {
cristyf2f27272009-12-17 14:48:46 +00002535 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002536 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2537 break;
2538 }
2539 if (LocaleCompare(keyword,"stretch") == 0)
2540 {
2541 option=ParseMagickOption(MagickStretchOptions,MagickFalse,
2542 value);
2543 if (option < 0)
2544 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2545 value);
2546 draw_info->stretch=(StretchType) option;
2547 break;
2548 }
2549 if (LocaleCompare(keyword, "stroke") == 0)
2550 {
2551 (void) QueryColorDatabase(value,&draw_info->stroke,
2552 &exception);
2553 break;
2554 }
2555 if (LocaleCompare(keyword,"strokewidth") == 0)
2556 {
cristyf2f27272009-12-17 14:48:46 +00002557 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002558 break;
2559 }
2560 if (LocaleCompare(keyword,"style") == 0)
2561 {
2562 option=ParseMagickOption(MagickStyleOptions,MagickFalse,
2563 value);
2564 if (option < 0)
2565 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2566 value);
2567 draw_info->style=(StyleType) option;
2568 break;
2569 }
2570 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2571 keyword);
2572 break;
2573 }
2574 case 'T':
2575 case 't':
2576 {
2577 if (LocaleCompare(keyword,"text") == 0)
2578 {
2579 CloneString(&draw_info->text,value);
2580 break;
2581 }
2582 if (LocaleCompare(keyword,"translate") == 0)
2583 {
2584 flags=ParseGeometry(value,&geometry_info);
2585 if ((flags & SigmaValue) == 0)
2586 geometry_info.sigma=1.0;
2587 affine.tx=geometry_info.rho;
2588 affine.ty=geometry_info.sigma;
2589 break;
2590 }
2591 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2592 keyword);
2593 break;
2594 }
2595 case 'U':
2596 case 'u':
2597 {
2598 if (LocaleCompare(keyword, "undercolor") == 0)
2599 {
2600 (void) QueryColorDatabase(value,&draw_info->undercolor,
2601 &exception);
2602 break;
2603 }
2604 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2605 keyword);
2606 break;
2607 }
2608 case 'W':
2609 case 'w':
2610 {
2611 if (LocaleCompare(keyword,"weight") == 0)
2612 {
cristyf2f27272009-12-17 14:48:46 +00002613 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002614 break;
2615 }
2616 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2617 keyword);
2618 break;
2619 }
2620 case 'X':
2621 case 'x':
2622 {
2623 if (LocaleCompare(keyword,"x") == 0)
2624 {
cristyf2f27272009-12-17 14:48:46 +00002625 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002626 break;
2627 }
2628 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2629 keyword);
2630 break;
2631 }
2632 case 'Y':
2633 case 'y':
2634 {
2635 if (LocaleCompare(keyword,"y") == 0)
2636 {
cristyf2f27272009-12-17 14:48:46 +00002637 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002638 break;
2639 }
2640 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2641 keyword);
2642 break;
2643 }
2644 default:
2645 {
2646 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2647 keyword);
2648 break;
2649 }
2650 }
2651 }
2652 (void) FormatMagickString(text,MaxTextExtent,"%lux%lu%+ld%+ld",
2653 geometry.width,geometry.height,geometry.x,geometry.y);
2654 CloneString(&draw_info->geometry,text);
2655 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
2656 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
2657 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
2658 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
2659 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
2660 current.tx;
2661 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
2662 current.ty;
2663 (void) DrawImage(msl_info->image[n],draw_info);
2664 draw_info=DestroyDrawInfo(draw_info);
2665 break;
2666 }
2667 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2668 }
2669 case 'E':
2670 case 'e':
2671 {
cristyb988fe72009-09-16 01:01:10 +00002672 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002673 {
2674 Image
2675 *edge_image;
2676
2677 /*
2678 Edge image.
2679 */
2680 if (msl_info->image[n] == (Image *) NULL)
2681 {
cristyb988fe72009-09-16 01:01:10 +00002682 ThrowMSLException(OptionError,"NoImagesDefined",
2683 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002684 break;
2685 }
2686 if (attributes != (const xmlChar **) NULL)
2687 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2688 {
2689 keyword=(const char *) attributes[i++];
2690 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002691 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002692 CloneString(&value,attribute);
2693 switch (*keyword)
2694 {
2695 case 'G':
2696 case 'g':
2697 {
2698 if (LocaleCompare(keyword,"geometry") == 0)
2699 {
2700 flags=ParseGeometry(value,&geometry_info);
2701 if ((flags & SigmaValue) == 0)
2702 geometry_info.sigma=1.0;
2703 break;
2704 }
2705 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2706 keyword);
2707 break;
2708 }
2709 case 'R':
2710 case 'r':
2711 {
2712 if (LocaleCompare(keyword,"radius") == 0)
2713 {
cristyf2f27272009-12-17 14:48:46 +00002714 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002715 break;
2716 }
2717 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2718 keyword);
2719 break;
2720 }
2721 default:
2722 {
2723 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2724 keyword);
2725 break;
2726 }
2727 }
2728 }
2729 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
2730 &msl_info->image[n]->exception);
2731 if (edge_image == (Image *) NULL)
2732 break;
2733 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2734 msl_info->image[n]=edge_image;
2735 break;
2736 }
cristyb988fe72009-09-16 01:01:10 +00002737 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002738 {
2739 Image
2740 *emboss_image;
2741
2742 /*
2743 Emboss image.
2744 */
2745 if (msl_info->image[n] == (Image *) NULL)
2746 {
cristyb988fe72009-09-16 01:01:10 +00002747 ThrowMSLException(OptionError,"NoImagesDefined",
2748 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002749 break;
2750 }
2751 if (attributes != (const xmlChar **) NULL)
2752 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2753 {
2754 keyword=(const char *) attributes[i++];
2755 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002756 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002757 CloneString(&value,attribute);
2758 switch (*keyword)
2759 {
2760 case 'G':
2761 case 'g':
2762 {
2763 if (LocaleCompare(keyword,"geometry") == 0)
2764 {
2765 flags=ParseGeometry(value,&geometry_info);
2766 if ((flags & SigmaValue) == 0)
2767 geometry_info.sigma=1.0;
2768 break;
2769 }
2770 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2771 keyword);
2772 break;
2773 }
2774 case 'R':
2775 case 'r':
2776 {
2777 if (LocaleCompare(keyword,"radius") == 0)
2778 {
cristyf2f27272009-12-17 14:48:46 +00002779 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00002780 break;
2781 }
2782 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2783 keyword);
2784 break;
2785 }
2786 case 'S':
2787 case 's':
2788 {
2789 if (LocaleCompare(keyword,"sigma") == 0)
2790 {
cristyf2f27272009-12-17 14:48:46 +00002791 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002792 break;
2793 }
2794 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2795 keyword);
2796 break;
2797 }
2798 default:
2799 {
2800 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2801 keyword);
2802 break;
2803 }
2804 }
2805 }
2806 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2807 geometry_info.sigma,&msl_info->image[n]->exception);
2808 if (emboss_image == (Image *) NULL)
2809 break;
2810 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2811 msl_info->image[n]=emboss_image;
2812 break;
2813 }
cristyb988fe72009-09-16 01:01:10 +00002814 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002815 {
2816 Image
2817 *enhance_image;
2818
2819 /*
2820 Enhance image.
2821 */
2822 if (msl_info->image[n] == (Image *) NULL)
2823 {
cristyb988fe72009-09-16 01:01:10 +00002824 ThrowMSLException(OptionError,"NoImagesDefined",
2825 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002826 break;
2827 }
2828 if (attributes != (const xmlChar **) NULL)
2829 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2830 {
2831 keyword=(const char *) attributes[i++];
2832 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002833 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002834 CloneString(&value,attribute);
2835 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2836 }
2837 enhance_image=EnhanceImage(msl_info->image[n],
2838 &msl_info->image[n]->exception);
2839 if (enhance_image == (Image *) NULL)
2840 break;
2841 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2842 msl_info->image[n]=enhance_image;
2843 break;
2844 }
cristyb988fe72009-09-16 01:01:10 +00002845 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002846 {
2847 /*
2848 Equalize image.
2849 */
2850 if (msl_info->image[n] == (Image *) NULL)
2851 {
cristyb988fe72009-09-16 01:01:10 +00002852 ThrowMSLException(OptionError,"NoImagesDefined",
2853 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002854 break;
2855 }
2856 if (attributes != (const xmlChar **) NULL)
2857 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2858 {
2859 keyword=(const char *) attributes[i++];
2860 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002861 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002862 CloneString(&value,attribute);
2863 switch (*keyword)
2864 {
2865 default:
2866 {
2867 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2868 keyword);
2869 break;
2870 }
2871 }
2872 }
2873 (void) EqualizeImage(msl_info->image[n]);
2874 break;
2875 }
2876 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2877 }
2878 case 'F':
2879 case 'f':
2880 {
cristyb988fe72009-09-16 01:01:10 +00002881 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002882 {
2883 if (msl_info->image[n] == (Image *) NULL)
2884 {
cristyb988fe72009-09-16 01:01:10 +00002885 ThrowMSLException(OptionError,"NoImagesDefined",
2886 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002887 break;
2888 }
2889
2890 /* no attributes here */
2891
2892 /* process the image */
2893 {
2894 Image
2895 *newImage;
2896
2897 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2898 &msl_info->image[n]->exception);
2899 if (newImage == (Image *) NULL)
2900 break;
2901 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2902 msl_info->image[n]=newImage;
2903 break;
2904 }
2905 }
cristyb988fe72009-09-16 01:01:10 +00002906 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002907 {
2908 Image
2909 *flip_image;
2910
2911 /*
2912 Flip image.
2913 */
2914 if (msl_info->image[n] == (Image *) NULL)
2915 {
cristyb988fe72009-09-16 01:01:10 +00002916 ThrowMSLException(OptionError,"NoImagesDefined",
2917 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002918 break;
2919 }
2920 if (attributes != (const xmlChar **) NULL)
2921 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2922 {
2923 keyword=(const char *) attributes[i++];
2924 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002925 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002926 CloneString(&value,attribute);
2927 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2928 }
2929 flip_image=FlipImage(msl_info->image[n],
2930 &msl_info->image[n]->exception);
2931 if (flip_image == (Image *) NULL)
2932 break;
2933 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2934 msl_info->image[n]=flip_image;
2935 break;
2936 }
cristyb988fe72009-09-16 01:01:10 +00002937 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002938 {
2939 Image
2940 *flop_image;
2941
2942 /*
2943 Flop image.
2944 */
2945 if (msl_info->image[n] == (Image *) NULL)
2946 {
cristyb988fe72009-09-16 01:01:10 +00002947 ThrowMSLException(OptionError,"NoImagesDefined",
2948 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002949 break;
2950 }
2951 if (attributes != (const xmlChar **) NULL)
2952 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2953 {
2954 keyword=(const char *) attributes[i++];
2955 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002956 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002957 CloneString(&value,attribute);
2958 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2959 }
2960 flop_image=FlopImage(msl_info->image[n],
2961 &msl_info->image[n]->exception);
2962 if (flop_image == (Image *) NULL)
2963 break;
2964 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2965 msl_info->image[n]=flop_image;
2966 break;
2967 }
cristyb988fe72009-09-16 01:01:10 +00002968 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002969 {
2970 FrameInfo
2971 frame_info;
2972
2973 Image
2974 *frame_image;
2975
2976 /*
2977 Frame image.
2978 */
2979 if (msl_info->image[n] == (Image *) NULL)
2980 {
cristyb988fe72009-09-16 01:01:10 +00002981 ThrowMSLException(OptionError,"NoImagesDefined",
2982 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002983 break;
2984 }
2985 SetGeometry(msl_info->image[n],&geometry);
2986 if (attributes != (const xmlChar **) NULL)
2987 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2988 {
2989 keyword=(const char *) attributes[i++];
2990 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002991 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002992 CloneString(&value,attribute);
2993 switch (*keyword)
2994 {
2995 case 'C':
2996 case 'c':
2997 {
2998 if (LocaleCompare(keyword,"compose") == 0)
2999 {
3000 option=ParseMagickOption(MagickComposeOptions,
3001 MagickFalse,value);
3002 if (option < 0)
3003 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3004 value);
3005 msl_info->image[n]->compose=(CompositeOperator) option;
3006 break;
3007 }
3008 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3009 keyword);
3010 break;
3011 }
3012 case 'F':
3013 case 'f':
3014 {
3015 if (LocaleCompare(keyword, "fill") == 0)
3016 {
3017 (void) QueryColorDatabase(value,
3018 &msl_info->image[n]->matte_color,&exception);
3019 break;
3020 }
3021 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3022 keyword);
3023 break;
3024 }
3025 case 'G':
3026 case 'g':
3027 {
3028 if (LocaleCompare(keyword,"geometry") == 0)
3029 {
3030 flags=ParsePageGeometry(msl_info->image[n],value,
3031 &geometry,&exception);
3032 if ((flags & HeightValue) == 0)
3033 geometry.height=geometry.width;
3034 frame_info.width=geometry.width;
3035 frame_info.height=geometry.height;
3036 frame_info.outer_bevel=geometry.x;
3037 frame_info.inner_bevel=geometry.y;
3038 break;
3039 }
3040 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3041 keyword);
3042 break;
3043 }
3044 case 'H':
3045 case 'h':
3046 {
3047 if (LocaleCompare(keyword,"height") == 0)
3048 {
cristyf2f27272009-12-17 14:48:46 +00003049 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003050 break;
3051 }
3052 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3053 keyword);
3054 break;
3055 }
3056 case 'I':
3057 case 'i':
3058 {
3059 if (LocaleCompare(keyword,"inner") == 0)
3060 {
cristyf2f27272009-12-17 14:48:46 +00003061 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003062 break;
3063 }
3064 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3065 keyword);
3066 break;
3067 }
3068 case 'O':
3069 case 'o':
3070 {
3071 if (LocaleCompare(keyword,"outer") == 0)
3072 {
cristyf2f27272009-12-17 14:48:46 +00003073 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003074 break;
3075 }
3076 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3077 keyword);
3078 break;
3079 }
3080 case 'W':
3081 case 'w':
3082 {
3083 if (LocaleCompare(keyword,"width") == 0)
3084 {
cristyf2f27272009-12-17 14:48:46 +00003085 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003086 break;
3087 }
3088 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3089 keyword);
3090 break;
3091 }
3092 default:
3093 {
3094 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3095 keyword);
3096 break;
3097 }
3098 }
3099 }
3100 frame_info.x=(long) frame_info.width;
3101 frame_info.y=(long) frame_info.height;
3102 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3103 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3104 frame_image=FrameImage(msl_info->image[n],&frame_info,
3105 &msl_info->image[n]->exception);
3106 if (frame_image == (Image *) NULL)
3107 break;
3108 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3109 msl_info->image[n]=frame_image;
3110 break;
3111 }
3112 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3113 }
3114 case 'G':
3115 case 'g':
3116 {
cristyb988fe72009-09-16 01:01:10 +00003117 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003118 {
3119 char
3120 gamma[MaxTextExtent];
3121
3122 MagickPixelPacket
3123 pixel;
3124
3125 /*
3126 Gamma image.
3127 */
3128 if (msl_info->image[n] == (Image *) NULL)
3129 {
cristyb988fe72009-09-16 01:01:10 +00003130 ThrowMSLException(OptionError,"NoImagesDefined",
3131 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003132 break;
3133 }
3134 channel=UndefinedChannel;
3135 pixel.red=0.0;
3136 pixel.green=0.0;
3137 pixel.blue=0.0;
3138 *gamma='\0';
3139 if (attributes != (const xmlChar **) NULL)
3140 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3141 {
3142 keyword=(const char *) attributes[i++];
3143 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003144 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003145 CloneString(&value,attribute);
3146 switch (*keyword)
3147 {
3148 case 'B':
3149 case 'b':
3150 {
3151 if (LocaleCompare(keyword,"blue") == 0)
3152 {
cristyf2f27272009-12-17 14:48:46 +00003153 pixel.blue=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003154 break;
3155 }
3156 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3157 keyword);
3158 break;
3159 }
3160 case 'C':
3161 case 'c':
3162 {
3163 if (LocaleCompare(keyword,"channel") == 0)
3164 {
3165 option=ParseChannelOption(value);
3166 if (option < 0)
3167 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3168 value);
3169 channel=(ChannelType) option;
3170 break;
3171 }
3172 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3173 keyword);
3174 break;
3175 }
3176 case 'G':
3177 case 'g':
3178 {
3179 if (LocaleCompare(keyword,"gamma") == 0)
3180 {
3181 (void) CopyMagickString(gamma,value,MaxTextExtent);
3182 break;
3183 }
3184 if (LocaleCompare(keyword,"green") == 0)
3185 {
cristyf2f27272009-12-17 14:48:46 +00003186 pixel.green=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003187 break;
3188 }
3189 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3190 keyword);
3191 break;
3192 }
3193 case 'R':
3194 case 'r':
3195 {
3196 if (LocaleCompare(keyword,"red") == 0)
3197 {
cristyf2f27272009-12-17 14:48:46 +00003198 pixel.red=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003199 break;
3200 }
3201 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3202 keyword);
3203 break;
3204 }
3205 default:
3206 {
3207 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3208 keyword);
3209 break;
3210 }
3211 }
3212 }
3213 if (*gamma == '\0')
cristye7f51092010-01-17 00:39:37 +00003214 (void) FormatMagickString(gamma,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003215 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb988fe72009-09-16 01:01:10 +00003216 switch (channel)
cristy3ed852e2009-09-05 21:47:34 +00003217 {
3218 default:
3219 {
3220 (void) GammaImage(msl_info->image[n],gamma);
3221 break;
3222 }
3223 case RedChannel:
3224 {
3225 (void) GammaImageChannel(msl_info->image[n],RedChannel,pixel.red);
3226 break;
3227 }
3228 case GreenChannel:
3229 {
3230 (void) GammaImageChannel(msl_info->image[n],GreenChannel,
3231 pixel.green);
3232 break;
3233 }
3234 case BlueChannel:
3235 {
3236 (void) GammaImageChannel(msl_info->image[n],BlueChannel,
3237 pixel.blue);
3238 break;
3239 }
3240 }
3241 break;
3242 }
cristyb988fe72009-09-16 01:01:10 +00003243 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003244 {
3245 if (msl_info->image[n] == (Image *) NULL)
3246 {
cristyb988fe72009-09-16 01:01:10 +00003247 ThrowMSLException(OptionError,"NoImagesDefined",
3248 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003249 break;
3250 }
3251 if (attributes == (const xmlChar **) NULL)
3252 break;
3253 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3254 {
3255 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003256 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003257 (void) CopyMagickString(key,value,MaxTextExtent);
3258 switch (*keyword)
3259 {
3260 case 'H':
3261 case 'h':
3262 {
3263 if (LocaleCompare(keyword,"height") == 0)
3264 {
3265 (void) FormatMagickString(value,MaxTextExtent,"%ld",
3266 msl_info->image[n]->rows);
3267 (void) SetImageProperty(msl_info->attributes[n],key,value);
3268 break;
3269 }
3270 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3271 }
3272 case 'W':
3273 case 'w':
3274 {
3275 if (LocaleCompare(keyword,"width") == 0)
3276 {
3277 (void) FormatMagickString(value,MaxTextExtent,"%ld",
3278 msl_info->image[n]->columns);
3279 (void) SetImageProperty(msl_info->attributes[n],key,value);
3280 break;
3281 }
3282 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3283 }
3284 default:
3285 {
3286 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3287 break;
3288 }
3289 }
3290 }
3291 break;
3292 }
cristyb988fe72009-09-16 01:01:10 +00003293 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003294 {
3295 msl_info->number_groups++;
3296 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3297 msl_info->group_info,msl_info->number_groups+1UL,
3298 sizeof(*msl_info->group_info));
3299 break;
3300 }
3301 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3302 }
3303 case 'I':
3304 case 'i':
3305 {
cristyb988fe72009-09-16 01:01:10 +00003306 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003307 {
cristy3ed852e2009-09-05 21:47:34 +00003308 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003309 if (attributes == (const xmlChar **) NULL)
3310 break;
3311 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3312 {
3313 keyword=(const char *) attributes[i++];
3314 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003315 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00003316 switch (*keyword)
3317 {
cristyb988fe72009-09-16 01:01:10 +00003318 case 'C':
3319 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003320 {
cristyb988fe72009-09-16 01:01:10 +00003321 if (LocaleCompare(keyword,"color") == 0)
3322 {
3323 Image
3324 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003325
cristyb988fe72009-09-16 01:01:10 +00003326 (void) CopyMagickString(msl_info->image_info[n]->filename,
3327 "xc:",MaxTextExtent);
3328 (void) ConcatenateMagickString(msl_info->image_info[n]->
3329 filename,value,MaxTextExtent);
3330 next_image=ReadImage(msl_info->image_info[n],&exception);
3331 CatchException(&exception);
3332 if (next_image == (Image *) NULL)
3333 continue;
3334 if (msl_info->image[n] == (Image *) NULL)
3335 msl_info->image[n]=next_image;
3336 else
3337 {
3338 register Image
3339 *p;
cristy3ed852e2009-09-05 21:47:34 +00003340
cristyb988fe72009-09-16 01:01:10 +00003341 /*
3342 Link image into image list.
3343 */
3344 p=msl_info->image[n];
3345 while (p->next != (Image *) NULL)
3346 p=GetNextImageInList(p);
3347 next_image->previous=p;
3348 p->next=next_image;
3349 }
3350 break;
3351 }
cristyb20775d2009-09-16 01:51:41 +00003352 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003353 break;
3354 }
3355 default:
3356 {
cristyb20775d2009-09-16 01:51:41 +00003357 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003358 break;
3359 }
3360 }
3361 }
3362 break;
3363 }
cristyb988fe72009-09-16 01:01:10 +00003364 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003365 {
3366 Image
3367 *implode_image;
3368
3369 /*
3370 Implode image.
3371 */
3372 if (msl_info->image[n] == (Image *) NULL)
3373 {
cristyb988fe72009-09-16 01:01:10 +00003374 ThrowMSLException(OptionError,"NoImagesDefined",
3375 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003376 break;
3377 }
3378 if (attributes != (const xmlChar **) NULL)
3379 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3380 {
3381 keyword=(const char *) attributes[i++];
3382 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003383 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003384 CloneString(&value,attribute);
3385 switch (*keyword)
3386 {
3387 case 'A':
3388 case 'a':
3389 {
3390 if (LocaleCompare(keyword,"amount") == 0)
3391 {
cristyf2f27272009-12-17 14:48:46 +00003392 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003393 break;
3394 }
3395 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3396 keyword);
3397 break;
3398 }
3399 case 'G':
3400 case 'g':
3401 {
3402 if (LocaleCompare(keyword,"geometry") == 0)
3403 {
3404 flags=ParseGeometry(value,&geometry_info);
3405 if ((flags & SigmaValue) == 0)
3406 geometry_info.sigma=1.0;
3407 break;
3408 }
3409 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3410 keyword);
3411 break;
3412 }
3413 default:
3414 {
3415 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3416 keyword);
3417 break;
3418 }
3419 }
3420 }
3421 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3422 &msl_info->image[n]->exception);
3423 if (implode_image == (Image *) NULL)
3424 break;
3425 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3426 msl_info->image[n]=implode_image;
3427 break;
3428 }
3429 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3430 }
3431 case 'L':
3432 case 'l':
3433 {
cristyb988fe72009-09-16 01:01:10 +00003434 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003435 break;
cristyb988fe72009-09-16 01:01:10 +00003436 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003437 {
3438 double
3439 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3440
3441 if (msl_info->image[n] == (Image *) NULL)
3442 {
cristyb988fe72009-09-16 01:01:10 +00003443 ThrowMSLException(OptionError,"NoImagesDefined",
3444 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003445 break;
3446 }
3447 if (attributes == (const xmlChar **) NULL)
3448 break;
3449 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3450 {
3451 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003452 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003453 (void) CopyMagickString(key,value,MaxTextExtent);
3454 switch (*keyword)
3455 {
3456 case 'B':
3457 case 'b':
3458 {
3459 if (LocaleCompare(keyword,"black") == 0)
3460 {
cristyf2f27272009-12-17 14:48:46 +00003461 levelBlack = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00003462 break;
3463 }
3464 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3465 break;
3466 }
3467 case 'G':
3468 case 'g':
3469 {
3470 if (LocaleCompare(keyword,"gamma") == 0)
3471 {
cristyf2f27272009-12-17 14:48:46 +00003472 levelGamma = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00003473 break;
3474 }
3475 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3476 break;
3477 }
3478 case 'W':
3479 case 'w':
3480 {
3481 if (LocaleCompare(keyword,"white") == 0)
3482 {
cristyf2f27272009-12-17 14:48:46 +00003483 levelWhite = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00003484 break;
3485 }
3486 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3487 break;
3488 }
3489 default:
3490 {
3491 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3492 break;
3493 }
3494 }
3495 }
3496
3497 /* process image */
3498 {
3499 char level[MaxTextExtent + 1];
3500 (void) FormatMagickString(level,MaxTextExtent,"%3.6f/%3.6f/%3.6f/",
3501 levelBlack,levelGamma,levelWhite);
3502 LevelImage ( msl_info->image[n], level );
3503 break;
3504 }
3505 }
3506 }
3507 case 'M':
3508 case 'm':
3509 {
cristyb988fe72009-09-16 01:01:10 +00003510 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003511 {
3512 Image
3513 *magnify_image;
3514
3515 /*
3516 Magnify image.
3517 */
3518 if (msl_info->image[n] == (Image *) NULL)
3519 {
cristyb988fe72009-09-16 01:01:10 +00003520 ThrowMSLException(OptionError,"NoImagesDefined",
3521 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003522 break;
3523 }
3524 if (attributes != (const xmlChar **) NULL)
3525 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3526 {
3527 keyword=(const char *) attributes[i++];
3528 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003529 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003530 CloneString(&value,attribute);
3531 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3532 }
3533 magnify_image=MagnifyImage(msl_info->image[n],
3534 &msl_info->image[n]->exception);
3535 if (magnify_image == (Image *) NULL)
3536 break;
3537 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3538 msl_info->image[n]=magnify_image;
3539 break;
3540 }
cristyb988fe72009-09-16 01:01:10 +00003541 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003542 {
3543 Image
3544 *affinity_image;
3545
3546 MagickBooleanType
3547 dither;
3548
3549 QuantizeInfo
3550 *quantize_info;
3551
3552 /*
3553 Map image.
3554 */
3555 if (msl_info->image[n] == (Image *) NULL)
3556 {
cristyb988fe72009-09-16 01:01:10 +00003557 ThrowMSLException(OptionError,"NoImagesDefined",
3558 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003559 break;
3560 }
3561 affinity_image=NewImageList();
3562 dither=MagickFalse;
3563 if (attributes != (const xmlChar **) NULL)
3564 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3565 {
3566 keyword=(const char *) attributes[i++];
3567 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003568 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003569 CloneString(&value,attribute);
3570 switch (*keyword)
3571 {
3572 case 'D':
3573 case 'd':
3574 {
3575 if (LocaleCompare(keyword,"dither") == 0)
3576 {
3577 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
3578 value);
3579 if (option < 0)
3580 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3581 value);
3582 dither=(MagickBooleanType) option;
3583 break;
3584 }
3585 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3586 keyword);
3587 break;
3588 }
3589 case 'I':
3590 case 'i':
3591 {
3592 if (LocaleCompare(keyword,"image") == 0)
3593 for (j=0; j < msl_info->n; j++)
3594 {
3595 const char
3596 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003597
cristy3ed852e2009-09-05 21:47:34 +00003598 attribute=GetImageProperty(msl_info->attributes[j],"id");
3599 if ((attribute != (const char *) NULL) &&
3600 (LocaleCompare(attribute,value) == 0))
3601 {
3602 affinity_image=CloneImage(msl_info->image[j],0,0,
3603 MagickFalse,&exception);
3604 break;
3605 }
3606 }
3607 break;
3608 }
3609 default:
3610 {
3611 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3612 keyword);
3613 break;
3614 }
3615 }
3616 }
3617 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3618 quantize_info->dither=dither;
3619 (void) RemapImages(quantize_info,msl_info->image[n],
3620 affinity_image);
3621 quantize_info=DestroyQuantizeInfo(quantize_info);
3622 affinity_image=DestroyImage(affinity_image);
3623 break;
3624 }
cristyb988fe72009-09-16 01:01:10 +00003625 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003626 {
3627 double
3628 opacity;
3629
3630 MagickPixelPacket
3631 target;
3632
3633 PaintMethod
3634 paint_method;
3635
3636 /*
3637 Matte floodfill image.
3638 */
3639 opacity=0.0;
3640 if (msl_info->image[n] == (Image *) NULL)
3641 {
cristyb988fe72009-09-16 01:01:10 +00003642 ThrowMSLException(OptionError,"NoImagesDefined",
3643 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003644 break;
3645 }
3646 SetGeometry(msl_info->image[n],&geometry);
3647 paint_method=FloodfillMethod;
3648 if (attributes != (const xmlChar **) NULL)
3649 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3650 {
3651 keyword=(const char *) attributes[i++];
3652 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003653 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003654 CloneString(&value,attribute);
3655 switch (*keyword)
3656 {
3657 case 'B':
3658 case 'b':
3659 {
3660 if (LocaleCompare(keyword,"bordercolor") == 0)
3661 {
3662 (void) QueryMagickColor(value,&target,&exception);
3663 paint_method=FillToBorderMethod;
3664 break;
3665 }
3666 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3667 keyword);
3668 break;
3669 }
3670 case 'F':
3671 case 'f':
3672 {
3673 if (LocaleCompare(keyword,"fuzz") == 0)
3674 {
cristyf2f27272009-12-17 14:48:46 +00003675 msl_info->image[n]->fuzz=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003676 break;
3677 }
3678 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3679 keyword);
3680 break;
3681 }
3682 case 'G':
3683 case 'g':
3684 {
3685 if (LocaleCompare(keyword,"geometry") == 0)
3686 {
3687 flags=ParsePageGeometry(msl_info->image[n],value,
3688 &geometry,&exception);
3689 if ((flags & HeightValue) == 0)
3690 geometry.height=geometry.width;
3691 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3692 geometry.x,geometry.y,&target,&exception);
3693 break;
3694 }
3695 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3696 keyword);
3697 break;
3698 }
3699 case 'O':
3700 case 'o':
3701 {
3702 if (LocaleCompare(keyword,"opacity") == 0)
3703 {
cristyf2f27272009-12-17 14:48:46 +00003704 opacity=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003705 break;
3706 }
3707 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3708 keyword);
3709 break;
3710 }
3711 case 'X':
3712 case 'x':
3713 {
3714 if (LocaleCompare(keyword,"x") == 0)
3715 {
cristyf2f27272009-12-17 14:48:46 +00003716 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003717 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3718 geometry.x,geometry.y,&target,&exception);
3719 break;
3720 }
3721 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3722 keyword);
3723 break;
3724 }
3725 case 'Y':
3726 case 'y':
3727 {
3728 if (LocaleCompare(keyword,"y") == 0)
3729 {
cristyf2f27272009-12-17 14:48:46 +00003730 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003731 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3732 geometry.x,geometry.y,&target,&exception);
3733 break;
3734 }
3735 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3736 keyword);
3737 break;
3738 }
3739 default:
3740 {
3741 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3742 keyword);
3743 break;
3744 }
3745 }
3746 }
3747 draw_info=CloneDrawInfo(msl_info->image_info[n],
3748 msl_info->draw_info[n]);
cristyce70c172010-01-07 17:15:30 +00003749 draw_info->fill.opacity=ClampToQuantum(opacity);
cristy3ed852e2009-09-05 21:47:34 +00003750 (void) FloodfillPaintImage(msl_info->image[n],OpacityChannel,
3751 draw_info,&target,geometry.x,geometry.y,
3752 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
3753 draw_info=DestroyDrawInfo(draw_info);
3754 break;
3755 }
cristyb988fe72009-09-16 01:01:10 +00003756 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003757 {
3758 Image
3759 *median_image;
3760
3761 /*
3762 Median-filter image.
3763 */
3764 if (msl_info->image[n] == (Image *) NULL)
3765 {
cristyb988fe72009-09-16 01:01:10 +00003766 ThrowMSLException(OptionError,"NoImagesDefined",
3767 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003768 break;
3769 }
3770 if (attributes != (const xmlChar **) NULL)
3771 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3772 {
3773 keyword=(const char *) attributes[i++];
3774 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003775 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003776 CloneString(&value,attribute);
3777 switch (*keyword)
3778 {
3779 case 'G':
3780 case 'g':
3781 {
3782 if (LocaleCompare(keyword,"geometry") == 0)
3783 {
3784 flags=ParseGeometry(value,&geometry_info);
3785 if ((flags & SigmaValue) == 0)
3786 geometry_info.sigma=1.0;
3787 break;
3788 }
3789 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3790 keyword);
3791 break;
3792 }
3793 case 'R':
3794 case 'r':
3795 {
3796 if (LocaleCompare(keyword,"radius") == 0)
3797 {
cristyf2f27272009-12-17 14:48:46 +00003798 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003799 break;
3800 }
3801 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3802 keyword);
3803 break;
3804 }
3805 default:
3806 {
3807 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3808 keyword);
3809 break;
3810 }
3811 }
3812 }
3813 median_image=MedianFilterImage(msl_info->image[n],geometry_info.rho,
3814 &msl_info->image[n]->exception);
3815 if (median_image == (Image *) NULL)
3816 break;
3817 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3818 msl_info->image[n]=median_image;
3819 break;
3820 }
cristyb988fe72009-09-16 01:01:10 +00003821 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003822 {
3823 Image
3824 *minify_image;
3825
3826 /*
3827 Minify image.
3828 */
3829 if (msl_info->image[n] == (Image *) NULL)
3830 {
cristyb988fe72009-09-16 01:01:10 +00003831 ThrowMSLException(OptionError,"NoImagesDefined",
3832 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003833 break;
3834 }
3835 if (attributes != (const xmlChar **) NULL)
3836 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3837 {
3838 keyword=(const char *) attributes[i++];
3839 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003840 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003841 CloneString(&value,attribute);
3842 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3843 }
3844 minify_image=MinifyImage(msl_info->image[n],
3845 &msl_info->image[n]->exception);
3846 if (minify_image == (Image *) NULL)
3847 break;
3848 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3849 msl_info->image[n]=minify_image;
3850 break;
3851 }
cristyb988fe72009-09-16 01:01:10 +00003852 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003853 break;
cristyb988fe72009-09-16 01:01:10 +00003854 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003855 {
3856 char
3857 modulate[MaxTextExtent];
3858
3859 /*
3860 Modulate image.
3861 */
3862 if (msl_info->image[n] == (Image *) NULL)
3863 {
cristyb988fe72009-09-16 01:01:10 +00003864 ThrowMSLException(OptionError,"NoImagesDefined",
3865 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003866 break;
3867 }
3868 geometry_info.rho=100.0;
3869 geometry_info.sigma=100.0;
3870 geometry_info.xi=100.0;
3871 if (attributes != (const xmlChar **) NULL)
3872 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3873 {
3874 keyword=(const char *) attributes[i++];
3875 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003876 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003877 CloneString(&value,attribute);
3878 switch (*keyword)
3879 {
3880 case 'B':
3881 case 'b':
3882 {
3883 if (LocaleCompare(keyword,"blackness") == 0)
3884 {
cristyf2f27272009-12-17 14:48:46 +00003885 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003886 break;
3887 }
3888 if (LocaleCompare(keyword,"brightness") == 0)
3889 {
cristyf2f27272009-12-17 14:48:46 +00003890 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003891 break;
3892 }
3893 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3894 keyword);
3895 break;
3896 }
3897 case 'F':
3898 case 'f':
3899 {
3900 if (LocaleCompare(keyword,"factor") == 0)
3901 {
3902 flags=ParseGeometry(value,&geometry_info);
3903 break;
3904 }
3905 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3906 keyword);
3907 break;
3908 }
3909 case 'H':
3910 case 'h':
3911 {
3912 if (LocaleCompare(keyword,"hue") == 0)
3913 {
cristyf2f27272009-12-17 14:48:46 +00003914 geometry_info.xi=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003915 break;
3916 }
3917 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3918 keyword);
3919 break;
3920 }
3921 case 'L':
3922 case 'l':
3923 {
3924 if (LocaleCompare(keyword,"lightness") == 0)
3925 {
cristyf2f27272009-12-17 14:48:46 +00003926 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003927 break;
3928 }
3929 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3930 keyword);
3931 break;
3932 }
3933 case 'S':
3934 case 's':
3935 {
3936 if (LocaleCompare(keyword,"saturation") == 0)
3937 {
cristyf2f27272009-12-17 14:48:46 +00003938 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003939 break;
3940 }
3941 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3942 keyword);
3943 break;
3944 }
3945 case 'W':
3946 case 'w':
3947 {
3948 if (LocaleCompare(keyword,"whiteness") == 0)
3949 {
cristyf2f27272009-12-17 14:48:46 +00003950 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00003951 break;
3952 }
3953 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3954 keyword);
3955 break;
3956 }
3957 default:
3958 {
3959 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3960 keyword);
3961 break;
3962 }
3963 }
3964 }
cristye7f51092010-01-17 00:39:37 +00003965 (void) FormatMagickString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003966 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
3967 (void) ModulateImage(msl_info->image[n],modulate);
3968 break;
3969 }
3970 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3971 }
3972 case 'N':
3973 case 'n':
3974 {
cristyb988fe72009-09-16 01:01:10 +00003975 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003976 {
3977 MagickBooleanType
3978 gray;
3979
3980 /*
3981 Negate image.
3982 */
3983 if (msl_info->image[n] == (Image *) NULL)
3984 {
cristyb988fe72009-09-16 01:01:10 +00003985 ThrowMSLException(OptionError,"NoImagesDefined",
3986 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003987 break;
3988 }
3989 gray=MagickFalse;
3990 if (attributes != (const xmlChar **) NULL)
3991 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3992 {
3993 keyword=(const char *) attributes[i++];
3994 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003995 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003996 CloneString(&value,attribute);
3997 switch (*keyword)
3998 {
3999 case 'C':
4000 case 'c':
4001 {
4002 if (LocaleCompare(keyword,"channel") == 0)
4003 {
4004 option=ParseChannelOption(value);
4005 if (option < 0)
4006 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4007 value);
4008 channel=(ChannelType) option;
4009 break;
4010 }
4011 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4012 keyword);
4013 break;
4014 }
4015 case 'G':
4016 case 'g':
4017 {
4018 if (LocaleCompare(keyword,"gray") == 0)
4019 {
4020 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4021 value);
4022 if (option < 0)
4023 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4024 value);
4025 gray=(MagickBooleanType) option;
4026 break;
4027 }
4028 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4029 keyword);
4030 break;
4031 }
4032 default:
4033 {
4034 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4035 keyword);
4036 break;
4037 }
4038 }
4039 }
4040 (void) NegateImageChannel(msl_info->image[n],channel,gray);
4041 break;
4042 }
cristyb988fe72009-09-16 01:01:10 +00004043 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004044 {
4045 /*
4046 Normalize image.
4047 */
4048 if (msl_info->image[n] == (Image *) NULL)
4049 {
cristyb988fe72009-09-16 01:01:10 +00004050 ThrowMSLException(OptionError,"NoImagesDefined",
4051 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004052 break;
4053 }
4054 if (attributes != (const xmlChar **) NULL)
4055 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4056 {
4057 keyword=(const char *) attributes[i++];
4058 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004059 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004060 CloneString(&value,attribute);
4061 switch (*keyword)
4062 {
4063 case 'C':
4064 case 'c':
4065 {
4066 if (LocaleCompare(keyword,"channel") == 0)
4067 {
4068 option=ParseChannelOption(value);
4069 if (option < 0)
4070 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4071 value);
4072 channel=(ChannelType) option;
4073 break;
4074 }
4075 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4076 keyword);
4077 break;
4078 }
4079 default:
4080 {
4081 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4082 keyword);
4083 break;
4084 }
4085 }
4086 }
4087 (void) NormalizeImageChannel(msl_info->image[n],channel);
4088 break;
4089 }
4090 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4091 }
4092 case 'O':
4093 case 'o':
4094 {
cristyb988fe72009-09-16 01:01:10 +00004095 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004096 {
4097 Image
4098 *paint_image;
4099
4100 /*
4101 Oil-paint image.
4102 */
4103 if (msl_info->image[n] == (Image *) NULL)
4104 {
cristyb988fe72009-09-16 01:01:10 +00004105 ThrowMSLException(OptionError,"NoImagesDefined",
4106 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004107 break;
4108 }
4109 if (attributes != (const xmlChar **) NULL)
4110 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4111 {
4112 keyword=(const char *) attributes[i++];
4113 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004114 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004115 CloneString(&value,attribute);
4116 switch (*keyword)
4117 {
4118 case 'G':
4119 case 'g':
4120 {
4121 if (LocaleCompare(keyword,"geometry") == 0)
4122 {
4123 flags=ParseGeometry(value,&geometry_info);
4124 if ((flags & SigmaValue) == 0)
4125 geometry_info.sigma=1.0;
4126 break;
4127 }
4128 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4129 keyword);
4130 break;
4131 }
4132 case 'R':
4133 case 'r':
4134 {
4135 if (LocaleCompare(keyword,"radius") == 0)
4136 {
cristyf2f27272009-12-17 14:48:46 +00004137 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004138 break;
4139 }
4140 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4141 keyword);
4142 break;
4143 }
4144 default:
4145 {
4146 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4147 keyword);
4148 break;
4149 }
4150 }
4151 }
4152 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4153 &msl_info->image[n]->exception);
4154 if (paint_image == (Image *) NULL)
4155 break;
4156 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4157 msl_info->image[n]=paint_image;
4158 break;
4159 }
cristyb988fe72009-09-16 01:01:10 +00004160 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004161 {
4162 MagickPixelPacket
4163 fill_color,
4164 target;
4165
4166 /*
4167 Opaque image.
4168 */
4169 if (msl_info->image[n] == (Image *) NULL)
4170 {
cristyb988fe72009-09-16 01:01:10 +00004171 ThrowMSLException(OptionError,"NoImagesDefined",
4172 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004173 break;
4174 }
4175 (void) QueryMagickColor("none",&target,&exception);
4176 (void) QueryMagickColor("none",&fill_color,&exception);
4177 if (attributes != (const xmlChar **) NULL)
4178 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4179 {
4180 keyword=(const char *) attributes[i++];
4181 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004182 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004183 CloneString(&value,attribute);
4184 switch (*keyword)
4185 {
4186 case 'C':
4187 case 'c':
4188 {
4189 if (LocaleCompare(keyword,"channel") == 0)
4190 {
4191 option=ParseChannelOption(value);
4192 if (option < 0)
4193 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4194 value);
4195 channel=(ChannelType) option;
4196 break;
4197 }
4198 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4199 keyword);
4200 break;
4201 }
4202 case 'F':
4203 case 'f':
4204 {
4205 if (LocaleCompare(keyword,"fill") == 0)
4206 {
4207 (void) QueryMagickColor(value,&fill_color,&exception);
4208 break;
4209 }
4210 if (LocaleCompare(keyword,"fuzz") == 0)
4211 {
cristyf2f27272009-12-17 14:48:46 +00004212 msl_info->image[n]->fuzz=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004213 break;
4214 }
4215 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4216 keyword);
4217 break;
4218 }
4219 default:
4220 {
4221 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4222 keyword);
4223 break;
4224 }
4225 }
4226 }
4227 (void) OpaquePaintImageChannel(msl_info->image[n],channel,
4228 &target,&fill_color,MagickFalse);
4229 break;
4230 }
4231 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4232 }
4233 case 'P':
4234 case 'p':
4235 {
cristyb988fe72009-09-16 01:01:10 +00004236 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004237 {
4238 if (attributes == (const xmlChar **) NULL)
4239 break;
4240 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4241 {
4242 keyword=(const char *) attributes[i++];
4243 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004244 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004245 CloneString(&value,attribute);
4246 switch (*keyword)
4247 {
4248 case 'O':
4249 case 'o':
4250 {
4251 if (LocaleCompare(keyword,"output") == 0)
4252 {
4253 (void) fprintf(stdout,"%s",value);
4254 break;
4255 }
4256 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4257 break;
4258 }
4259 default:
4260 {
4261 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4262 break;
4263 }
4264 }
4265 }
4266 break;
4267 }
cristy4fa36e42009-09-18 14:24:06 +00004268 if (LocaleCompare((const char *) tag, "profile") == 0)
4269 {
cristy4fa36e42009-09-18 14:24:06 +00004270 if (msl_info->image[n] == (Image *) NULL)
4271 {
4272 ThrowMSLException(OptionError,"NoImagesDefined",
4273 (const char *) tag);
4274 break;
4275 }
4276 if (attributes == (const xmlChar **) NULL)
4277 break;
4278 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4279 {
4280 const char
4281 *name;
4282
4283 const StringInfo
4284 *profile;
4285
4286 Image
4287 *profile_image;
4288
4289 ImageInfo
4290 *profile_info;
4291
4292 keyword=(const char *) attributes[i++];
4293 attribute=InterpretImageProperties(msl_info->image_info[n],
4294 msl_info->attributes[n],(const char *) attributes[i]);
4295 CloneString(&value,attribute);
4296 if (*keyword == '+')
4297 {
4298 /*
4299 Remove a profile from the image.
4300 */
4301 (void) ProfileImage(msl_info->image[n],keyword,
4302 (const unsigned char *) NULL,0,MagickTrue);
4303 continue;
4304 }
4305 /*
4306 Associate a profile with the image.
4307 */
4308 profile_info=CloneImageInfo(msl_info->image_info[n]);
4309 profile=GetImageProfile(msl_info->image[n],"iptc");
4310 if (profile != (StringInfo *) NULL)
4311 profile_info->profile=(void *) CloneStringInfo(profile);
4312 profile_image=GetImageCache(profile_info,keyword,&exception);
4313 profile_info=DestroyImageInfo(profile_info);
4314 if (profile_image == (Image *) NULL)
4315 {
4316 char
4317 name[MaxTextExtent],
4318 filename[MaxTextExtent];
4319
4320 register char
4321 *p;
4322
4323 StringInfo
4324 *profile;
4325
4326 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4327 (void) CopyMagickString(name,keyword,MaxTextExtent);
4328 for (p=filename; *p != '\0'; p++)
4329 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4330 (IsPathAccessible(keyword) == MagickFalse))
4331 {
4332 register char
4333 *q;
4334
4335 /*
4336 Look for profile name (e.g. name:profile).
4337 */
4338 (void) CopyMagickString(name,filename,(size_t)
4339 (p-filename+1));
4340 for (q=filename; *q != '\0'; q++)
4341 *q=(*++p);
4342 break;
4343 }
4344 profile=FileToStringInfo(filename,~0UL,&exception);
4345 if (profile != (StringInfo *) NULL)
4346 {
4347 (void) ProfileImage(msl_info->image[n],name,
4348 GetStringInfoDatum(profile),(unsigned long)
4349 GetStringInfoLength(profile),MagickFalse);
4350 profile=DestroyStringInfo(profile);
4351 }
4352 continue;
4353 }
4354 ResetImageProfileIterator(profile_image);
4355 name=GetNextImageProfile(profile_image);
4356 while (name != (const char *) NULL)
4357 {
4358 profile=GetImageProfile(profile_image,name);
4359 if (profile != (StringInfo *) NULL)
4360 (void) ProfileImage(msl_info->image[n],name,
4361 GetStringInfoDatum(profile),(unsigned long)
4362 GetStringInfoLength(profile),MagickFalse);
4363 name=GetNextImageProfile(profile_image);
4364 }
4365 profile_image=DestroyImage(profile_image);
4366 }
4367 break;
4368 }
cristy3ed852e2009-09-05 21:47:34 +00004369 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4370 }
4371 case 'Q':
4372 case 'q':
4373 {
cristyb988fe72009-09-16 01:01:10 +00004374 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004375 {
4376 QuantizeInfo
4377 quantize_info;
4378
4379 /*
4380 Quantize image.
4381 */
4382 if (msl_info->image[n] == (Image *) NULL)
4383 {
cristyb988fe72009-09-16 01:01:10 +00004384 ThrowMSLException(OptionError,"NoImagesDefined",
4385 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004386 break;
4387 }
4388 GetQuantizeInfo(&quantize_info);
4389 if (attributes != (const xmlChar **) NULL)
4390 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4391 {
4392 keyword=(const char *) attributes[i++];
4393 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004394 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004395 CloneString(&value,attribute);
4396 switch (*keyword)
4397 {
4398 case 'C':
4399 case 'c':
4400 {
4401 if (LocaleCompare(keyword,"colors") == 0)
4402 {
cristyf2f27272009-12-17 14:48:46 +00004403 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004404 break;
4405 }
4406 if (LocaleCompare(keyword,"colorspace") == 0)
4407 {
4408 option=ParseMagickOption(MagickColorspaceOptions,
4409 MagickFalse,value);
4410 if (option < 0)
4411 ThrowMSLException(OptionError,
4412 "UnrecognizedColorspaceType",value);
4413 quantize_info.colorspace=(ColorspaceType) option;
4414 break;
4415 }
4416 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4417 keyword);
4418 break;
4419 }
4420 case 'D':
4421 case 'd':
4422 {
4423 if (LocaleCompare(keyword,"dither") == 0)
4424 {
4425 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4426 value);
4427 if (option < 0)
4428 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4429 value);
4430 quantize_info.dither=(MagickBooleanType) option;
4431 break;
4432 }
4433 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4434 keyword);
4435 break;
4436 }
4437 case 'M':
4438 case 'm':
4439 {
4440 if (LocaleCompare(keyword,"measure") == 0)
4441 {
4442 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4443 value);
4444 if (option < 0)
4445 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4446 value);
4447 quantize_info.measure_error=(MagickBooleanType) option;
4448 break;
4449 }
4450 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4451 keyword);
4452 break;
4453 }
4454 case 'T':
4455 case 't':
4456 {
4457 if (LocaleCompare(keyword,"treedepth") == 0)
4458 {
cristyf2f27272009-12-17 14:48:46 +00004459 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004460 break;
4461 }
4462 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4463 keyword);
4464 break;
4465 }
4466 default:
4467 {
4468 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4469 keyword);
4470 break;
4471 }
4472 }
4473 }
4474 (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4475 break;
4476 }
cristyb988fe72009-09-16 01:01:10 +00004477 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004478 {
4479 char
4480 text[MaxTextExtent];
4481
4482 MagickBooleanType
4483 status;
4484
4485 TypeMetric
4486 metrics;
4487
4488 /*
4489 Query font metrics.
4490 */
4491 draw_info=CloneDrawInfo(msl_info->image_info[n],
4492 msl_info->draw_info[n]);
4493 angle=0.0;
4494 current=draw_info->affine;
4495 GetAffineMatrix(&affine);
4496 if (attributes != (const xmlChar **) NULL)
4497 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4498 {
4499 keyword=(const char *) attributes[i++];
4500 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004501 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004502 CloneString(&value,attribute);
4503 switch (*keyword)
4504 {
4505 case 'A':
4506 case 'a':
4507 {
4508 if (LocaleCompare(keyword,"affine") == 0)
4509 {
4510 char
4511 *p;
4512
4513 p=value;
4514 draw_info->affine.sx=strtod(p,&p);
4515 if (*p ==',')
4516 p++;
4517 draw_info->affine.rx=strtod(p,&p);
4518 if (*p ==',')
4519 p++;
4520 draw_info->affine.ry=strtod(p,&p);
4521 if (*p ==',')
4522 p++;
4523 draw_info->affine.sy=strtod(p,&p);
4524 if (*p ==',')
4525 p++;
4526 draw_info->affine.tx=strtod(p,&p);
4527 if (*p ==',')
4528 p++;
4529 draw_info->affine.ty=strtod(p,&p);
4530 break;
4531 }
4532 if (LocaleCompare(keyword,"align") == 0)
4533 {
4534 option=ParseMagickOption(MagickAlignOptions,MagickFalse,
4535 value);
4536 if (option < 0)
4537 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4538 value);
4539 draw_info->align=(AlignType) option;
4540 break;
4541 }
4542 if (LocaleCompare(keyword,"antialias") == 0)
4543 {
4544 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4545 value);
4546 if (option < 0)
4547 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4548 value);
4549 draw_info->stroke_antialias=(MagickBooleanType) option;
4550 draw_info->text_antialias=(MagickBooleanType) option;
4551 break;
4552 }
4553 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4554 keyword);
4555 break;
4556 }
4557 case 'D':
4558 case 'd':
4559 {
4560 if (LocaleCompare(keyword,"density") == 0)
4561 {
4562 CloneString(&draw_info->density,value);
4563 break;
4564 }
4565 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4566 keyword);
4567 break;
4568 }
4569 case 'E':
4570 case 'e':
4571 {
4572 if (LocaleCompare(keyword,"encoding") == 0)
4573 {
4574 CloneString(&draw_info->encoding,value);
4575 break;
4576 }
4577 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4578 keyword);
4579 break;
4580 }
4581 case 'F':
4582 case 'f':
4583 {
4584 if (LocaleCompare(keyword, "fill") == 0)
4585 {
4586 (void) QueryColorDatabase(value,&draw_info->fill,
4587 &exception);
4588 break;
4589 }
4590 if (LocaleCompare(keyword,"family") == 0)
4591 {
4592 CloneString(&draw_info->family,value);
4593 break;
4594 }
4595 if (LocaleCompare(keyword,"font") == 0)
4596 {
4597 CloneString(&draw_info->font,value);
4598 break;
4599 }
4600 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4601 keyword);
4602 break;
4603 }
4604 case 'G':
4605 case 'g':
4606 {
4607 if (LocaleCompare(keyword,"geometry") == 0)
4608 {
4609 flags=ParsePageGeometry(msl_info->image[n],value,
4610 &geometry,&exception);
4611 if ((flags & HeightValue) == 0)
4612 geometry.height=geometry.width;
4613 break;
4614 }
4615 if (LocaleCompare(keyword,"gravity") == 0)
4616 {
4617 option=ParseMagickOption(MagickGravityOptions,MagickFalse,
4618 value);
4619 if (option < 0)
4620 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4621 value);
4622 draw_info->gravity=(GravityType) option;
4623 break;
4624 }
4625 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4626 keyword);
4627 break;
4628 }
4629 case 'P':
4630 case 'p':
4631 {
4632 if (LocaleCompare(keyword,"pointsize") == 0)
4633 {
cristyf2f27272009-12-17 14:48:46 +00004634 draw_info->pointsize=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004635 break;
4636 }
4637 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4638 keyword);
4639 break;
4640 }
4641 case 'R':
4642 case 'r':
4643 {
4644 if (LocaleCompare(keyword,"rotate") == 0)
4645 {
cristyf2f27272009-12-17 14:48:46 +00004646 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004647 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4648 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4649 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4650 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4651 break;
4652 }
4653 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4654 keyword);
4655 break;
4656 }
4657 case 'S':
4658 case 's':
4659 {
4660 if (LocaleCompare(keyword,"scale") == 0)
4661 {
4662 flags=ParseGeometry(value,&geometry_info);
4663 if ((flags & SigmaValue) == 0)
4664 geometry_info.sigma=1.0;
4665 affine.sx=geometry_info.rho;
4666 affine.sy=geometry_info.sigma;
4667 break;
4668 }
4669 if (LocaleCompare(keyword,"skewX") == 0)
4670 {
cristyf2f27272009-12-17 14:48:46 +00004671 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004672 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4673 break;
4674 }
4675 if (LocaleCompare(keyword,"skewY") == 0)
4676 {
cristyf2f27272009-12-17 14:48:46 +00004677 angle=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00004678 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4679 break;
4680 }
4681 if (LocaleCompare(keyword,"stretch") == 0)
4682 {
4683 option=ParseMagickOption(MagickStretchOptions,MagickFalse,
4684 value);
4685 if (option < 0)
4686 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4687 value);
4688 draw_info->stretch=(StretchType) option;
4689 break;
4690 }
4691 if (LocaleCompare(keyword, "stroke") == 0)
4692 {
4693 (void) QueryColorDatabase(value,&draw_info->stroke,
4694 &exception);
4695 break;
4696 }
4697 if (LocaleCompare(keyword,"strokewidth") == 0)
4698 {
cristyf2f27272009-12-17 14:48:46 +00004699 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004700 break;
4701 }
4702 if (LocaleCompare(keyword,"style") == 0)
4703 {
4704 option=ParseMagickOption(MagickStyleOptions,MagickFalse,
4705 value);
4706 if (option < 0)
4707 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4708 value);
4709 draw_info->style=(StyleType) option;
4710 break;
4711 }
4712 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4713 keyword);
4714 break;
4715 }
4716 case 'T':
4717 case 't':
4718 {
4719 if (LocaleCompare(keyword,"text") == 0)
4720 {
4721 CloneString(&draw_info->text,value);
4722 break;
4723 }
4724 if (LocaleCompare(keyword,"translate") == 0)
4725 {
4726 flags=ParseGeometry(value,&geometry_info);
4727 if ((flags & SigmaValue) == 0)
4728 geometry_info.sigma=1.0;
4729 affine.tx=geometry_info.rho;
4730 affine.ty=geometry_info.sigma;
4731 break;
4732 }
4733 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4734 keyword);
4735 break;
4736 }
4737 case 'U':
4738 case 'u':
4739 {
4740 if (LocaleCompare(keyword, "undercolor") == 0)
4741 {
4742 (void) QueryColorDatabase(value,&draw_info->undercolor,
4743 &exception);
4744 break;
4745 }
4746 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4747 keyword);
4748 break;
4749 }
4750 case 'W':
4751 case 'w':
4752 {
4753 if (LocaleCompare(keyword,"weight") == 0)
4754 {
cristyf2f27272009-12-17 14:48:46 +00004755 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004756 break;
4757 }
4758 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4759 keyword);
4760 break;
4761 }
4762 case 'X':
4763 case 'x':
4764 {
4765 if (LocaleCompare(keyword,"x") == 0)
4766 {
cristyf2f27272009-12-17 14:48:46 +00004767 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004768 break;
4769 }
4770 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4771 keyword);
4772 break;
4773 }
4774 case 'Y':
4775 case 'y':
4776 {
4777 if (LocaleCompare(keyword,"y") == 0)
4778 {
cristyf2f27272009-12-17 14:48:46 +00004779 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004780 break;
4781 }
4782 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4783 keyword);
4784 break;
4785 }
4786 default:
4787 {
4788 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4789 keyword);
4790 break;
4791 }
4792 }
4793 }
4794 (void) FormatMagickString(text,MaxTextExtent,"%lux%lu%+ld%+ld",
4795 geometry.width,geometry.height,geometry.x,geometry.y);
4796 CloneString(&draw_info->geometry,text);
4797 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
4798 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
4799 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
4800 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
4801 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
4802 current.tx;
4803 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
4804 current.ty;
4805 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4806 if (status != MagickFalse)
4807 {
4808 Image
4809 *image;
4810
4811 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004812 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004813 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004814 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004815 "%g",metrics.pixels_per_em.y);
4816 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004817 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004818 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004819 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004820 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004821 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004822 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004823 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004824 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004825 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004826 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004827 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004828 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004829 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004830 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004831 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004832 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004833 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004834 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004835 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004836 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004837 metrics.origin.y);
4838 }
4839 draw_info=DestroyDrawInfo(draw_info);
4840 break;
4841 }
4842 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4843 }
4844 case 'R':
4845 case 'r':
4846 {
cristyb988fe72009-09-16 01:01:10 +00004847 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004848 {
4849 MagickBooleanType
4850 raise;
4851
4852 /*
4853 Raise image.
4854 */
4855 if (msl_info->image[n] == (Image *) NULL)
4856 {
cristyb988fe72009-09-16 01:01:10 +00004857 ThrowMSLException(OptionError,"NoImagesDefined",
4858 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004859 break;
4860 }
4861 raise=MagickFalse;
4862 SetGeometry(msl_info->image[n],&geometry);
4863 if (attributes != (const xmlChar **) NULL)
4864 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4865 {
4866 keyword=(const char *) attributes[i++];
4867 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004868 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004869 CloneString(&value,attribute);
4870 switch (*keyword)
4871 {
4872 case 'G':
4873 case 'g':
4874 {
4875 if (LocaleCompare(keyword,"geometry") == 0)
4876 {
4877 flags=ParsePageGeometry(msl_info->image[n],value,
4878 &geometry,&exception);
4879 if ((flags & HeightValue) == 0)
4880 geometry.height=geometry.width;
4881 break;
4882 }
4883 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4884 keyword);
4885 break;
4886 }
4887 case 'H':
4888 case 'h':
4889 {
4890 if (LocaleCompare(keyword,"height") == 0)
4891 {
cristyf2f27272009-12-17 14:48:46 +00004892 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004893 break;
4894 }
4895 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4896 keyword);
4897 break;
4898 }
4899 case 'R':
4900 case 'r':
4901 {
4902 if (LocaleCompare(keyword,"raise") == 0)
4903 {
4904 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4905 value);
4906 if (option < 0)
4907 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4908 value);
4909 raise=(MagickBooleanType) option;
4910 break;
4911 }
4912 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4913 keyword);
4914 break;
4915 }
4916 case 'W':
4917 case 'w':
4918 {
4919 if (LocaleCompare(keyword,"width") == 0)
4920 {
cristyf2f27272009-12-17 14:48:46 +00004921 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004922 break;
4923 }
4924 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4925 keyword);
4926 break;
4927 }
4928 default:
4929 {
4930 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4931 keyword);
4932 break;
4933 }
4934 }
4935 }
4936 (void) RaiseImage(msl_info->image[n],&geometry,raise);
4937 break;
4938 }
cristyb988fe72009-09-16 01:01:10 +00004939 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004940 {
4941 if (attributes == (const xmlChar **) NULL)
4942 break;
4943 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4944 {
4945 keyword=(const char *) attributes[i++];
4946 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004947 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00004948 switch (*keyword)
4949 {
4950 case 'F':
4951 case 'f':
4952 {
4953 if (LocaleCompare(keyword,"filename") == 0)
4954 {
4955 Image
4956 *image;
4957
4958 (void) CopyMagickString(msl_info->image_info[n]->filename,
4959 value,MaxTextExtent);
4960 image=ReadImage(msl_info->image_info[n],&exception);
4961 CatchException(&exception);
4962 if (image == (Image *) NULL)
4963 continue;
4964 AppendImageToList(&msl_info->image[n],image);
4965 break;
4966 }
cristy4582cbb2009-09-23 00:35:43 +00004967 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004968 break;
4969 }
4970 default:
4971 {
cristy4582cbb2009-09-23 00:35:43 +00004972 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004973 break;
4974 }
4975 }
4976 }
4977 break;
4978 }
cristyb988fe72009-09-16 01:01:10 +00004979 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004980 {
4981 Image
4982 *paint_image;
4983
4984 /*
4985 Reduce-noise image.
4986 */
4987 if (msl_info->image[n] == (Image *) NULL)
4988 {
cristyb988fe72009-09-16 01:01:10 +00004989 ThrowMSLException(OptionError,"NoImagesDefined",
4990 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004991 break;
4992 }
4993 if (attributes != (const xmlChar **) NULL)
4994 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4995 {
4996 keyword=(const char *) attributes[i++];
4997 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004998 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004999 CloneString(&value,attribute);
5000 switch (*keyword)
5001 {
5002 case 'G':
5003 case 'g':
5004 {
5005 if (LocaleCompare(keyword,"geometry") == 0)
5006 {
5007 flags=ParseGeometry(value,&geometry_info);
5008 if ((flags & SigmaValue) == 0)
5009 geometry_info.sigma=1.0;
5010 break;
5011 }
5012 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5013 keyword);
5014 break;
5015 }
5016 case 'R':
5017 case 'r':
5018 {
5019 if (LocaleCompare(keyword,"radius") == 0)
5020 {
cristyf2f27272009-12-17 14:48:46 +00005021 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005022 break;
5023 }
5024 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5025 keyword);
5026 break;
5027 }
5028 default:
5029 {
5030 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5031 keyword);
5032 break;
5033 }
5034 }
5035 }
5036 paint_image=ReduceNoiseImage(msl_info->image[n],geometry_info.rho,
5037 &msl_info->image[n]->exception);
5038 if (paint_image == (Image *) NULL)
5039 break;
5040 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5041 msl_info->image[n]=paint_image;
5042 break;
5043 }
cristyb988fe72009-09-16 01:01:10 +00005044 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005045 {
5046 /* init the values */
5047 width=msl_info->image[n]->page.width;
5048 height=msl_info->image[n]->page.height;
5049 x=msl_info->image[n]->page.x;
5050 y=msl_info->image[n]->page.y;
5051
5052 if (msl_info->image[n] == (Image *) NULL)
5053 {
cristyb988fe72009-09-16 01:01:10 +00005054 ThrowMSLException(OptionError,"NoImagesDefined",
5055 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005056 break;
5057 }
5058 if (attributes == (const xmlChar **) NULL)
5059 break;
5060 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5061 {
5062 keyword=(const char *) attributes[i++];
5063 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005064 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005065 switch (*keyword)
5066 {
5067 case 'G':
5068 case 'g':
5069 {
5070 if (LocaleCompare(keyword,"geometry") == 0)
5071 {
5072 int
5073 flags;
5074
5075 RectangleInfo
5076 geometry;
5077
5078 flags=ParseAbsoluteGeometry(value,&geometry);
5079 if ((flags & WidthValue) != 0)
5080 {
5081 if ((flags & HeightValue) == 0)
5082 geometry.height=geometry.width;
5083 width=geometry.width;
5084 height=geometry.height;
5085 }
5086 if ((flags & AspectValue) != 0)
5087 {
5088 if ((flags & XValue) != 0)
5089 x+=geometry.x;
5090 if ((flags & YValue) != 0)
5091 y+=geometry.y;
5092 }
5093 else
5094 {
5095 if ((flags & XValue) != 0)
5096 {
5097 x=geometry.x;
5098 if ((width == 0) && (geometry.x > 0))
5099 width=msl_info->image[n]->columns+geometry.x;
5100 }
5101 if ((flags & YValue) != 0)
5102 {
5103 y=geometry.y;
5104 if ((height == 0) && (geometry.y > 0))
5105 height=msl_info->image[n]->rows+geometry.y;
5106 }
5107 }
5108 break;
5109 }
5110 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5111 break;
5112 }
5113 case 'H':
5114 case 'h':
5115 {
5116 if (LocaleCompare(keyword,"height") == 0)
5117 {
cristyf2f27272009-12-17 14:48:46 +00005118 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005119 break;
5120 }
5121 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5122 break;
5123 }
5124 case 'W':
5125 case 'w':
5126 {
5127 if (LocaleCompare(keyword,"width") == 0)
5128 {
cristyf2f27272009-12-17 14:48:46 +00005129 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005130 break;
5131 }
5132 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5133 break;
5134 }
5135 case 'X':
5136 case 'x':
5137 {
5138 if (LocaleCompare(keyword,"x") == 0)
5139 {
cristyf2f27272009-12-17 14:48:46 +00005140 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005141 break;
5142 }
5143 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5144 break;
5145 }
5146 case 'Y':
5147 case 'y':
5148 {
5149 if (LocaleCompare(keyword,"y") == 0)
5150 {
cristyf2f27272009-12-17 14:48:46 +00005151 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005152 break;
5153 }
5154 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5155 break;
5156 }
5157 default:
5158 {
5159 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5160 break;
5161 }
5162 }
5163 }
5164
cristyb988fe72009-09-16 01:01:10 +00005165 msl_info->image[n]->page.width=width;
5166 msl_info->image[n]->page.height=height;
5167 msl_info->image[n]->page.x=x;
5168 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005169 break;
5170 }
cristyb988fe72009-09-16 01:01:10 +00005171 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005172 {
5173 double
5174 x_resolution,
5175 y_resolution;
5176
5177 if (msl_info->image[n] == (Image *) NULL)
5178 {
cristyb988fe72009-09-16 01:01:10 +00005179 ThrowMSLException(OptionError,"NoImagesDefined",
5180 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005181 break;
5182 }
5183 if (attributes == (const xmlChar **) NULL)
5184 break;
5185 x_resolution=DefaultResolution;
5186 y_resolution=DefaultResolution;
5187 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5188 {
5189 keyword=(const char *) attributes[i++];
5190 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005191 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005192 switch (*keyword)
5193 {
5194 case 'b':
5195 {
5196 if (LocaleCompare(keyword,"blur") == 0)
5197 {
cristyf2f27272009-12-17 14:48:46 +00005198 msl_info->image[n]->blur=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005199 break;
5200 }
5201 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5202 break;
5203 }
5204 case 'G':
5205 case 'g':
5206 {
5207 if (LocaleCompare(keyword,"geometry") == 0)
5208 {
5209 long
5210 flags;
5211
5212 flags=ParseGeometry(value,&geometry_info);
5213 if ((flags & SigmaValue) == 0)
5214 geometry_info.sigma*=geometry_info.rho;
5215 x_resolution=geometry_info.rho;
5216 y_resolution=geometry_info.sigma;
5217 break;
5218 }
5219 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5220 break;
5221 }
5222 case 'X':
5223 case 'x':
5224 {
5225 if (LocaleCompare(keyword,"x-resolution") == 0)
5226 {
cristyf2f27272009-12-17 14:48:46 +00005227 x_resolution=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005228 break;
5229 }
5230 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5231 break;
5232 }
5233 case 'Y':
5234 case 'y':
5235 {
5236 if (LocaleCompare(keyword,"y-resolution") == 0)
5237 {
cristyf2f27272009-12-17 14:48:46 +00005238 y_resolution=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005239 break;
5240 }
5241 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5242 break;
5243 }
5244 default:
5245 {
5246 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5247 break;
5248 }
5249 }
5250 }
5251 /*
5252 Resample image.
5253 */
5254 {
5255 double
5256 factor;
5257
5258 Image
5259 *resample_image;
5260
5261 factor=1.0;
5262 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5263 factor=2.54;
5264 width=(unsigned long) (x_resolution*msl_info->image[n]->columns/
5265 (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5266 msl_info->image[n]->x_resolution))+0.5);
5267 height=(unsigned long) (y_resolution*msl_info->image[n]->rows/
5268 (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5269 msl_info->image[n]->y_resolution))+0.5);
5270 resample_image=ResizeImage(msl_info->image[n],width,height,
5271 msl_info->image[n]->filter,msl_info->image[n]->blur,
5272 &msl_info->image[n]->exception);
5273 if (resample_image == (Image *) NULL)
5274 break;
5275 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5276 msl_info->image[n]=resample_image;
5277 }
5278 break;
5279 }
cristyb988fe72009-09-16 01:01:10 +00005280 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005281 {
5282 double
5283 blur;
5284
5285 FilterTypes
5286 filter;
5287
5288 Image
5289 *resize_image;
5290
5291 /*
5292 Resize image.
5293 */
5294 if (msl_info->image[n] == (Image *) NULL)
5295 {
cristyb988fe72009-09-16 01:01:10 +00005296 ThrowMSLException(OptionError,"NoImagesDefined",
5297 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005298 break;
5299 }
5300 filter=UndefinedFilter;
5301 blur=1.0;
5302 if (attributes != (const xmlChar **) NULL)
5303 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5304 {
5305 keyword=(const char *) attributes[i++];
5306 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005307 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005308 CloneString(&value,attribute);
5309 switch (*keyword)
5310 {
5311 case 'F':
5312 case 'f':
5313 {
5314 if (LocaleCompare(keyword,"filter") == 0)
5315 {
5316 option=ParseMagickOption(MagickFilterOptions,MagickFalse,
5317 value);
5318 if (option < 0)
5319 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5320 value);
5321 filter=(FilterTypes) option;
5322 break;
5323 }
5324 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5325 keyword);
5326 break;
5327 }
5328 case 'G':
5329 case 'g':
5330 {
5331 if (LocaleCompare(keyword,"geometry") == 0)
5332 {
5333 flags=ParseRegionGeometry(msl_info->image[n],value,
5334 &geometry,&exception);
5335 break;
5336 }
5337 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5338 keyword);
5339 break;
5340 }
5341 case 'H':
5342 case 'h':
5343 {
5344 if (LocaleCompare(keyword,"height") == 0)
5345 {
cristye27293e2009-12-18 02:53:20 +00005346 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005347 break;
5348 }
5349 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5350 keyword);
5351 break;
5352 }
5353 case 'S':
5354 case 's':
5355 {
5356 if (LocaleCompare(keyword,"support") == 0)
5357 {
cristyf2f27272009-12-17 14:48:46 +00005358 blur=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005359 break;
5360 }
5361 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5362 keyword);
5363 break;
5364 }
5365 case 'W':
5366 case 'w':
5367 {
5368 if (LocaleCompare(keyword,"width") == 0)
5369 {
cristyf2f27272009-12-17 14:48:46 +00005370 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005371 break;
5372 }
5373 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5374 keyword);
5375 break;
5376 }
5377 default:
5378 {
5379 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5380 keyword);
5381 break;
5382 }
5383 }
5384 }
5385 resize_image=ResizeImage(msl_info->image[n],geometry.width,
5386 geometry.height,filter,blur,&msl_info->image[n]->exception);
5387 if (resize_image == (Image *) NULL)
5388 break;
5389 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5390 msl_info->image[n]=resize_image;
5391 break;
5392 }
cristyb988fe72009-09-16 01:01:10 +00005393 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005394 {
5395 Image
5396 *roll_image;
5397
5398 /*
5399 Roll image.
5400 */
5401 if (msl_info->image[n] == (Image *) NULL)
5402 {
cristyb988fe72009-09-16 01:01:10 +00005403 ThrowMSLException(OptionError,"NoImagesDefined",
5404 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005405 break;
5406 }
5407 SetGeometry(msl_info->image[n],&geometry);
5408 if (attributes != (const xmlChar **) NULL)
5409 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5410 {
5411 keyword=(const char *) attributes[i++];
5412 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005413 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005414 CloneString(&value,attribute);
5415 switch (*keyword)
5416 {
5417 case 'G':
5418 case 'g':
5419 {
5420 if (LocaleCompare(keyword,"geometry") == 0)
5421 {
5422 flags=ParsePageGeometry(msl_info->image[n],value,
5423 &geometry,&exception);
5424 if ((flags & HeightValue) == 0)
5425 geometry.height=geometry.width;
5426 break;
5427 }
5428 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5429 keyword);
5430 break;
5431 }
5432 case 'X':
5433 case 'x':
5434 {
5435 if (LocaleCompare(keyword,"x") == 0)
5436 {
cristyf2f27272009-12-17 14:48:46 +00005437 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005438 break;
5439 }
5440 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5441 keyword);
5442 break;
5443 }
5444 case 'Y':
5445 case 'y':
5446 {
5447 if (LocaleCompare(keyword,"y") == 0)
5448 {
cristyf2f27272009-12-17 14:48:46 +00005449 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005450 break;
5451 }
5452 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5453 keyword);
5454 break;
5455 }
5456 default:
5457 {
5458 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5459 keyword);
5460 break;
5461 }
5462 }
5463 }
5464 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5465 &msl_info->image[n]->exception);
5466 if (roll_image == (Image *) NULL)
5467 break;
5468 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5469 msl_info->image[n]=roll_image;
5470 break;
5471 }
cristyb988fe72009-09-16 01:01:10 +00005472 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005473 {
5474 /* init the values */
5475 width=msl_info->image[n]->columns;
5476 height=msl_info->image[n]->rows;
5477 x = y = 0;
5478
5479 if (msl_info->image[n] == (Image *) NULL)
5480 {
cristyb988fe72009-09-16 01:01:10 +00005481 ThrowMSLException(OptionError,"NoImagesDefined",
5482 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005483 break;
5484 }
5485 if (attributes == (const xmlChar **) NULL)
5486 break;
5487 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5488 {
5489 keyword=(const char *) attributes[i++];
5490 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005491 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005492 switch (*keyword)
5493 {
5494 case 'G':
5495 case 'g':
5496 {
5497 if (LocaleCompare(keyword,"geometry") == 0)
5498 {
5499 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5500 break;
5501 }
5502 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5503 break;
5504 }
5505 case 'X':
5506 case 'x':
5507 {
5508 if (LocaleCompare(keyword,"x") == 0)
5509 {
cristyf2f27272009-12-17 14:48:46 +00005510 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005511 break;
5512 }
5513 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5514 break;
5515 }
5516 case 'Y':
5517 case 'y':
5518 {
5519 if (LocaleCompare(keyword,"y") == 0)
5520 {
cristyf2f27272009-12-17 14:48:46 +00005521 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005522 break;
5523 }
5524 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5525 break;
5526 }
5527 default:
5528 {
5529 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5530 break;
5531 }
5532 }
5533 }
5534
5535 /*
5536 process image.
5537 */
5538 {
5539 Image
5540 *newImage;
5541
5542 newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5543 if (newImage == (Image *) NULL)
5544 break;
5545 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5546 msl_info->image[n]=newImage;
5547 }
5548
5549 break;
5550 }
cristyb988fe72009-09-16 01:01:10 +00005551 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005552 {
5553 Image
5554 *rotate_image;
5555
5556 /*
5557 Rotate image.
5558 */
5559 if (msl_info->image[n] == (Image *) NULL)
5560 {
cristyb988fe72009-09-16 01:01:10 +00005561 ThrowMSLException(OptionError,"NoImagesDefined",
5562 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005563 break;
5564 }
5565 if (attributes != (const xmlChar **) NULL)
5566 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5567 {
5568 keyword=(const char *) attributes[i++];
5569 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005570 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005571 CloneString(&value,attribute);
5572 switch (*keyword)
5573 {
5574 case 'D':
5575 case 'd':
5576 {
5577 if (LocaleCompare(keyword,"degrees") == 0)
5578 {
cristyf2f27272009-12-17 14:48:46 +00005579 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005580 break;
5581 }
5582 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5583 keyword);
5584 break;
5585 }
5586 case 'G':
5587 case 'g':
5588 {
5589 if (LocaleCompare(keyword,"geometry") == 0)
5590 {
5591 flags=ParseGeometry(value,&geometry_info);
5592 if ((flags & SigmaValue) == 0)
5593 geometry_info.sigma=1.0;
5594 break;
5595 }
5596 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5597 keyword);
5598 break;
5599 }
5600 default:
5601 {
5602 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5603 keyword);
5604 break;
5605 }
5606 }
5607 }
5608 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5609 &msl_info->image[n]->exception);
5610 if (rotate_image == (Image *) NULL)
5611 break;
5612 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5613 msl_info->image[n]=rotate_image;
5614 break;
5615 }
cristyb988fe72009-09-16 01:01:10 +00005616 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005617 {
5618 /* init the values */
5619 double degrees = 0;
5620
5621 if (msl_info->image[n] == (Image *) NULL)
5622 {
cristyb988fe72009-09-16 01:01:10 +00005623 ThrowMSLException(OptionError,"NoImagesDefined",
5624 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005625 break;
5626 }
5627 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005628 break;
cristy3ed852e2009-09-05 21:47:34 +00005629 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5630 {
5631 keyword=(const char *) attributes[i++];
5632 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005633 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005634 switch (*keyword)
5635 {
5636 case 'D':
5637 case 'd':
5638 {
5639 if (LocaleCompare(keyword,"degrees") == 0)
5640 {
cristyf2f27272009-12-17 14:48:46 +00005641 degrees = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00005642 break;
5643 }
5644 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5645 break;
5646 }
5647 default:
5648 {
5649 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5650 break;
5651 }
5652 }
5653 }
5654
5655 /*
5656 process image.
5657 */
5658 {
5659 Image
5660 *newImage;
5661
5662 newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5663 if (newImage == (Image *) NULL)
5664 break;
5665 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5666 msl_info->image[n]=newImage;
5667 }
5668
5669 break;
5670 }
5671 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5672 }
5673 case 'S':
5674 case 's':
5675 {
cristyb988fe72009-09-16 01:01:10 +00005676 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005677 {
5678 Image
5679 *sample_image;
5680
5681 /*
5682 Sample image.
5683 */
5684 if (msl_info->image[n] == (Image *) NULL)
5685 {
cristyb988fe72009-09-16 01:01:10 +00005686 ThrowMSLException(OptionError,"NoImagesDefined",
5687 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005688 break;
5689 }
5690 if (attributes != (const xmlChar **) NULL)
5691 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5692 {
5693 keyword=(const char *) attributes[i++];
5694 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005695 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005696 CloneString(&value,attribute);
5697 switch (*keyword)
5698 {
5699 case 'G':
5700 case 'g':
5701 {
5702 if (LocaleCompare(keyword,"geometry") == 0)
5703 {
5704 flags=ParseRegionGeometry(msl_info->image[n],value,
5705 &geometry,&exception);
5706 break;
5707 }
5708 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5709 keyword);
5710 break;
5711 }
5712 case 'H':
5713 case 'h':
5714 {
5715 if (LocaleCompare(keyword,"height") == 0)
5716 {
cristye27293e2009-12-18 02:53:20 +00005717 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005718 break;
5719 }
5720 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5721 keyword);
5722 break;
5723 }
5724 case 'W':
5725 case 'w':
5726 {
5727 if (LocaleCompare(keyword,"width") == 0)
5728 {
cristyf2f27272009-12-17 14:48:46 +00005729 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005730 break;
5731 }
5732 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5733 keyword);
5734 break;
5735 }
5736 default:
5737 {
5738 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5739 keyword);
5740 break;
5741 }
5742 }
5743 }
5744 sample_image=SampleImage(msl_info->image[n],geometry.width,
5745 geometry.height,&msl_info->image[n]->exception);
5746 if (sample_image == (Image *) NULL)
5747 break;
5748 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5749 msl_info->image[n]=sample_image;
5750 break;
5751 }
cristyb988fe72009-09-16 01:01:10 +00005752 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005753 {
5754 Image
5755 *scale_image;
5756
5757 /*
5758 Scale image.
5759 */
5760 if (msl_info->image[n] == (Image *) NULL)
5761 {
cristyb988fe72009-09-16 01:01:10 +00005762 ThrowMSLException(OptionError,"NoImagesDefined",
5763 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005764 break;
5765 }
5766 if (attributes != (const xmlChar **) NULL)
5767 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5768 {
5769 keyword=(const char *) attributes[i++];
5770 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005771 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005772 CloneString(&value,attribute);
5773 switch (*keyword)
5774 {
5775 case 'G':
5776 case 'g':
5777 {
5778 if (LocaleCompare(keyword,"geometry") == 0)
5779 {
5780 flags=ParseRegionGeometry(msl_info->image[n],value,
5781 &geometry,&exception);
5782 break;
5783 }
5784 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5785 keyword);
5786 break;
5787 }
5788 case 'H':
5789 case 'h':
5790 {
5791 if (LocaleCompare(keyword,"height") == 0)
5792 {
cristye27293e2009-12-18 02:53:20 +00005793 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005794 break;
5795 }
5796 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5797 keyword);
5798 break;
5799 }
5800 case 'W':
5801 case 'w':
5802 {
5803 if (LocaleCompare(keyword,"width") == 0)
5804 {
cristyf2f27272009-12-17 14:48:46 +00005805 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005806 break;
5807 }
5808 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5809 keyword);
5810 break;
5811 }
5812 default:
5813 {
5814 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5815 keyword);
5816 break;
5817 }
5818 }
5819 }
5820 scale_image=ScaleImage(msl_info->image[n],geometry.width,
5821 geometry.height,&msl_info->image[n]->exception);
5822 if (scale_image == (Image *) NULL)
5823 break;
5824 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5825 msl_info->image[n]=scale_image;
5826 break;
5827 }
cristyb988fe72009-09-16 01:01:10 +00005828 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005829 {
5830 ColorspaceType
5831 colorspace;
5832
5833 MagickBooleanType
5834 verbose;
cristyb988fe72009-09-16 01:01:10 +00005835
cristy3ed852e2009-09-05 21:47:34 +00005836 /*
5837 Segment image.
5838 */
5839 if (msl_info->image[n] == (Image *) NULL)
5840 {
cristyb988fe72009-09-16 01:01:10 +00005841 ThrowMSLException(OptionError,"NoImagesDefined",
5842 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005843 break;
5844 }
5845 geometry_info.rho=1.0;
5846 geometry_info.sigma=1.5;
5847 colorspace=RGBColorspace;
5848 verbose=MagickFalse;
5849 if (attributes != (const xmlChar **) NULL)
5850 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5851 {
5852 keyword=(const char *) attributes[i++];
5853 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005854 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005855 CloneString(&value,attribute);
5856 switch (*keyword)
5857 {
5858 case 'C':
5859 case 'c':
5860 {
5861 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5862 {
cristyf2f27272009-12-17 14:48:46 +00005863 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005864 break;
5865 }
5866 if (LocaleCompare(keyword,"colorspace") == 0)
5867 {
5868 option=ParseMagickOption(MagickColorspaceOptions,
5869 MagickFalse,value);
5870 if (option < 0)
5871 ThrowMSLException(OptionError,
5872 "UnrecognizedColorspaceType",value);
5873 colorspace=(ColorspaceType) option;
5874 break;
5875 }
5876 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5877 keyword);
5878 break;
5879 }
5880 case 'G':
5881 case 'g':
5882 {
5883 if (LocaleCompare(keyword,"geometry") == 0)
5884 {
5885 flags=ParseGeometry(value,&geometry_info);
5886 if ((flags & SigmaValue) == 0)
5887 geometry_info.sigma=1.5;
5888 break;
5889 }
5890 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5891 keyword);
5892 break;
5893 }
5894 case 'S':
5895 case 's':
5896 {
5897 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5898 {
cristyf2f27272009-12-17 14:48:46 +00005899 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00005900 break;
5901 }
5902 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5903 keyword);
5904 break;
5905 }
5906 default:
5907 {
5908 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5909 keyword);
5910 break;
5911 }
5912 }
5913 }
5914 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5915 geometry_info.rho,geometry_info.sigma);
5916 break;
5917 }
cristyb988fe72009-09-16 01:01:10 +00005918 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005919 {
5920 if (msl_info->image[n] == (Image *) NULL)
5921 {
cristyb988fe72009-09-16 01:01:10 +00005922 ThrowMSLException(OptionError,"NoImagesDefined",
5923 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005924 break;
5925 }
5926
5927 if (attributes == (const xmlChar **) NULL)
5928 break;
5929 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5930 {
5931 keyword=(const char *) attributes[i++];
5932 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005933 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005934 switch (*keyword)
5935 {
cristy3ed852e2009-09-05 21:47:34 +00005936 case 'C':
5937 case 'c':
5938 {
5939 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005940 {
cristy2c8b6312009-09-16 02:37:23 +00005941 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005942 {
cristy2c8b6312009-09-16 02:37:23 +00005943 const char
5944 *property;
5945
5946 property=GetImageProperty(msl_info->attributes[j],"id");
5947 if (LocaleCompare(property,value) == 0)
5948 {
5949 SetImageMask(msl_info->image[n],msl_info->image[j]);
5950 break;
5951 }
cristy3ed852e2009-09-05 21:47:34 +00005952 }
cristy2c8b6312009-09-16 02:37:23 +00005953 break;
cristy3ed852e2009-09-05 21:47:34 +00005954 }
cristy3ed852e2009-09-05 21:47:34 +00005955 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005956 {
cristy2c8b6312009-09-16 02:37:23 +00005957 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005958 {
cristy2c8b6312009-09-16 02:37:23 +00005959 const char
5960 *property;
5961
5962 property=GetImageProperty(msl_info->attributes[j],"id");
5963 if (LocaleCompare(property,value) == 0)
5964 {
5965 SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5966 break;
5967 }
cristy3ed852e2009-09-05 21:47:34 +00005968 }
cristy2c8b6312009-09-16 02:37:23 +00005969 break;
cristy3ed852e2009-09-05 21:47:34 +00005970 }
cristy2c8b6312009-09-16 02:37:23 +00005971 if (LocaleCompare(keyword,"colorspace") == 0)
5972 {
5973 long
5974 colorspace;
5975
5976 colorspace=(ColorspaceType) ParseMagickOption(
5977 MagickColorspaceOptions,MagickFalse,keyword);
5978 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00005979 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00005980 value);
5981 (void) TransformImageColorspace(msl_info->image[n],
5982 (ColorspaceType) colorspace);
5983 break;
5984 }
5985 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005986 break;
5987 }
5988 case 'D':
5989 case 'd':
5990 {
cristy2c8b6312009-09-16 02:37:23 +00005991 if (LocaleCompare(keyword,"density") == 0)
5992 {
5993 flags=ParseGeometry(value,&geometry_info);
5994 msl_info->image[n]->x_resolution=geometry_info.rho;
5995 msl_info->image[n]->y_resolution=geometry_info.sigma;
5996 if ((flags & SigmaValue) == 0)
5997 msl_info->image[n]->y_resolution=
5998 msl_info->image[n]->x_resolution;
5999 break;
6000 }
6001 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006002 break;
6003 }
6004 case 'O':
6005 case 'o':
6006 {
6007 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006008 {
6009 long opac = OpaqueOpacity,
cristy3ed852e2009-09-05 21:47:34 +00006010 len = (long) strlen( value );
6011
cristy2c8b6312009-09-16 02:37:23 +00006012 if (value[len-1] == '%') {
6013 char tmp[100];
6014 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006015 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006016 opac = (int)(QuantumRange * ((float)opac/100));
6017 } else
cristyf2f27272009-12-17 14:48:46 +00006018 opac = StringToLong( value );
cristy2c8b6312009-09-16 02:37:23 +00006019 (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6020 break;
cristy3ed852e2009-09-05 21:47:34 +00006021 }
cristy2c8b6312009-09-16 02:37:23 +00006022 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006023 break;
6024 }
6025 case 'P':
6026 case 'p':
6027 {
6028 if (LocaleCompare(keyword, "page") == 0)
6029 {
6030 char
6031 page[MaxTextExtent];
6032
6033 const char
6034 *image_option;
6035
6036 MagickStatusType
6037 flags;
6038
6039 RectangleInfo
6040 geometry;
6041
6042 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6043 image_option=GetImageOption(msl_info->image_info[n],"page");
6044 if (image_option != (const char *) NULL)
6045 flags=ParseAbsoluteGeometry(image_option,&geometry);
6046 flags=ParseAbsoluteGeometry(value,&geometry);
6047 (void) FormatMagickString(page,MaxTextExtent,"%lux%lu",
6048 geometry.width,geometry.height);
6049 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
6050 (void) FormatMagickString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
6051 geometry.width,geometry.height,geometry.x,geometry.y);
6052 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6053 msl_info->image_info[n]->page=GetPageGeometry(page);
6054 break;
6055 }
cristy2c8b6312009-09-16 02:37:23 +00006056 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006057 break;
6058 }
6059 default:
6060 {
cristy2c8b6312009-09-16 02:37:23 +00006061 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006062 break;
6063 }
6064 }
6065 }
6066 break;
6067 }
cristyb988fe72009-09-16 01:01:10 +00006068 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006069 {
6070 Image
6071 *shade_image;
6072
6073 MagickBooleanType
6074 gray;
6075
6076 /*
6077 Shade image.
6078 */
6079 if (msl_info->image[n] == (Image *) NULL)
6080 {
cristyb988fe72009-09-16 01:01:10 +00006081 ThrowMSLException(OptionError,"NoImagesDefined",
6082 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006083 break;
6084 }
6085 gray=MagickFalse;
6086 if (attributes != (const xmlChar **) NULL)
6087 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6088 {
6089 keyword=(const char *) attributes[i++];
6090 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006091 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006092 CloneString(&value,attribute);
6093 switch (*keyword)
6094 {
6095 case 'A':
6096 case 'a':
6097 {
6098 if (LocaleCompare(keyword,"azimuth") == 0)
6099 {
cristyf2f27272009-12-17 14:48:46 +00006100 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006101 break;
6102 }
6103 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6104 keyword);
6105 break;
6106 }
6107 case 'E':
6108 case 'e':
6109 {
6110 if (LocaleCompare(keyword,"elevation") == 0)
6111 {
cristyf2f27272009-12-17 14:48:46 +00006112 geometry_info.sigma=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006113 break;
6114 }
6115 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6116 keyword);
6117 break;
6118 }
6119 case 'G':
6120 case 'g':
6121 {
6122 if (LocaleCompare(keyword,"geometry") == 0)
6123 {
6124 flags=ParseGeometry(value,&geometry_info);
6125 if ((flags & SigmaValue) == 0)
6126 geometry_info.sigma=1.0;
6127 break;
6128 }
6129 if (LocaleCompare(keyword,"gray") == 0)
6130 {
6131 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
6132 value);
6133 if (option < 0)
6134 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6135 value);
6136 gray=(MagickBooleanType) option;
6137 break;
6138 }
6139 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6140 keyword);
6141 break;
6142 }
6143 default:
6144 {
6145 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6146 keyword);
6147 break;
6148 }
6149 }
6150 }
6151 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6152 geometry_info.sigma,&msl_info->image[n]->exception);
6153 if (shade_image == (Image *) NULL)
6154 break;
6155 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6156 msl_info->image[n]=shade_image;
6157 break;
6158 }
cristyb988fe72009-09-16 01:01:10 +00006159 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006160 {
6161 Image
6162 *shadow_image;
6163
6164 /*
6165 Shear image.
6166 */
6167 if (msl_info->image[n] == (Image *) NULL)
6168 {
cristyb988fe72009-09-16 01:01:10 +00006169 ThrowMSLException(OptionError,"NoImagesDefined",
6170 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006171 break;
6172 }
6173 if (attributes != (const xmlChar **) NULL)
6174 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6175 {
6176 keyword=(const char *) attributes[i++];
6177 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006178 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006179 CloneString(&value,attribute);
6180 switch (*keyword)
6181 {
6182 case 'G':
6183 case 'g':
6184 {
6185 if (LocaleCompare(keyword,"geometry") == 0)
6186 {
6187 flags=ParseGeometry(value,&geometry_info);
6188 if ((flags & SigmaValue) == 0)
6189 geometry_info.sigma=1.0;
6190 break;
6191 }
6192 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6193 keyword);
6194 break;
6195 }
6196 case 'O':
6197 case 'o':
6198 {
6199 if (LocaleCompare(keyword,"opacity") == 0)
6200 {
cristyf2f27272009-12-17 14:48:46 +00006201 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006202 break;
6203 }
6204 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6205 keyword);
6206 break;
6207 }
6208 case 'S':
6209 case 's':
6210 {
6211 if (LocaleCompare(keyword,"sigma") == 0)
6212 {
cristyf2f27272009-12-17 14:48:46 +00006213 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006214 break;
6215 }
6216 break;
6217 }
6218 case 'X':
6219 case 'x':
6220 {
6221 if (LocaleCompare(keyword,"x") == 0)
6222 {
cristyf2f27272009-12-17 14:48:46 +00006223 geometry_info.xi=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006224 break;
6225 }
6226 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6227 keyword);
6228 break;
6229 }
6230 case 'Y':
6231 case 'y':
6232 {
6233 if (LocaleCompare(keyword,"y") == 0)
6234 {
cristyf2f27272009-12-17 14:48:46 +00006235 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006236 break;
6237 }
6238 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6239 keyword);
6240 break;
6241 }
6242 default:
6243 {
6244 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6245 keyword);
6246 break;
6247 }
6248 }
6249 }
6250 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
6251 geometry_info.sigma,(long) (geometry_info.xi+0.5),(long)
6252 (geometry_info.psi+0.5),&msl_info->image[n]->exception);
6253 if (shadow_image == (Image *) NULL)
6254 break;
6255 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6256 msl_info->image[n]=shadow_image;
6257 break;
6258 }
cristyb988fe72009-09-16 01:01:10 +00006259 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006260 {
6261 double radius = 0.0,
6262 sigma = 1.0;
6263
6264 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006265 {
6266 ThrowMSLException(OptionError,"NoImagesDefined",
6267 (const char *) tag);
6268 break;
6269 }
cristy3ed852e2009-09-05 21:47:34 +00006270 /*
6271 NOTE: sharpen can have no attributes, since we use all the defaults!
6272 */
6273 if (attributes != (const xmlChar **) NULL)
6274 {
6275 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6276 {
6277 keyword=(const char *) attributes[i++];
6278 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006279 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006280 switch (*keyword)
6281 {
6282 case 'R':
6283 case 'r':
6284 {
6285 if (LocaleCompare(keyword, "radius") == 0)
6286 {
cristyf2f27272009-12-17 14:48:46 +00006287 radius = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00006288 break;
6289 }
6290 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6291 break;
6292 }
6293 case 'S':
6294 case 's':
6295 {
6296 if (LocaleCompare(keyword,"sigma") == 0)
6297 {
cristyf2f27272009-12-17 14:48:46 +00006298 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006299 break;
6300 }
6301 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6302 break;
6303 }
6304 default:
6305 {
6306 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6307 break;
6308 }
6309 }
6310 }
6311 }
6312
6313 /*
6314 sharpen image.
6315 */
6316 {
6317 Image
6318 *newImage;
6319
6320 newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6321 if (newImage == (Image *) NULL)
6322 break;
6323 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6324 msl_info->image[n]=newImage;
6325 break;
6326 }
6327 }
cristyb988fe72009-09-16 01:01:10 +00006328 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006329 {
6330 /* init the values */
6331 width = height = 0;
6332 x = y = 0;
6333
6334 if (msl_info->image[n] == (Image *) NULL)
6335 {
cristyb988fe72009-09-16 01:01:10 +00006336 ThrowMSLException(OptionError,"NoImagesDefined",
6337 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006338 break;
6339 }
6340 if (attributes == (const xmlChar **) NULL)
6341 break;
6342 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6343 {
6344 keyword=(const char *) attributes[i++];
6345 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006346 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006347 switch (*keyword)
6348 {
6349 case 'G':
6350 case 'g':
6351 {
6352 if (LocaleCompare(keyword,"geometry") == 0)
6353 {
6354 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6355 break;
6356 }
6357 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6358 break;
6359 }
6360 case 'H':
6361 case 'h':
6362 {
6363 if (LocaleCompare(keyword,"height") == 0)
6364 {
cristyf2f27272009-12-17 14:48:46 +00006365 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006366 break;
6367 }
6368 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6369 break;
6370 }
6371 case 'W':
6372 case 'w':
6373 {
6374 if (LocaleCompare(keyword,"width") == 0)
6375 {
cristyf2f27272009-12-17 14:48:46 +00006376 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006377 break;
6378 }
6379 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6380 break;
6381 }
6382 default:
6383 {
6384 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6385 break;
6386 }
6387 }
6388 }
6389
6390 /*
6391 process image.
6392 */
6393 {
6394 Image
6395 *newImage;
6396 RectangleInfo
6397 rectInfo;
6398
6399 rectInfo.height = height;
6400 rectInfo.width = width;
6401 rectInfo.x = x;
6402 rectInfo.y = y;
6403
6404
6405 newImage=ShaveImage(msl_info->image[n], &rectInfo,
6406 &msl_info->image[n]->exception);
6407 if (newImage == (Image *) NULL)
6408 break;
6409 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6410 msl_info->image[n]=newImage;
6411 }
6412
6413 break;
6414 }
cristyb988fe72009-09-16 01:01:10 +00006415 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006416 {
6417 Image
6418 *shear_image;
6419
6420 /*
6421 Shear image.
6422 */
6423 if (msl_info->image[n] == (Image *) NULL)
6424 {
cristyb988fe72009-09-16 01:01:10 +00006425 ThrowMSLException(OptionError,"NoImagesDefined",
6426 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006427 break;
6428 }
6429 if (attributes != (const xmlChar **) NULL)
6430 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6431 {
6432 keyword=(const char *) attributes[i++];
6433 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006434 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006435 CloneString(&value,attribute);
6436 switch (*keyword)
6437 {
6438 case 'F':
6439 case 'f':
6440 {
6441 if (LocaleCompare(keyword, "fill") == 0)
6442 {
6443 (void) QueryColorDatabase(value,
6444 &msl_info->image[n]->background_color,&exception);
6445 break;
6446 }
6447 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6448 keyword);
6449 break;
6450 }
6451 case 'G':
6452 case 'g':
6453 {
6454 if (LocaleCompare(keyword,"geometry") == 0)
6455 {
6456 flags=ParseGeometry(value,&geometry_info);
6457 if ((flags & SigmaValue) == 0)
6458 geometry_info.sigma=1.0;
6459 break;
6460 }
6461 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6462 keyword);
6463 break;
6464 }
6465 case 'X':
6466 case 'x':
6467 {
6468 if (LocaleCompare(keyword,"x") == 0)
6469 {
cristyf2f27272009-12-17 14:48:46 +00006470 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006471 break;
6472 }
6473 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6474 keyword);
6475 break;
6476 }
6477 case 'Y':
6478 case 'y':
6479 {
6480 if (LocaleCompare(keyword,"y") == 0)
6481 {
cristyf2f27272009-12-17 14:48:46 +00006482 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006483 break;
6484 }
6485 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6486 keyword);
6487 break;
6488 }
6489 default:
6490 {
6491 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6492 keyword);
6493 break;
6494 }
6495 }
6496 }
6497 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6498 geometry_info.sigma,&msl_info->image[n]->exception);
6499 if (shear_image == (Image *) NULL)
6500 break;
6501 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6502 msl_info->image[n]=shear_image;
6503 break;
6504 }
cristyb988fe72009-09-16 01:01:10 +00006505 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006506 {
6507 /*
6508 Signature image.
6509 */
6510 if (msl_info->image[n] == (Image *) NULL)
6511 {
cristyb988fe72009-09-16 01:01:10 +00006512 ThrowMSLException(OptionError,"NoImagesDefined",
6513 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006514 break;
6515 }
6516 if (attributes != (const xmlChar **) NULL)
6517 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6518 {
6519 keyword=(const char *) attributes[i++];
6520 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006521 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006522 CloneString(&value,attribute);
6523 switch (*keyword)
6524 {
6525 default:
6526 {
6527 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6528 keyword);
6529 break;
6530 }
6531 }
6532 }
6533 (void) SignatureImage(msl_info->image[n]);
6534 break;
6535 }
cristyb988fe72009-09-16 01:01:10 +00006536 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006537 {
6538 /*
6539 Solarize image.
6540 */
6541 if (msl_info->image[n] == (Image *) NULL)
6542 {
cristyb988fe72009-09-16 01:01:10 +00006543 ThrowMSLException(OptionError,"NoImagesDefined",
6544 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006545 break;
6546 }
6547 geometry_info.rho=QuantumRange/2.0;
6548 if (attributes != (const xmlChar **) NULL)
6549 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6550 {
6551 keyword=(const char *) attributes[i++];
6552 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006553 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006554 CloneString(&value,attribute);
6555 switch (*keyword)
6556 {
6557 case 'G':
6558 case 'g':
6559 {
6560 if (LocaleCompare(keyword,"geometry") == 0)
6561 {
6562 flags=ParseGeometry(value,&geometry_info);
6563 break;
6564 }
6565 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6566 keyword);
6567 break;
6568 }
6569 case 'T':
6570 case 't':
6571 {
6572 if (LocaleCompare(keyword,"threshold") == 0)
6573 {
cristyf2f27272009-12-17 14:48:46 +00006574 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006575 break;
6576 }
6577 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6578 keyword);
6579 break;
6580 }
6581 default:
6582 {
6583 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6584 keyword);
6585 break;
6586 }
6587 }
6588 }
6589 (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6590 break;
6591 }
cristyb988fe72009-09-16 01:01:10 +00006592 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006593 {
6594 Image
6595 *spread_image;
6596
6597 /*
6598 Spread image.
6599 */
6600 if (msl_info->image[n] == (Image *) NULL)
6601 {
cristyb988fe72009-09-16 01:01:10 +00006602 ThrowMSLException(OptionError,"NoImagesDefined",
6603 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006604 break;
6605 }
6606 if (attributes != (const xmlChar **) NULL)
6607 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6608 {
6609 keyword=(const char *) attributes[i++];
6610 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006611 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006612 CloneString(&value,attribute);
6613 switch (*keyword)
6614 {
6615 case 'G':
6616 case 'g':
6617 {
6618 if (LocaleCompare(keyword,"geometry") == 0)
6619 {
6620 flags=ParseGeometry(value,&geometry_info);
6621 if ((flags & SigmaValue) == 0)
6622 geometry_info.sigma=1.0;
6623 break;
6624 }
6625 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6626 keyword);
6627 break;
6628 }
6629 case 'R':
6630 case 'r':
6631 {
6632 if (LocaleCompare(keyword,"radius") == 0)
6633 {
cristyf2f27272009-12-17 14:48:46 +00006634 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006635 break;
6636 }
6637 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6638 keyword);
6639 break;
6640 }
6641 default:
6642 {
6643 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6644 keyword);
6645 break;
6646 }
6647 }
6648 }
6649 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6650 &msl_info->image[n]->exception);
6651 if (spread_image == (Image *) NULL)
6652 break;
6653 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6654 msl_info->image[n]=spread_image;
6655 break;
6656 }
cristyb988fe72009-09-16 01:01:10 +00006657 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006658 {
6659 Image *
6660 watermark = (Image*)NULL;
6661
6662 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006663 {
6664 ThrowMSLException(OptionError,"NoImagesDefined",
6665 (const char *) tag);
6666 break;
6667 }
cristy3ed852e2009-09-05 21:47:34 +00006668 if (attributes == (const xmlChar **) NULL)
6669 break;
6670 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6671 {
6672 keyword=(const char *) attributes[i++];
6673 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006674 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006675 switch (*keyword)
6676 {
6677 case 'I':
6678 case 'i':
6679 {
6680 if (LocaleCompare(keyword,"image") == 0)
6681 {
6682 for (j=0; j<msl_info->n;j++)
6683 {
6684 const char *
6685 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6686 if (theAttr && LocaleCompare(theAttr, value) == 0)
6687 {
6688 watermark = msl_info->image[j];
6689 break;
6690 }
6691 }
6692 break;
6693 }
6694 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6695 break;
6696 }
6697 default:
6698 {
6699 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6700 break;
6701 }
6702 }
6703 }
6704
6705 /*
6706 process image.
6707 */
6708 if ( watermark != (Image*) NULL )
6709 {
6710 Image
6711 *newImage;
6712
6713 newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6714 if (newImage == (Image *) NULL)
6715 break;
6716 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6717 msl_info->image[n]=newImage;
6718 break;
6719 } else
6720 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6721 }
cristyb988fe72009-09-16 01:01:10 +00006722 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006723 {
6724 Image *
6725 stereoImage = (Image*)NULL;
6726
6727 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006728 {
6729 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6730 break;
6731 }
cristy3ed852e2009-09-05 21:47:34 +00006732 if (attributes == (const xmlChar **) NULL)
6733 break;
6734 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6735 {
6736 keyword=(const char *) attributes[i++];
6737 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006738 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006739 switch (*keyword)
6740 {
6741 case 'I':
6742 case 'i':
6743 {
6744 if (LocaleCompare(keyword,"image") == 0)
6745 {
6746 for (j=0; j<msl_info->n;j++)
6747 {
6748 const char *
6749 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6750 if (theAttr && LocaleCompare(theAttr, value) == 0)
6751 {
6752 stereoImage = msl_info->image[j];
6753 break;
6754 }
6755 }
6756 break;
6757 }
6758 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6759 break;
6760 }
6761 default:
6762 {
6763 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6764 break;
6765 }
6766 }
6767 }
6768
6769 /*
6770 process image.
6771 */
6772 if ( stereoImage != (Image*) NULL )
6773 {
6774 Image
6775 *newImage;
6776
6777 newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6778 if (newImage == (Image *) NULL)
6779 break;
6780 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6781 msl_info->image[n]=newImage;
6782 break;
6783 } else
6784 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6785 }
cristyb988fe72009-09-16 01:01:10 +00006786 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006787 {
6788 Image
6789 *p,
6790 *q,
6791 *swap;
6792
6793 long
6794 index,
6795 swap_index;
6796
6797 if (msl_info->image[n] == (Image *) NULL)
6798 {
cristyb988fe72009-09-16 01:01:10 +00006799 ThrowMSLException(OptionError,"NoImagesDefined",
6800 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006801 break;
6802 }
6803 index=(-1);
6804 swap_index=(-2);
6805 if (attributes != (const xmlChar **) NULL)
6806 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6807 {
6808 keyword=(const char *) attributes[i++];
6809 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006810 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006811 CloneString(&value,attribute);
6812 switch (*keyword)
6813 {
6814 case 'G':
6815 case 'g':
6816 {
6817 if (LocaleCompare(keyword,"indexes") == 0)
6818 {
6819 flags=ParseGeometry(value,&geometry_info);
6820 index=(long) geometry_info.rho;
6821 if ((flags & SigmaValue) == 0)
6822 swap_index=(long) geometry_info.sigma;
6823 break;
6824 }
6825 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6826 keyword);
6827 break;
6828 }
6829 default:
6830 {
6831 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6832 keyword);
6833 break;
6834 }
6835 }
6836 }
6837 /*
6838 Swap images.
6839 */
6840 p=GetImageFromList(msl_info->image[n],index);
6841 q=GetImageFromList(msl_info->image[n],swap_index);
6842 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6843 {
cristyb988fe72009-09-16 01:01:10 +00006844 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006845 break;
6846 }
6847 swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6848 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6849 ReplaceImageInList(&q,swap);
6850 msl_info->image[n]=GetFirstImageInList(q);
6851 break;
6852 }
cristyb988fe72009-09-16 01:01:10 +00006853 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006854 {
6855 Image
6856 *swirl_image;
6857
6858 /*
6859 Swirl image.
6860 */
6861 if (msl_info->image[n] == (Image *) NULL)
6862 {
cristyb988fe72009-09-16 01:01:10 +00006863 ThrowMSLException(OptionError,"NoImagesDefined",
6864 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006865 break;
6866 }
6867 if (attributes != (const xmlChar **) NULL)
6868 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6869 {
6870 keyword=(const char *) attributes[i++];
6871 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006872 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006873 CloneString(&value,attribute);
6874 switch (*keyword)
6875 {
6876 case 'D':
6877 case 'd':
6878 {
6879 if (LocaleCompare(keyword,"degrees") == 0)
6880 {
cristyf2f27272009-12-17 14:48:46 +00006881 geometry_info.rho=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006882 break;
6883 }
6884 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6885 keyword);
6886 break;
6887 }
6888 case 'G':
6889 case 'g':
6890 {
6891 if (LocaleCompare(keyword,"geometry") == 0)
6892 {
6893 flags=ParseGeometry(value,&geometry_info);
6894 if ((flags & SigmaValue) == 0)
6895 geometry_info.sigma=1.0;
6896 break;
6897 }
6898 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6899 keyword);
6900 break;
6901 }
6902 default:
6903 {
6904 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6905 keyword);
6906 break;
6907 }
6908 }
6909 }
6910 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6911 &msl_info->image[n]->exception);
6912 if (swirl_image == (Image *) NULL)
6913 break;
6914 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6915 msl_info->image[n]=swirl_image;
6916 break;
6917 }
cristyb988fe72009-09-16 01:01:10 +00006918 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006919 {
6920 /*
6921 Sync image.
6922 */
6923 if (msl_info->image[n] == (Image *) NULL)
6924 {
cristyb988fe72009-09-16 01:01:10 +00006925 ThrowMSLException(OptionError,"NoImagesDefined",
6926 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006927 break;
6928 }
6929 if (attributes != (const xmlChar **) NULL)
6930 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6931 {
6932 keyword=(const char *) attributes[i++];
6933 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006934 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006935 CloneString(&value,attribute);
6936 switch (*keyword)
6937 {
6938 default:
6939 {
6940 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6941 keyword);
6942 break;
6943 }
6944 }
6945 }
6946 (void) SyncImage(msl_info->image[n]);
6947 break;
6948 }
6949 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6950 }
6951 case 'T':
6952 case 't':
6953 {
cristyb988fe72009-09-16 01:01:10 +00006954 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006955 {
6956 Image
6957 *texture_image;
6958
6959 /*
6960 Texture image.
6961 */
6962 if (msl_info->image[n] == (Image *) NULL)
6963 {
cristyb988fe72009-09-16 01:01:10 +00006964 ThrowMSLException(OptionError,"NoImagesDefined",
6965 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006966 break;
6967 }
6968 texture_image=NewImageList();
6969 if (attributes != (const xmlChar **) NULL)
6970 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6971 {
6972 keyword=(const char *) attributes[i++];
6973 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006974 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006975 CloneString(&value,attribute);
6976 switch (*keyword)
6977 {
6978 case 'I':
6979 case 'i':
6980 {
6981 if (LocaleCompare(keyword,"image") == 0)
6982 for (j=0; j < msl_info->n; j++)
6983 {
6984 const char
6985 *attribute;
cristyb988fe72009-09-16 01:01:10 +00006986
cristy3ed852e2009-09-05 21:47:34 +00006987 attribute=GetImageProperty(msl_info->attributes[j],"id");
6988 if ((attribute != (const char *) NULL) &&
6989 (LocaleCompare(attribute,value) == 0))
6990 {
6991 texture_image=CloneImage(msl_info->image[j],0,0,
6992 MagickFalse,&exception);
6993 break;
6994 }
6995 }
6996 break;
6997 }
6998 default:
6999 {
7000 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7001 keyword);
7002 break;
7003 }
7004 }
7005 }
7006 (void) TextureImage(msl_info->image[n],texture_image);
7007 texture_image=DestroyImage(texture_image);
7008 break;
7009 }
cristyb988fe72009-09-16 01:01:10 +00007010 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007011 {
7012 /* init the values */
7013 double threshold = 0;
7014
7015 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007016 {
7017 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7018 break;
7019 }
cristy3ed852e2009-09-05 21:47:34 +00007020 if (attributes == (const xmlChar **) NULL)
7021 break;
7022 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7023 {
7024 keyword=(const char *) attributes[i++];
7025 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007026 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007027 switch (*keyword)
7028 {
7029 case 'T':
7030 case 't':
7031 {
7032 if (LocaleCompare(keyword,"threshold") == 0)
7033 {
cristyf2f27272009-12-17 14:48:46 +00007034 threshold = StringToDouble( value );
cristy3ed852e2009-09-05 21:47:34 +00007035 break;
7036 }
7037 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7038 break;
7039 }
7040 default:
7041 {
7042 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7043 break;
7044 }
7045 }
7046 }
7047
7048 /*
7049 process image.
7050 */
7051 {
7052 BilevelImageChannel(msl_info->image[n],
7053 (ChannelType) ((long) (AllChannels &~ (long) OpacityChannel)),
7054 threshold);
7055 break;
7056 }
7057 }
cristyb988fe72009-09-16 01:01:10 +00007058 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007059 {
7060 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007061 {
7062 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7063 break;
7064 }
cristy3ed852e2009-09-05 21:47:34 +00007065 if (attributes == (const xmlChar **) NULL)
7066 break;
7067 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7068 {
7069 keyword=(const char *) attributes[i++];
7070 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007071 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007072 switch (*keyword)
7073 {
7074 case 'C':
7075 case 'c':
7076 {
7077 if (LocaleCompare(keyword,"color") == 0)
7078 {
7079 MagickPixelPacket
7080 target;
7081
7082 (void) QueryMagickColor(value,&target,&exception);
7083 (void) TransparentPaintImage(msl_info->image[n],&target,
7084 TransparentOpacity,MagickFalse);
7085 break;
7086 }
7087 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7088 break;
7089 }
7090 default:
7091 {
7092 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7093 break;
7094 }
7095 }
7096 }
7097 break;
7098 }
cristyb988fe72009-09-16 01:01:10 +00007099 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007100 {
7101 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007102 {
7103 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7104 break;
7105 }
cristy3ed852e2009-09-05 21:47:34 +00007106
7107 /* no attributes here */
7108
7109 /* process the image */
7110 {
7111 Image
7112 *newImage;
7113 RectangleInfo
7114 rectInfo;
7115
7116 /* all zeros on a crop == trim edges! */
7117 rectInfo.height = rectInfo.width = 0;
7118 rectInfo.x = rectInfo.y = 0;
7119
7120 newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7121 if (newImage == (Image *) NULL)
7122 break;
7123 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7124 msl_info->image[n]=newImage;
7125 break;
7126 }
7127 }
7128 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7129 }
7130 case 'W':
7131 case 'w':
7132 {
cristyb988fe72009-09-16 01:01:10 +00007133 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007134 {
7135 if (msl_info->image[n] == (Image *) NULL)
7136 {
cristyb988fe72009-09-16 01:01:10 +00007137 ThrowMSLException(OptionError,"NoImagesDefined",
7138 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007139 break;
7140 }
7141 if (attributes == (const xmlChar **) NULL)
7142 break;
7143 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7144 {
7145 keyword=(const char *) attributes[i++];
7146 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007147 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007148 switch (*keyword)
7149 {
7150 case 'F':
7151 case 'f':
7152 {
7153 if (LocaleCompare(keyword,"filename") == 0)
7154 {
7155 (void) CopyMagickString(msl_info->image[n]->filename,value,
7156 MaxTextExtent);
7157 break;
7158 }
cristy4582cbb2009-09-23 00:35:43 +00007159 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007160 }
7161 default:
7162 {
cristy4582cbb2009-09-23 00:35:43 +00007163 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007164 break;
7165 }
7166 }
7167 }
7168
7169 /* process */
7170 {
7171 (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7172 break;
7173 }
7174 }
7175 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7176 }
7177 default:
7178 {
7179 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7180 break;
7181 }
7182 }
7183 if ( value != NULL )
7184 value=DestroyString(value);
7185 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7186}
7187
7188static void MSLEndElement(void *context,const xmlChar *tag)
7189{
7190 long
7191 n;
7192
7193 MSLInfo
7194 *msl_info;
7195
7196 /*
7197 Called when the end of an element has been detected.
7198 */
7199 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7200 tag);
7201 msl_info=(MSLInfo *) context;
7202 n=msl_info->n;
7203 switch (*tag)
7204 {
7205 case 'C':
7206 case 'c':
7207 {
cristyb988fe72009-09-16 01:01:10 +00007208 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007209 {
7210 (void) DeleteImageProperty(msl_info->image[n],"comment");
7211 if (msl_info->content == (char *) NULL)
7212 break;
7213 StripString(msl_info->content);
7214 (void) SetImageProperty(msl_info->image[n],"comment",
7215 msl_info->content);
7216 break;
7217 }
7218 break;
7219 }
7220 case 'G':
7221 case 'g':
7222 {
cristyb988fe72009-09-16 01:01:10 +00007223 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007224 {
7225 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7226 {
7227 long i = (long)
7228 (msl_info->group_info[msl_info->number_groups-1].numImages);
7229 while ( i-- )
7230 {
7231 if (msl_info->image[msl_info->n] != (Image *) NULL)
7232 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7233 msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7234 msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7235 msl_info->n--;
7236 }
7237 }
7238 msl_info->number_groups--;
7239 }
7240 break;
7241 }
7242 case 'I':
7243 case 'i':
7244 {
cristyb988fe72009-09-16 01:01:10 +00007245 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007246 MSLPopImage(msl_info);
7247 break;
7248 }
7249 case 'L':
7250 case 'l':
7251 {
cristyb988fe72009-09-16 01:01:10 +00007252 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007253 {
7254 (void) DeleteImageProperty(msl_info->image[n],"label");
7255 if (msl_info->content == (char *) NULL)
7256 break;
7257 StripString(msl_info->content);
7258 (void) SetImageProperty(msl_info->image[n],"label",
7259 msl_info->content);
7260 break;
7261 }
7262 break;
7263 }
7264 case 'M':
7265 case 'm':
7266 {
cristyb988fe72009-09-16 01:01:10 +00007267 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007268 {
7269 /*
7270 This our base element.
7271 at the moment we don't do anything special
7272 but someday we might!
7273 */
7274 }
7275 break;
7276 }
7277 default:
7278 break;
7279 }
7280 if (msl_info->content != (char *) NULL)
7281 msl_info->content=DestroyString(msl_info->content);
7282}
7283
7284static void MSLCharacters(void *context,const xmlChar *c,int length)
7285{
7286 MSLInfo
7287 *msl_info;
7288
7289 register char
7290 *p;
7291
7292 register long
7293 i;
7294
7295 /*
7296 Receiving some characters from the parser.
7297 */
7298 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7299 " SAX.characters(%s,%d)",c,length);
7300 msl_info=(MSLInfo *) context;
7301 if (msl_info->content != (char *) NULL)
7302 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7303 strlen(msl_info->content)+length+MaxTextExtent,
7304 sizeof(*msl_info->content));
7305 else
7306 {
7307 msl_info->content=(char *) NULL;
7308 if (~length >= MaxTextExtent)
7309 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7310 sizeof(*msl_info->content));
7311 if (msl_info->content != (char *) NULL)
7312 *msl_info->content='\0';
7313 }
7314 if (msl_info->content == (char *) NULL)
7315 return;
7316 p=msl_info->content+strlen(msl_info->content);
7317 for (i=0; i < length; i++)
7318 *p++=c[i];
7319 *p='\0';
7320}
7321
7322static void MSLReference(void *context,const xmlChar *name)
7323{
7324 MSLInfo
7325 *msl_info;
7326
7327 xmlParserCtxtPtr
7328 parser;
7329
7330 /*
7331 Called when an entity reference is detected.
7332 */
7333 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7334 " SAX.reference(%s)",name);
7335 msl_info=(MSLInfo *) context;
7336 parser=msl_info->parser;
7337 if (*name == '#')
7338 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7339 else
7340 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7341}
7342
7343static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7344{
7345 MSLInfo
7346 *msl_info;
7347
7348 /*
7349 Receiving some ignorable whitespaces from the parser.
7350 */
7351 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7352 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7353 msl_info=(MSLInfo *) context;
7354}
7355
7356static void MSLProcessingInstructions(void *context,const xmlChar *target,
7357 const xmlChar *data)
7358{
7359 MSLInfo
7360 *msl_info;
7361
7362 /*
7363 A processing instruction has been parsed.
7364 */
7365 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7366 " SAX.processingInstruction(%s, %s)",
7367 target,data);
7368 msl_info=(MSLInfo *) context;
7369}
7370
7371static void MSLComment(void *context,const xmlChar *value)
7372{
7373 MSLInfo
7374 *msl_info;
7375
7376 /*
7377 A comment has been parsed.
7378 */
7379 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7380 " SAX.comment(%s)",value);
7381 msl_info=(MSLInfo *) context;
7382}
7383
7384static void MSLWarning(void *context,const char *format,...)
7385{
7386 char
7387 *message,
7388 reason[MaxTextExtent];
7389
7390 MSLInfo
7391 *msl_info;
7392
7393 va_list
7394 operands;
7395
7396 /**
7397 Display and format a warning messages, gives file, line, position and
7398 extra parameters.
7399 */
7400 va_start(operands,format);
7401 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7402 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7403 msl_info=(MSLInfo *) context;
7404#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7405 (void) vsprintf(reason,format,operands);
7406#else
7407 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7408#endif
7409 message=GetExceptionMessage(errno);
7410 ThrowMSLException(CoderError,reason,message);
7411 message=DestroyString(message);
7412 va_end(operands);
7413}
7414
7415static void MSLError(void *context,const char *format,...)
7416{
7417 char
7418 reason[MaxTextExtent];
7419
7420 MSLInfo
7421 *msl_info;
7422
7423 va_list
7424 operands;
7425
7426 /*
7427 Display and format a error formats, gives file, line, position and
7428 extra parameters.
7429 */
7430 va_start(operands,format);
7431 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7432 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7433 msl_info=(MSLInfo *) context;
7434#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7435 (void) vsprintf(reason,format,operands);
7436#else
7437 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7438#endif
7439 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7440 va_end(operands);
7441}
7442
7443static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7444{
7445 MSLInfo
7446 *msl_info;
7447
7448 xmlNodePtr
7449 child;
7450
7451 xmlParserCtxtPtr
7452 parser;
7453
7454 /*
7455 Called when a pcdata block has been parsed.
7456 */
7457 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7458 " SAX.pcdata(%s, %d)",value,length);
7459 msl_info=(MSLInfo *) context;
7460 parser=msl_info->parser;
7461 child=xmlGetLastChild(parser->node);
7462 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7463 {
7464 xmlTextConcat(child,value,length);
7465 return;
7466 }
7467 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7468}
7469
7470static void MSLExternalSubset(void *context,const xmlChar *name,
7471 const xmlChar *external_id,const xmlChar *system_id)
7472{
7473 MSLInfo
7474 *msl_info;
7475
7476 xmlParserCtxt
7477 parser_context;
7478
7479 xmlParserCtxtPtr
7480 parser;
7481
7482 xmlParserInputPtr
7483 input;
7484
7485 /*
7486 Does this document has an external subset?
7487 */
7488 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7489 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007490 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7491 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007492 msl_info=(MSLInfo *) context;
7493 parser=msl_info->parser;
7494 if (((external_id == NULL) && (system_id == NULL)) ||
7495 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7496 (msl_info->document == 0)))
7497 return;
7498 input=MSLResolveEntity(context,external_id,system_id);
7499 if (input == NULL)
7500 return;
7501 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7502 parser_context=(*parser);
7503 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7504 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7505 {
7506 parser->errNo=XML_ERR_NO_MEMORY;
7507 parser->input=parser_context.input;
7508 parser->inputNr=parser_context.inputNr;
7509 parser->inputMax=parser_context.inputMax;
7510 parser->inputTab=parser_context.inputTab;
7511 return;
7512 }
7513 parser->inputNr=0;
7514 parser->inputMax=5;
7515 parser->input=NULL;
7516 xmlPushInput(parser,input);
7517 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7518 if (input->filename == (char *) NULL)
7519 input->filename=(char *) xmlStrdup(system_id);
7520 input->line=1;
7521 input->col=1;
7522 input->base=parser->input->cur;
7523 input->cur=parser->input->cur;
7524 input->free=NULL;
7525 xmlParseExternalSubset(parser,external_id,system_id);
7526 while (parser->inputNr > 1)
7527 (void) xmlPopInput(parser);
7528 xmlFreeInputStream(parser->input);
7529 xmlFree(parser->inputTab);
7530 parser->input=parser_context.input;
7531 parser->inputNr=parser_context.inputNr;
7532 parser->inputMax=parser_context.inputMax;
7533 parser->inputTab=parser_context.inputTab;
7534}
7535
7536#if defined(__cplusplus) || defined(c_plusplus)
7537}
7538#endif
7539
7540static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7541 ExceptionInfo *exception)
7542{
cristy3ed852e2009-09-05 21:47:34 +00007543 char
7544 message[MaxTextExtent];
7545
7546 Image
7547 *msl_image;
7548
7549 int
7550 status;
7551
7552 long
7553 n;
7554
7555 MSLInfo
7556 msl_info;
7557
cristy5f6f01c2009-11-19 19:36:42 +00007558 xmlSAXHandler
7559 sax_modules;
7560
cristy3ed852e2009-09-05 21:47:34 +00007561 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007562 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007563
7564 /*
7565 Open image file.
7566 */
7567 assert(image_info != (const ImageInfo *) NULL);
7568 assert(image_info->signature == MagickSignature);
7569 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007570 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7571 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007572 assert(image != (Image **) NULL);
7573 msl_image=AcquireImage(image_info);
7574 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7575 if (status == MagickFalse)
7576 {
7577 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7578 msl_image->filename);
7579 msl_image=DestroyImageList(msl_image);
7580 return(MagickFalse);
7581 }
7582 msl_image->columns=1;
7583 msl_image->rows=1;
7584 /*
7585 Parse MSL file.
7586 */
7587 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7588 msl_info.exception=exception;
7589 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7590 sizeof(*msl_info.image_info));
7591 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7592 sizeof(*msl_info.draw_info));
7593 /* top of the stack is the MSL file itself */
cristy90823212009-12-12 20:48:33 +00007594 msl_info.image=(Image **) AcquireAlignedMemory(1,sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007595 msl_info.attributes=(Image **) AcquireMagickMemory(
7596 sizeof(*msl_info.attributes));
7597 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7598 sizeof(*msl_info.group_info));
7599 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7600 (msl_info.image == (Image **) NULL) ||
7601 (msl_info.attributes == (Image **) NULL) ||
7602 (msl_info.group_info == (MSLGroupInfo *) NULL))
7603 ThrowFatalException(ResourceLimitFatalError,
7604 "UnableToInterpretMSLImage");
7605 *msl_info.image_info=CloneImageInfo(image_info);
7606 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7607 *msl_info.attributes=AcquireImage(image_info);
7608 msl_info.group_info[0].numImages=0;
7609 /* the first slot is used to point to the MSL file image */
7610 *msl_info.image=msl_image;
7611 if (*image != (Image *) NULL)
7612 MSLPushImage(&msl_info,*image);
7613 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007614 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7615 sax_modules.internalSubset=MSLInternalSubset;
7616 sax_modules.isStandalone=MSLIsStandalone;
7617 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7618 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7619 sax_modules.resolveEntity=MSLResolveEntity;
7620 sax_modules.getEntity=MSLGetEntity;
7621 sax_modules.entityDecl=MSLEntityDeclaration;
7622 sax_modules.notationDecl=MSLNotationDeclaration;
7623 sax_modules.attributeDecl=MSLAttributeDeclaration;
7624 sax_modules.elementDecl=MSLElementDeclaration;
7625 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7626 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7627 sax_modules.startDocument=MSLStartDocument;
7628 sax_modules.endDocument=MSLEndDocument;
7629 sax_modules.startElement=MSLStartElement;
7630 sax_modules.endElement=MSLEndElement;
7631 sax_modules.reference=MSLReference;
7632 sax_modules.characters=MSLCharacters;
7633 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7634 sax_modules.processingInstruction=MSLProcessingInstructions;
7635 sax_modules.comment=MSLComment;
7636 sax_modules.warning=MSLWarning;
7637 sax_modules.error=MSLError;
7638 sax_modules.fatalError=MSLError;
7639 sax_modules.getParameterEntity=MSLGetParameterEntity;
7640 sax_modules.cdataBlock=MSLCDataBlock;
7641 sax_modules.externalSubset=MSLExternalSubset;
7642 sax_handler=(&sax_modules);
7643 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007644 msl_image->filename);
7645 while (ReadBlobString(msl_image,message) != (char *) NULL)
7646 {
7647 n=(long) strlen(message);
7648 if (n == 0)
7649 continue;
7650 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7651 if (status != 0)
7652 break;
7653 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7654 if (msl_info.exception->severity >= ErrorException)
7655 break;
7656 }
7657 if (msl_info.exception->severity == UndefinedException)
7658 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7659 xmlFreeParserCtxt(msl_info.parser);
7660 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7661 xmlCleanupParser();
7662 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7663 msl_info.group_info);
7664 if (*image == (Image *) NULL)
7665 *image=(*msl_info.image);
cristy5f6f01c2009-11-19 19:36:42 +00007666 if ((*msl_info.image)->exception.severity != UndefinedException)
7667 return(MagickFalse);
7668 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007669}
7670
7671static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7672{
7673 Image
7674 *image;
7675
7676 /*
7677 Open image file.
7678 */
7679 assert(image_info != (const ImageInfo *) NULL);
7680 assert(image_info->signature == MagickSignature);
7681 if (image_info->debug != MagickFalse)
7682 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7683 image_info->filename);
7684 assert(exception != (ExceptionInfo *) NULL);
7685 assert(exception->signature == MagickSignature);
7686 image=(Image *) NULL;
7687 (void) ProcessMSLScript(image_info,&image,exception);
7688 return(GetFirstImageInList(image));
7689}
7690#endif
7691
7692/*
7693%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7694% %
7695% %
7696% %
7697% R e g i s t e r M S L I m a g e %
7698% %
7699% %
7700% %
7701%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7702%
7703% RegisterMSLImage() adds attributes for the MSL image format to
7704% the list of supported formats. The attributes include the image format
7705% tag, a method to read and/or write the format, whether the format
7706% supports the saving of more than one frame to the same file or blob,
7707% whether the format supports native in-memory I/O, and a brief
7708% description of the format.
7709%
7710% The format of the RegisterMSLImage method is:
7711%
7712% unsigned long RegisterMSLImage(void)
7713%
7714*/
7715ModuleExport unsigned long RegisterMSLImage(void)
7716{
7717 MagickInfo
7718 *entry;
7719
7720 entry=SetMagickInfo("MSL");
7721#if defined(MAGICKCORE_XML_DELEGATE)
7722 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7723 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7724#endif
7725 entry->description=ConstantString("Magick Scripting Language");
7726 entry->module=ConstantString("MSL");
7727 (void) RegisterMagickInfo(entry);
7728 return(MagickImageCoderSignature);
7729}
7730
7731/*
7732%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7733% %
7734% %
7735% %
cristyb988fe72009-09-16 01:01:10 +00007736% S e t M S L A t t r i b u t e s %
7737% %
7738% %
7739% %
7740%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7741%
7742% SetMSLAttributes() ...
7743%
7744% The format of the SetMSLAttributes method is:
7745%
7746% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007747% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007748%
7749% A description of each parameter follows:
7750%
7751% o msl_info: the MSL info.
7752%
cristyb20775d2009-09-16 01:51:41 +00007753% o keyword: the keyword.
7754%
7755% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007756%
7757*/
cristyb20775d2009-09-16 01:51:41 +00007758static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7759 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007760{
cristy4582cbb2009-09-23 00:35:43 +00007761 Image
7762 *attributes;
7763
cristyb20775d2009-09-16 01:51:41 +00007764 DrawInfo
7765 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007766
7767 ExceptionInfo
7768 *exception;
7769
cristy4582cbb2009-09-23 00:35:43 +00007770 GeometryInfo
7771 geometry_info;
7772
cristy4fa36e42009-09-18 14:24:06 +00007773 Image
7774 *image;
7775
cristyb20775d2009-09-16 01:51:41 +00007776 ImageInfo
7777 *image_info;
7778
cristy4582cbb2009-09-23 00:35:43 +00007779 int
7780 flags;
7781
cristyb988fe72009-09-16 01:01:10 +00007782 long
7783 n;
7784
cristyb988fe72009-09-16 01:01:10 +00007785 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007786 if (keyword == (const char *) NULL)
7787 return(MagickTrue);
7788 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007789 return(MagickTrue);
7790 exception=msl_info->exception;
7791 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007792 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007793 image_info=msl_info->image_info[n];
7794 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007795 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007796 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007797 {
cristyfb758a52009-09-16 14:36:08 +00007798 case 'A':
7799 case 'a':
7800 {
7801 if (LocaleCompare(keyword,"adjoin") == 0)
7802 {
7803 long
7804 adjoin;
7805
7806 adjoin=ParseMagickOption(MagickBooleanOptions,MagickFalse,value);
7807 if (adjoin < 0)
7808 ThrowMSLException(OptionError,"UnrecognizedType",value);
7809 image_info->adjoin=(MagickBooleanType) adjoin;
7810 break;
7811 }
cristy4fa36e42009-09-18 14:24:06 +00007812 if (LocaleCompare(keyword,"alpha") == 0)
7813 {
7814 long
7815 alpha;
7816
7817 alpha=ParseMagickOption(MagickAlphaOptions,MagickFalse,value);
7818 if (alpha < 0)
7819 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007820 if (image != (Image *) NULL)
7821 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha);
7822 break;
7823 }
7824 if (LocaleCompare(keyword,"antialias") == 0)
7825 {
7826 long
7827 antialias;
7828
7829 antialias=ParseMagickOption(MagickBooleanOptions,MagickFalse,value);
7830 if (antialias < 0)
7831 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7832 image_info->antialias=(MagickBooleanType) antialias;
7833 break;
7834 }
7835 if (LocaleCompare(keyword,"area-limit") == 0)
7836 {
7837 MagickSizeType
7838 limit;
7839
7840 limit=MagickResourceInfinity;
7841 if (LocaleCompare(value,"unlimited") != 0)
cristyf2f27272009-12-17 14:48:46 +00007842 limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007843 (void) SetMagickResourceLimit(AreaResource,limit);
7844 break;
7845 }
7846 if (LocaleCompare(keyword,"attenuate") == 0)
7847 {
7848 (void) SetImageOption(image_info,keyword,value);
7849 break;
7850 }
7851 if (LocaleCompare(keyword,"authenticate") == 0)
7852 {
7853 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007854 break;
7855 }
cristyfb758a52009-09-16 14:36:08 +00007856 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7857 break;
7858 }
cristyb20775d2009-09-16 01:51:41 +00007859 case 'B':
7860 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007861 {
cristyb20775d2009-09-16 01:51:41 +00007862 if (LocaleCompare(keyword,"background") == 0)
7863 {
cristy2c8b6312009-09-16 02:37:23 +00007864 (void) QueryColorDatabase(value,&image_info->background_color,
cristyb20775d2009-09-16 01:51:41 +00007865 exception);
7866 break;
7867 }
cristy4582cbb2009-09-23 00:35:43 +00007868 if (LocaleCompare(keyword,"bias") == 0)
7869 {
7870 if (image == (Image *) NULL)
7871 break;
cristyf2f27272009-12-17 14:48:46 +00007872 image->bias=SiPrefixToDouble(value,QuantumRange);
cristy4582cbb2009-09-23 00:35:43 +00007873 break;
7874 }
7875 if (LocaleCompare(keyword,"blue-primary") == 0)
7876 {
7877 if (image == (Image *) NULL)
7878 break;
7879 flags=ParseGeometry(value,&geometry_info);
7880 image->chromaticity.blue_primary.x=geometry_info.rho;
7881 image->chromaticity.blue_primary.y=geometry_info.sigma;
7882 if ((flags & SigmaValue) == 0)
7883 image->chromaticity.blue_primary.y=
7884 image->chromaticity.blue_primary.x;
7885 break;
7886 }
cristy2c8b6312009-09-16 02:37:23 +00007887 if (LocaleCompare(keyword,"bordercolor") == 0)
7888 {
7889 (void) QueryColorDatabase(value,&image_info->border_color,
7890 exception);
7891 break;
7892 }
7893 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7894 break;
7895 }
7896 case 'D':
7897 case 'd':
7898 {
7899 if (LocaleCompare(keyword,"density") == 0)
7900 {
7901 (void) CloneString(&image_info->density,value);
7902 (void) CloneString(&draw_info->density,value);
7903 break;
7904 }
cristyb20775d2009-09-16 01:51:41 +00007905 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7906 break;
7907 }
7908 case 'F':
7909 case 'f':
7910 {
7911 if (LocaleCompare(keyword,"fill") == 0)
7912 {
cristy2c8b6312009-09-16 02:37:23 +00007913 (void) QueryColorDatabase(value,&draw_info->fill,exception);
cristya30afaf2009-09-22 13:42:12 +00007914 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00007915 break;
7916 }
cristy4582cbb2009-09-23 00:35:43 +00007917 if (LocaleCompare(keyword,"filename") == 0)
7918 {
7919 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7920 break;
7921 }
7922 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7923 break;
7924 }
7925 case 'G':
7926 case 'g':
7927 {
7928 if (LocaleCompare(keyword,"gravity") == 0)
7929 {
7930 long
7931 gravity;
7932
7933 gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,value);
7934 if (gravity < 0)
7935 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7936 (void) SetImageOption(image_info,keyword,value);
7937 break;
7938 }
cristyb20775d2009-09-16 01:51:41 +00007939 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7940 break;
7941 }
7942 case 'I':
7943 case 'i':
7944 {
7945 if (LocaleCompare(keyword,"id") == 0)
7946 {
cristy4582cbb2009-09-23 00:35:43 +00007947 (void) SetImageProperty(attributes,keyword,value);
cristy2c8b6312009-09-16 02:37:23 +00007948 break;
7949 }
7950 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7951 break;
7952 }
7953 case 'M':
7954 case 'm':
7955 {
7956 if (LocaleCompare(keyword,"magick") == 0)
7957 {
7958 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
7959 break;
7960 }
cristy2c8b6312009-09-16 02:37:23 +00007961 if (LocaleCompare(keyword,"mattecolor") == 0)
7962 {
7963 (void) QueryColorDatabase(value,&image_info->matte_color,
7964 exception);
cristyb20775d2009-09-16 01:51:41 +00007965 break;
7966 }
7967 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7968 break;
7969 }
7970 case 'P':
7971 case 'p':
7972 {
7973 if (LocaleCompare(keyword,"pointsize") == 0)
7974 {
cristyf2f27272009-12-17 14:48:46 +00007975 image_info->pointsize=StringToDouble(value);
7976 draw_info->pointsize=StringToDouble(value);
cristyb20775d2009-09-16 01:51:41 +00007977 break;
7978 }
7979 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7980 break;
7981 }
cristy4582cbb2009-09-23 00:35:43 +00007982 case 'Q':
7983 case 'q':
7984 {
7985 if (LocaleCompare(keyword,"quality") == 0)
7986 {
cristyf2f27272009-12-17 14:48:46 +00007987 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00007988 if (image == (Image *) NULL)
7989 break;
cristyf2f27272009-12-17 14:48:46 +00007990 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00007991 break;
7992 }
7993 break;
7994 }
cristyb20775d2009-09-16 01:51:41 +00007995 case 'S':
7996 case 's':
7997 {
7998 if (LocaleCompare(keyword,"size") == 0)
7999 {
cristy2c8b6312009-09-16 02:37:23 +00008000 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008001 break;
8002 }
8003 if (LocaleCompare(keyword,"stroke") == 0)
8004 {
cristy2c8b6312009-09-16 02:37:23 +00008005 (void) QueryColorDatabase(value,&draw_info->stroke,exception);
cristya30afaf2009-09-22 13:42:12 +00008006 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008007 break;
8008 }
8009 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8010 break;
8011 }
8012 default:
8013 {
8014 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8015 break;
cristyb988fe72009-09-16 01:01:10 +00008016 }
8017 }
8018 return(MagickTrue);
8019}
8020
8021/*
8022%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8023% %
8024% %
8025% %
cristy3ed852e2009-09-05 21:47:34 +00008026% U n r e g i s t e r M S L I m a g e %
8027% %
8028% %
8029% %
8030%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8031%
8032% UnregisterMSLImage() removes format registrations made by the
8033% MSL module from the list of supported formats.
8034%
8035% The format of the UnregisterMSLImage method is:
8036%
8037% UnregisterMSLImage(void)
8038%
8039*/
8040ModuleExport void UnregisterMSLImage(void)
8041{
8042 (void) UnregisterMagickInfo("MSL");
8043}
8044
8045#if defined(MAGICKCORE_XML_DELEGATE)
8046/*
8047%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8048% %
8049% %
8050% %
8051% W r i t e M S L I m a g e %
8052% %
8053% %
8054% %
8055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8056%
8057% WriteMSLImage() writes an image to a file in MVG image format.
8058%
8059% The format of the WriteMSLImage method is:
8060%
8061% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8062%
8063% A description of each parameter follows.
8064%
8065% o image_info: the image info.
8066%
8067% o image: The image.
8068%
8069*/
8070static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8071{
8072 assert(image_info != (const ImageInfo *) NULL);
8073 assert(image_info->signature == MagickSignature);
8074 assert(image != (Image *) NULL);
8075 assert(image->signature == MagickSignature);
8076 if (image->debug != MagickFalse)
8077 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8078 (void) ReferenceImage(image);
8079 (void) ProcessMSLScript(image_info,&image,&image->exception);
8080 return(MagickTrue);
8081}
8082#endif