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