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