blob: d2346db292ce305a54001d3980776352a60c5c34 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% M M SSSSS L %
7% MM MM SS L %
8% M M M SSS L %
9% M M SS L %
10% M M SSSSS LLLLL %
11% %
12% %
13% Execute Magick Scripting Language Scripts. %
14% %
15% Software Design %
16% John Cristy %
17% Leonard Rosenthol %
18% William Radcliffe %
19% December 2001 %
20% %
21% %
cristy16af1cb2009-12-11 21:38:29 +000022% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000023% dedicated to making software imaging solutions freely available. %
24% %
25% You may not use this file except in compliance with the License. You may %
26% obtain a copy of the License at %
27% %
28% http://www.imagemagick.org/script/license.php %
29% %
30% Unless required by applicable law or agreed to in writing, software %
31% distributed under the License is distributed on an "AS IS" BASIS, %
32% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
33% See the License for the specific language governing permissions and %
34% limitations under the License. %
35% %
36%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37%
38%
39*/
40
41/*
42 Include declarations.
43*/
44#include "magick/studio.h"
45#include "magick/annotate.h"
46#include "magick/artifact.h"
47#include "magick/blob.h"
48#include "magick/blob-private.h"
49#include "magick/cache.h"
50#include "magick/cache-view.h"
51#include "magick/color.h"
cristy316d5172009-09-17 19:31:25 +000052#include "magick/colormap.h"
cristy3ed852e2009-09-05 21:47:34 +000053#include "magick/color-private.h"
54#include "magick/composite.h"
55#include "magick/constitute.h"
56#include "magick/decorate.h"
57#include "magick/display.h"
58#include "magick/draw.h"
59#include "magick/effect.h"
60#include "magick/enhance.h"
61#include "magick/exception.h"
62#include "magick/exception-private.h"
63#include "magick/fx.h"
64#include "magick/geometry.h"
65#include "magick/image.h"
66#include "magick/image-private.h"
67#include "magick/list.h"
68#include "magick/log.h"
69#include "magick/magick.h"
70#include "magick/memory_.h"
71#include "magick/option.h"
72#include "magick/paint.h"
cristy4fa36e42009-09-18 14:24:06 +000073#include "magick/profile.h"
cristy3ed852e2009-09-05 21:47:34 +000074#include "magick/property.h"
75#include "magick/quantize.h"
76#include "magick/quantum-private.h"
cristy4fa36e42009-09-18 14:24:06 +000077#include "magick/registry.h"
cristy3ed852e2009-09-05 21:47:34 +000078#include "magick/resize.h"
cristy4582cbb2009-09-23 00:35:43 +000079#include "magick/resource_.h"
cristy3ed852e2009-09-05 21:47:34 +000080#include "magick/segment.h"
81#include "magick/shear.h"
82#include "magick/signature.h"
83#include "magick/static.h"
84#include "magick/string_.h"
85#include "magick/module.h"
86#include "magick/transform.h"
87#include "magick/threshold.h"
88#include "magick/utility.h"
89#if defined(MAGICKCORE_XML_DELEGATE)
90# if defined(__WINDOWS__)
91# if defined(__MINGW32__)
92# define _MSC_VER
93# else
94# include <win32config.h>
95# endif
96# endif
97# include <libxml/parser.h>
98# include <libxml/xmlmemory.h>
99# include <libxml/parserInternals.h>
100# include <libxml/xmlerror.h>
101#endif
102
103/*
104 Define Declatations.
105*/
106#define ThrowMSLException(severity,tag,reason) \
107 (void) ThrowMagickException(msl_info->exception,GetMagickModule(),severity, \
108 tag,"`%s'",reason);
109
110/*
111 Typedef declaractions.
112*/
113typedef struct _MSLGroupInfo
114{
115 unsigned long
116 numImages; /* how many images are in this group */
117} MSLGroupInfo;
118
119typedef struct _MSLInfo
120{
121 ExceptionInfo
122 *exception;
123
124 long
125 n,
126 number_groups;
127
128 ImageInfo
129 **image_info;
130
131 DrawInfo
132 **draw_info;
133
134 Image
135 **attributes,
136 **image;
137
138 char
139 *content;
140
141 MSLGroupInfo
142 *group_info;
143
144#if defined(MAGICKCORE_XML_DELEGATE)
145 xmlParserCtxtPtr
146 parser;
147
148 xmlDocPtr
149 document;
150#endif
151} MSLInfo;
152
153/*
154 Forward declarations.
155*/
156#if defined(MAGICKCORE_XML_DELEGATE)
157static MagickBooleanType
158 WriteMSLImage(const ImageInfo *,Image *);
cristyb988fe72009-09-16 01:01:10 +0000159
160static MagickBooleanType
cristyb20775d2009-09-16 01:51:41 +0000161 SetMSLAttributes(MSLInfo *,const char *,const char *);
cristy3ed852e2009-09-05 21:47:34 +0000162#endif
163
164#if defined(MAGICKCORE_XML_DELEGATE)
cristyb988fe72009-09-16 01:01:10 +0000165
cristy3ed852e2009-09-05 21:47:34 +0000166/*
167%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
168% %
169% %
170% %
171% R e a d M S L I m a g e %
172% %
173% %
174% %
175%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
176%
177% ReadMSLImage() reads a Magick Scripting Language file and returns it.
178% It allocates the memory necessary for the new Image structure and returns a
179% pointer to the new image.
180%
181% The format of the ReadMSLImage method is:
182%
183% Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
184%
185% A description of each parameter follows:
186%
187% o image_info: the image info.
188%
189% o exception: return any errors or warnings in this structure.
190%
cristy3ed852e2009-09-05 21:47:34 +0000191*/
192
193#if defined(__cplusplus) || defined(c_plusplus)
194extern "C" {
195#endif
196
cristy4fa36e42009-09-18 14:24:06 +0000197static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
198 ExceptionInfo *exception)
199{
200 char
201 key[MaxTextExtent];
202
203 ExceptionInfo
204 *sans_exception;
205
206 Image
207 *image;
208
209 ImageInfo
210 *read_info;
211
212 (void) FormatMagickString(key,MaxTextExtent,"cache:%s",path);
213 sans_exception=AcquireExceptionInfo();
214 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
215 sans_exception=DestroyExceptionInfo(sans_exception);
216 if (image != (Image *) NULL)
217 return(image);
218 read_info=CloneImageInfo(image_info);
219 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
220 image=ReadImage(read_info,exception);
221 read_info=DestroyImageInfo(read_info);
222 if (image != (Image *) NULL)
223 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
224 return(image);
225}
226
227static int IsPathDirectory(const char *path)
228{
229 MagickBooleanType
230 status;
231
232 struct stat
233 attributes;
234
235 if ((path == (const char *) NULL) || (*path == '\0'))
236 return(MagickFalse);
237 status=GetPathAttributes(path,&attributes);
238 if (status == MagickFalse)
239 return(-1);
240 if (S_ISDIR(attributes.st_mode) == 0)
241 return(0);
242 return(1);
243}
244
cristy3ed852e2009-09-05 21:47:34 +0000245static int MSLIsStandalone(void *context)
246{
247 MSLInfo
248 *msl_info;
249
250 /*
251 Is this document tagged standalone?
252 */
253 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.MSLIsStandalone()");
254 msl_info=(MSLInfo *) context;
255 return(msl_info->document->standalone == 1);
256}
257
258static int MSLHasInternalSubset(void *context)
259{
260 MSLInfo
261 *msl_info;
262
263 /*
264 Does this document has an internal subset?
265 */
266 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
267 " SAX.MSLHasInternalSubset()");
268 msl_info=(MSLInfo *) context;
269 return(msl_info->document->intSubset != NULL);
270}
271
272static int MSLHasExternalSubset(void *context)
273{
274 MSLInfo
275 *msl_info;
276
277 /*
278 Does this document has an external subset?
279 */
280 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
281 " SAX.MSLHasExternalSubset()");
282 msl_info=(MSLInfo *) context;
283 return(msl_info->document->extSubset != NULL);
284}
285
286static void MSLInternalSubset(void *context,const xmlChar *name,
287 const xmlChar *external_id,const xmlChar *system_id)
288{
289 MSLInfo
290 *msl_info;
291
292 /*
293 Does this document has an internal subset?
294 */
295 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
296 " SAX.internalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000297 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
298 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +0000299 msl_info=(MSLInfo *) context;
300 (void) xmlCreateIntSubset(msl_info->document,name,external_id,system_id);
301}
302
303static xmlParserInputPtr MSLResolveEntity(void *context,
304 const xmlChar *public_id,const xmlChar *system_id)
305{
306 MSLInfo
307 *msl_info;
308
309 xmlParserInputPtr
310 stream;
311
312 /*
313 Special entity resolver, better left to the parser, it has more
314 context than the application layer. The default behaviour is to
315 not resolve the entities, in that case the ENTITY_REF nodes are
316 built in the structure (and the parameter values).
317 */
318 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
319 " SAX.resolveEntity(%s, %s)",
cristyb988fe72009-09-16 01:01:10 +0000320 (public_id != (const xmlChar *) NULL ? (const char *) public_id : "none"),
321 (system_id != (const xmlChar *) NULL ? (const char *) system_id : "none"));
cristy3ed852e2009-09-05 21:47:34 +0000322 msl_info=(MSLInfo *) context;
323 stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
324 public_id,msl_info->parser);
325 return(stream);
326}
327
328static xmlEntityPtr MSLGetEntity(void *context,const xmlChar *name)
329{
330 MSLInfo
331 *msl_info;
332
333 /*
334 Get an entity by name.
335 */
336 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000337 " SAX.MSLGetEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000338 msl_info=(MSLInfo *) context;
339 return(xmlGetDocEntity(msl_info->document,name));
340}
341
342static xmlEntityPtr MSLGetParameterEntity(void *context,const xmlChar *name)
343{
344 MSLInfo
345 *msl_info;
346
347 /*
348 Get a parameter entity by name.
349 */
350 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000351 " SAX.getParameterEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000352 msl_info=(MSLInfo *) context;
353 return(xmlGetParameterEntity(msl_info->document,name));
354}
355
356static void MSLEntityDeclaration(void *context,const xmlChar *name,int type,
357 const xmlChar *public_id,const xmlChar *system_id,xmlChar *content)
358{
359 MSLInfo
360 *msl_info;
361
362 /*
363 An entity definition has been parsed.
364 */
365 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
366 " SAX.entityDecl(%s, %d, %s, %s, %s)",name,type,
cristyb988fe72009-09-16 01:01:10 +0000367 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
368 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
369 content);
cristy3ed852e2009-09-05 21:47:34 +0000370 msl_info=(MSLInfo *) context;
371 if (msl_info->parser->inSubset == 1)
372 (void) xmlAddDocEntity(msl_info->document,name,type,public_id,system_id,
373 content);
374 else
375 if (msl_info->parser->inSubset == 2)
376 (void) xmlAddDtdEntity(msl_info->document,name,type,public_id,system_id,
377 content);
378}
379
380static void MSLAttributeDeclaration(void *context,const xmlChar *element,
381 const xmlChar *name,int type,int value,const xmlChar *default_value,
382 xmlEnumerationPtr tree)
383{
384 MSLInfo
385 *msl_info;
386
387 xmlChar
388 *fullname,
389 *prefix;
390
391 xmlParserCtxtPtr
392 parser;
393
394 /*
395 An attribute definition has been parsed.
396 */
397 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
398 " SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",element,name,type,value,
399 default_value);
400 msl_info=(MSLInfo *) context;
401 fullname=(xmlChar *) NULL;
402 prefix=(xmlChar *) NULL;
403 parser=msl_info->parser;
404 fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
405 if (parser->inSubset == 1)
406 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->intSubset,
407 element,fullname,prefix,(xmlAttributeType) type,
408 (xmlAttributeDefault) value,default_value,tree);
409 else
410 if (parser->inSubset == 2)
411 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->extSubset,
412 element,fullname,prefix,(xmlAttributeType) type,
413 (xmlAttributeDefault) value,default_value,tree);
414 if (prefix != (xmlChar *) NULL)
415 xmlFree(prefix);
416 if (fullname != (xmlChar *) NULL)
417 xmlFree(fullname);
418}
419
420static void MSLElementDeclaration(void *context,const xmlChar *name,int type,
421 xmlElementContentPtr content)
422{
423 MSLInfo
424 *msl_info;
425
426 xmlParserCtxtPtr
427 parser;
428
429 /*
430 An element definition has been parsed.
431 */
432 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
433 " SAX.elementDecl(%s, %d, ...)",name,type);
434 msl_info=(MSLInfo *) context;
435 parser=msl_info->parser;
436 if (parser->inSubset == 1)
437 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->intSubset,
438 name,(xmlElementTypeVal) type,content);
439 else
440 if (parser->inSubset == 2)
441 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->extSubset,
442 name,(xmlElementTypeVal) type,content);
443}
444
445static void MSLNotationDeclaration(void *context,const xmlChar *name,
446 const xmlChar *public_id,const xmlChar *system_id)
447{
448 MSLInfo
449 *msl_info;
450
451 xmlParserCtxtPtr
452 parser;
453
454 /*
455 What to do when a notation declaration has been parsed.
456 */
457 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
458 " SAX.notationDecl(%s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000459 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
460 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none");
cristy3ed852e2009-09-05 21:47:34 +0000461 msl_info=(MSLInfo *) context;
462 parser=msl_info->parser;
463 if (parser->inSubset == 1)
464 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
465 name,public_id,system_id);
466 else
467 if (parser->inSubset == 2)
468 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
469 name,public_id,system_id);
470}
471
472static void MSLUnparsedEntityDeclaration(void *context,const xmlChar *name,
473 const xmlChar *public_id,const xmlChar *system_id,const xmlChar *notation)
474{
475 MSLInfo
476 *msl_info;
477
478 /*
479 What to do when an unparsed entity declaration is parsed.
480 */
481 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
482 " SAX.unparsedEntityDecl(%s, %s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000483 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
484 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
485 notation);
cristy3ed852e2009-09-05 21:47:34 +0000486 msl_info=(MSLInfo *) context;
487 (void) xmlAddDocEntity(msl_info->document,name,
488 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,public_id,system_id,notation);
489
490}
491
492static void MSLSetDocumentLocator(void *context,xmlSAXLocatorPtr location)
493{
494 MSLInfo
495 *msl_info;
496
497 /*
498 Receive the document locator at startup, actually xmlDefaultSAXLocator.
499 */
500 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
501 " SAX.setDocumentLocator()\n");
502 (void) location;
503 msl_info=(MSLInfo *) context;
504}
505
506static void MSLStartDocument(void *context)
507{
508 MSLInfo
509 *msl_info;
510
511 xmlParserCtxtPtr
512 parser;
513
514 /*
515 Called when the document start being processed.
516 */
517 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
518 " SAX.startDocument()");
519 msl_info=(MSLInfo *) context;
520 parser=msl_info->parser;
521 msl_info->document=xmlNewDoc(parser->version);
522 if (msl_info->document == (xmlDocPtr) NULL)
523 return;
524 if (parser->encoding == NULL)
525 msl_info->document->encoding=NULL;
526 else
527 msl_info->document->encoding=xmlStrdup(parser->encoding);
528 msl_info->document->standalone=parser->standalone;
529}
530
531static void MSLEndDocument(void *context)
532{
533 MSLInfo
534 *msl_info;
535
536 /*
537 Called when the document end has been detected.
538 */
539 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endDocument()");
540 msl_info=(MSLInfo *) context;
541 if (msl_info->content != (char *) NULL)
542 msl_info->content=DestroyString(msl_info->content);
543}
544
545static void MSLPushImage(MSLInfo *msl_info,Image *image)
546{
547 long
548 n;
549
550 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
551 assert(msl_info != (MSLInfo *) NULL);
552 msl_info->n++;
553 n=msl_info->n;
554 msl_info->image_info=(ImageInfo **) ResizeQuantumMemory(msl_info->image_info,
555 (n+1),sizeof(*msl_info->image_info));
556 msl_info->draw_info=(DrawInfo **) ResizeQuantumMemory(msl_info->draw_info,
557 (n+1),sizeof(*msl_info->draw_info));
558 msl_info->attributes=(Image **) ResizeQuantumMemory(msl_info->attributes,
559 (n+1),sizeof(*msl_info->attributes));
560 msl_info->image=(Image **) ResizeQuantumMemory(msl_info->image,(n+1),
561 sizeof(*msl_info->image));
562 if ((msl_info->image_info == (ImageInfo **) NULL) ||
563 (msl_info->draw_info == (DrawInfo **) NULL) ||
564 (msl_info->attributes == (Image **) NULL) ||
565 (msl_info->image == (Image **) NULL))
566 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
567 msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
568 msl_info->draw_info[n]=CloneDrawInfo(msl_info->image_info[n-1],
569 msl_info->draw_info[n-1]);
570 if (image == (Image *) NULL)
571 msl_info->attributes[n]=AcquireImage(msl_info->image_info[n]);
572 else
573 msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,&image->exception);
574 msl_info->image[n]=(Image *) image;
575 if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
576 (msl_info->attributes[n] == (Image *) NULL))
577 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
578 if (msl_info->number_groups != 0)
579 msl_info->group_info[msl_info->number_groups-1].numImages++;
580}
581
582static void MSLPopImage(MSLInfo *msl_info)
583{
584 if (msl_info->number_groups != 0)
585 return;
586 if (msl_info->image[msl_info->n] != (Image *) NULL)
587 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
588 msl_info->attributes[msl_info->n]=DestroyImage(
589 msl_info->attributes[msl_info->n]);
590 msl_info->image_info[msl_info->n]=DestroyImageInfo(
591 msl_info->image_info[msl_info->n]);
592 msl_info->n--;
593}
594
595static void MSLStartElement(void *context,const xmlChar *tag,
596 const xmlChar **attributes)
597{
598 AffineMatrix
599 affine,
600 current;
601
602 ChannelType
603 channel;
604
605 char
606 key[MaxTextExtent],
607 *value;
608
609 const char
610 *attribute,
611 *keyword;
612
613 double
614 angle;
615
616 DrawInfo
617 *draw_info;
618
619 ExceptionInfo
620 exception;
621
622 GeometryInfo
623 geometry_info;
624
625 Image
626 *image;
627
628 int
629 flags;
630
631 long
632 option,
633 j,
634 n,
635 x,
636 y;
637
638 MSLInfo
639 *msl_info;
640
641 RectangleInfo
642 geometry;
643
644 register long
645 i;
646
647 unsigned long
648 height,
649 width;
650
651 /*
652 Called when an opening tag has been processed.
653 */
654 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
655 " SAX.startElement(%s",tag);
656 GetExceptionInfo(&exception);
657 msl_info=(MSLInfo *) context;
658 n=msl_info->n;
659 keyword=(const char *) NULL;
660 value=(char *) NULL;
661 SetGeometryInfo(&geometry_info);
662 channel=DefaultChannels;
663 switch (*tag)
664 {
665 case 'A':
666 case 'a':
667 {
cristyb988fe72009-09-16 01:01:10 +0000668 if (LocaleCompare((const char *) tag,"add-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000669 {
670 Image
671 *noise_image;
672
673 NoiseType
674 noise;
675
676 /*
677 Add noise image.
678 */
679 if (msl_info->image[n] == (Image *) NULL)
680 {
cristyb988fe72009-09-16 01:01:10 +0000681 ThrowMSLException(OptionError,"NoImagesDefined",
682 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000683 break;
684 }
685 noise=UniformNoise;
686 if (attributes != (const xmlChar **) NULL)
687 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
688 {
689 keyword=(const char *) attributes[i++];
690 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +0000691 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +0000692 CloneString(&value,attribute);
693 switch (*keyword)
694 {
695 case 'C':
696 case 'c':
697 {
698 if (LocaleCompare(keyword,"channel") == 0)
699 {
700 option=ParseChannelOption(value);
701 if (option < 0)
702 ThrowMSLException(OptionError,"UnrecognizedChannelType",
703 value);
704 channel=(ChannelType) option;
705 break;
706 }
707 ThrowMSLException(OptionError,"UnrecognizedAttribute",
708 keyword);
709 break;
710 }
711 case 'N':
712 case 'n':
713 {
714 if (LocaleCompare(keyword,"noise") == 0)
715 {
716 option=ParseMagickOption(MagickNoiseOptions,MagickFalse,
717 value);
718 if (option < 0)
719 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
720 value);
721 noise=(NoiseType) option;
722 break;
723 }
724 ThrowMSLException(OptionError,"UnrecognizedAttribute",
725 keyword);
726 break;
727 }
728 default:
729 {
730 ThrowMSLException(OptionError,"UnrecognizedAttribute",
731 keyword);
732 break;
733 }
734 }
735 }
736 noise_image=AddNoiseImageChannel(msl_info->image[n],channel,noise,
737 &msl_info->image[n]->exception);
738 if (noise_image == (Image *) NULL)
739 break;
740 msl_info->image[n]=DestroyImage(msl_info->image[n]);
741 msl_info->image[n]=noise_image;
742 break;
743 }
cristyb988fe72009-09-16 01:01:10 +0000744 if (LocaleCompare((const char *) tag,"annotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000745 {
746 char
747 text[MaxTextExtent];
748
749 /*
750 Annotate image.
751 */
752 if (msl_info->image[n] == (Image *) NULL)
753 {
cristyb988fe72009-09-16 01:01:10 +0000754 ThrowMSLException(OptionError,"NoImagesDefined",
755 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000756 break;
757 }
758 draw_info=CloneDrawInfo(msl_info->image_info[n],
759 msl_info->draw_info[n]);
760 angle=0.0;
761 current=draw_info->affine;
762 GetAffineMatrix(&affine);
763 if (attributes != (const xmlChar **) NULL)
764 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
765 {
766 keyword=(const char *) attributes[i++];
767 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +0000768 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +0000769 CloneString(&value,attribute);
770 switch (*keyword)
771 {
772 case 'A':
773 case 'a':
774 {
775 if (LocaleCompare(keyword,"affine") == 0)
776 {
777 char
778 *p;
779
780 p=value;
781 draw_info->affine.sx=strtod(p,&p);
782 if (*p ==',')
783 p++;
784 draw_info->affine.rx=strtod(p,&p);
785 if (*p ==',')
786 p++;
787 draw_info->affine.ry=strtod(p,&p);
788 if (*p ==',')
789 p++;
790 draw_info->affine.sy=strtod(p,&p);
791 if (*p ==',')
792 p++;
793 draw_info->affine.tx=strtod(p,&p);
794 if (*p ==',')
795 p++;
796 draw_info->affine.ty=strtod(p,&p);
797 break;
798 }
799 if (LocaleCompare(keyword,"align") == 0)
800 {
801 option=ParseMagickOption(MagickAlignOptions,MagickFalse,
802 value);
803 if (option < 0)
804 ThrowMSLException(OptionError,"UnrecognizedAlignType",
805 value);
806 draw_info->align=(AlignType) option;
807 break;
808 }
809 if (LocaleCompare(keyword,"antialias") == 0)
810 {
811 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
812 value);
813 if (option < 0)
814 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
815 value);
816 draw_info->stroke_antialias=(MagickBooleanType) option;
817 draw_info->text_antialias=(MagickBooleanType) option;
818 break;
819 }
820 ThrowMSLException(OptionError,"UnrecognizedAttribute",
821 keyword);
822 break;
823 }
824 case 'D':
825 case 'd':
826 {
827 if (LocaleCompare(keyword,"density") == 0)
828 {
829 CloneString(&draw_info->density,value);
830 break;
831 }
832 ThrowMSLException(OptionError,"UnrecognizedAttribute",
833 keyword);
834 break;
835 }
836 case 'E':
837 case 'e':
838 {
839 if (LocaleCompare(keyword,"encoding") == 0)
840 {
841 CloneString(&draw_info->encoding,value);
842 break;
843 }
844 ThrowMSLException(OptionError,"UnrecognizedAttribute",
845 keyword);
846 break;
847 }
848 case 'F':
849 case 'f':
850 {
851 if (LocaleCompare(keyword, "fill") == 0)
852 {
853 (void) QueryColorDatabase(value,&draw_info->fill,
854 &exception);
855 break;
856 }
857 if (LocaleCompare(keyword,"family") == 0)
858 {
859 CloneString(&draw_info->family,value);
860 break;
861 }
862 if (LocaleCompare(keyword,"font") == 0)
863 {
864 CloneString(&draw_info->font,value);
865 break;
866 }
867 ThrowMSLException(OptionError,"UnrecognizedAttribute",
868 keyword);
869 break;
870 }
871 case 'G':
872 case 'g':
873 {
874 if (LocaleCompare(keyword,"geometry") == 0)
875 {
876 flags=ParsePageGeometry(msl_info->image[n],value,
877 &geometry,&exception);
878 if ((flags & HeightValue) == 0)
879 geometry.height=geometry.width;
880 break;
881 }
882 if (LocaleCompare(keyword,"gravity") == 0)
883 {
884 option=ParseMagickOption(MagickGravityOptions,MagickFalse,
885 value);
886 if (option < 0)
887 ThrowMSLException(OptionError,"UnrecognizedGravityType",
888 value);
889 draw_info->gravity=(GravityType) option;
890 break;
891 }
892 ThrowMSLException(OptionError,"UnrecognizedAttribute",
893 keyword);
894 break;
895 }
896 case 'P':
897 case 'p':
898 {
899 if (LocaleCompare(keyword,"pointsize") == 0)
900 {
901 draw_info->pointsize=atof(value);
902 break;
903 }
904 ThrowMSLException(OptionError,"UnrecognizedAttribute",
905 keyword);
906 break;
907 }
908 case 'R':
909 case 'r':
910 {
911 if (LocaleCompare(keyword,"rotate") == 0)
912 {
913 angle=atof(value);
914 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
915 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
916 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
917 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
918 break;
919 }
920 ThrowMSLException(OptionError,"UnrecognizedAttribute",
921 keyword);
922 break;
923 }
924 case 'S':
925 case 's':
926 {
927 if (LocaleCompare(keyword,"scale") == 0)
928 {
929 flags=ParseGeometry(value,&geometry_info);
930 if ((flags & SigmaValue) == 0)
931 geometry_info.sigma=1.0;
932 affine.sx=geometry_info.rho;
933 affine.sy=geometry_info.sigma;
934 break;
935 }
936 if (LocaleCompare(keyword,"skewX") == 0)
937 {
938 angle=atof(value);
939 affine.ry=tan(DegreesToRadians(fmod((double) angle,
940 360.0)));
941 break;
942 }
943 if (LocaleCompare(keyword,"skewY") == 0)
944 {
945 angle=atof(value);
946 affine.rx=tan(DegreesToRadians(fmod((double) angle,
947 360.0)));
948 break;
949 }
950 if (LocaleCompare(keyword,"stretch") == 0)
951 {
952 option=ParseMagickOption(MagickStretchOptions,MagickFalse,
953 value);
954 if (option < 0)
955 ThrowMSLException(OptionError,"UnrecognizedStretchType",
956 value);
957 draw_info->stretch=(StretchType) option;
958 break;
959 }
960 if (LocaleCompare(keyword, "stroke") == 0)
961 {
962 (void) QueryColorDatabase(value,&draw_info->stroke,
963 &exception);
964 break;
965 }
966 if (LocaleCompare(keyword,"strokewidth") == 0)
967 {
968 draw_info->stroke_width=atol(value);
969 break;
970 }
971 if (LocaleCompare(keyword,"style") == 0)
972 {
973 option=ParseMagickOption(MagickStyleOptions,MagickFalse,
974 value);
975 if (option < 0)
976 ThrowMSLException(OptionError,"UnrecognizedStyleType",
977 value);
978 draw_info->style=(StyleType) option;
979 break;
980 }
981 ThrowMSLException(OptionError,"UnrecognizedAttribute",
982 keyword);
983 break;
984 }
985 case 'T':
986 case 't':
987 {
988 if (LocaleCompare(keyword,"text") == 0)
989 {
990 CloneString(&draw_info->text,value);
991 break;
992 }
993 if (LocaleCompare(keyword,"translate") == 0)
994 {
995 flags=ParseGeometry(value,&geometry_info);
996 if ((flags & SigmaValue) == 0)
997 geometry_info.sigma=1.0;
998 affine.tx=geometry_info.rho;
999 affine.ty=geometry_info.sigma;
1000 break;
1001 }
1002 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1003 keyword);
1004 break;
1005 }
1006 case 'U':
1007 case 'u':
1008 {
1009 if (LocaleCompare(keyword, "undercolor") == 0)
1010 {
1011 (void) QueryColorDatabase(value,&draw_info->undercolor,
1012 &exception);
1013 break;
1014 }
1015 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1016 keyword);
1017 break;
1018 }
1019 case 'W':
1020 case 'w':
1021 {
1022 if (LocaleCompare(keyword,"weight") == 0)
1023 {
1024 draw_info->weight=atol(value);
1025 break;
1026 }
1027 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1028 keyword);
1029 break;
1030 }
1031 case 'X':
1032 case 'x':
1033 {
1034 if (LocaleCompare(keyword,"x") == 0)
1035 {
1036 geometry.x=atol(value);
1037 break;
1038 }
1039 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1040 keyword);
1041 break;
1042 }
1043 case 'Y':
1044 case 'y':
1045 {
1046 if (LocaleCompare(keyword,"y") == 0)
1047 {
1048 geometry.y=atol(value);
1049 break;
1050 }
1051 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1052 keyword);
1053 break;
1054 }
1055 default:
1056 {
1057 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1058 keyword);
1059 break;
1060 }
1061 }
1062 }
1063 (void) FormatMagickString(text,MaxTextExtent,"%lux%lu%+ld%+ld",
1064 geometry.width,geometry.height,geometry.x,geometry.y);
1065 CloneString(&draw_info->geometry,text);
1066 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
1067 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
1068 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
1069 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
1070 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
1071 current.tx;
1072 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
1073 current.ty;
1074 (void) AnnotateImage(msl_info->image[n],draw_info);
1075 draw_info=DestroyDrawInfo(draw_info);
1076 break;
1077 }
cristyb988fe72009-09-16 01:01:10 +00001078 if (LocaleCompare((const char *) tag,"append") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001079 {
1080 Image
1081 *append_image;
1082
1083 MagickBooleanType
1084 stack;
cristyb988fe72009-09-16 01:01:10 +00001085
cristy3ed852e2009-09-05 21:47:34 +00001086 if (msl_info->image[n] == (Image *) NULL)
1087 {
cristyb988fe72009-09-16 01:01:10 +00001088 ThrowMSLException(OptionError,"NoImagesDefined",
1089 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001090 break;
1091 }
1092 stack=MagickFalse;
1093 if (attributes != (const xmlChar **) NULL)
1094 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1095 {
1096 keyword=(const char *) attributes[i++];
1097 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001098 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001099 CloneString(&value,attribute);
1100 switch (*keyword)
1101 {
1102 case 'S':
1103 case 's':
1104 {
1105 if (LocaleCompare(keyword,"stack") == 0)
1106 {
1107 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
1108 value);
1109 if (option < 0)
1110 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1111 value);
1112 stack=(MagickBooleanType) option;
1113 break;
1114 }
1115 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1116 keyword);
1117 break;
1118 }
1119 default:
1120 {
1121 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1122 keyword);
1123 break;
1124 }
1125 }
1126 }
1127 append_image=AppendImages(msl_info->image[n],stack,
1128 &msl_info->image[n]->exception);
1129 if (append_image == (Image *) NULL)
1130 break;
1131 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1132 msl_info->image[n]=append_image;
1133 break;
1134 }
1135 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1136 break;
1137 }
1138 case 'B':
1139 case 'b':
1140 {
cristyb988fe72009-09-16 01:01:10 +00001141 if (LocaleCompare((const char *) tag,"blur") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001142 {
1143 Image
1144 *blur_image;
1145
1146 /*
1147 Blur image.
1148 */
1149 if (msl_info->image[n] == (Image *) NULL)
1150 {
cristyb988fe72009-09-16 01:01:10 +00001151 ThrowMSLException(OptionError,"NoImagesDefined",
1152 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001153 break;
1154 }
1155 if (attributes != (const xmlChar **) NULL)
1156 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1157 {
1158 keyword=(const char *) attributes[i++];
1159 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001160 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001161 CloneString(&value,attribute);
1162 switch (*keyword)
1163 {
1164 case 'C':
1165 case 'c':
1166 {
1167 if (LocaleCompare(keyword,"channel") == 0)
1168 {
1169 option=ParseChannelOption(value);
1170 if (option < 0)
1171 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1172 value);
1173 channel=(ChannelType) option;
1174 break;
1175 }
1176 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1177 keyword);
1178 break;
1179 }
1180 case 'G':
1181 case 'g':
1182 {
1183 if (LocaleCompare(keyword,"geometry") == 0)
1184 {
1185 flags=ParseGeometry(value,&geometry_info);
1186 if ((flags & SigmaValue) == 0)
1187 geometry_info.sigma=1.0;
1188 break;
1189 }
1190 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1191 keyword);
1192 break;
1193 }
1194 case 'R':
1195 case 'r':
1196 {
1197 if (LocaleCompare(keyword,"radius") == 0)
1198 {
1199 geometry_info.rho=atof(value);
1200 break;
1201 }
1202 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1203 keyword);
1204 break;
1205 }
1206 case 'S':
1207 case 's':
1208 {
1209 if (LocaleCompare(keyword,"sigma") == 0)
1210 {
1211 geometry_info.sigma=atol(value);
1212 break;
1213 }
1214 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1215 keyword);
1216 break;
1217 }
1218 default:
1219 {
1220 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1221 keyword);
1222 break;
1223 }
1224 }
1225 }
1226 blur_image=BlurImageChannel(msl_info->image[n],channel,
1227 geometry_info.rho,geometry_info.sigma,
1228 &msl_info->image[n]->exception);
1229 if (blur_image == (Image *) NULL)
1230 break;
1231 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1232 msl_info->image[n]=blur_image;
1233 break;
1234 }
cristyb988fe72009-09-16 01:01:10 +00001235 if (LocaleCompare((const char *) tag,"border") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001236 {
1237 Image
1238 *border_image;
1239
1240 /*
1241 Border image.
1242 */
1243 if (msl_info->image[n] == (Image *) NULL)
1244 {
cristyb988fe72009-09-16 01:01:10 +00001245 ThrowMSLException(OptionError,"NoImagesDefined",
1246 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001247 break;
1248 }
1249 SetGeometry(msl_info->image[n],&geometry);
1250 if (attributes != (const xmlChar **) NULL)
1251 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1252 {
1253 keyword=(const char *) attributes[i++];
1254 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001255 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001256 CloneString(&value,attribute);
1257 switch (*keyword)
1258 {
1259 case 'C':
1260 case 'c':
1261 {
1262 if (LocaleCompare(keyword,"compose") == 0)
1263 {
1264 option=ParseMagickOption(MagickComposeOptions,MagickFalse,
1265 value);
1266 if (option < 0)
1267 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1268 value);
1269 msl_info->image[n]->compose=(CompositeOperator) option;
1270 break;
1271 }
1272 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1273 keyword);
1274 break;
1275 }
1276 case 'F':
1277 case 'f':
1278 {
1279 if (LocaleCompare(keyword, "fill") == 0)
1280 {
1281 (void) QueryColorDatabase(value,
1282 &msl_info->image[n]->border_color,&exception);
1283 break;
1284 }
1285 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1286 keyword);
1287 break;
1288 }
1289 case 'G':
1290 case 'g':
1291 {
1292 if (LocaleCompare(keyword,"geometry") == 0)
1293 {
1294 flags=ParsePageGeometry(msl_info->image[n],value,
1295 &geometry,&exception);
1296 if ((flags & HeightValue) == 0)
1297 geometry.height=geometry.width;
1298 break;
1299 }
1300 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1301 keyword);
1302 break;
1303 }
1304 case 'H':
1305 case 'h':
1306 {
1307 if (LocaleCompare(keyword,"height") == 0)
1308 {
1309 geometry.height=atol(value);
1310 break;
1311 }
1312 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1313 keyword);
1314 break;
1315 }
1316 case 'W':
1317 case 'w':
1318 {
1319 if (LocaleCompare(keyword,"width") == 0)
1320 {
1321 geometry.width=atol(value);
1322 break;
1323 }
1324 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1325 keyword);
1326 break;
1327 }
1328 default:
1329 {
1330 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1331 keyword);
1332 break;
1333 }
1334 }
1335 }
1336 border_image=BorderImage(msl_info->image[n],&geometry,
1337 &msl_info->image[n]->exception);
1338 if (border_image == (Image *) NULL)
1339 break;
1340 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1341 msl_info->image[n]=border_image;
1342 break;
1343 }
1344 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1345 }
1346 case 'C':
1347 case 'c':
1348 {
cristyb988fe72009-09-16 01:01:10 +00001349 if (LocaleCompare((const char *) tag,"colorize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001350 {
1351 char
1352 opacity[MaxTextExtent];
1353
1354 Image
1355 *colorize_image;
1356
1357 PixelPacket
1358 target;
1359
1360 /*
1361 Add noise image.
1362 */
1363 if (msl_info->image[n] == (Image *) NULL)
1364 {
cristyb988fe72009-09-16 01:01:10 +00001365 ThrowMSLException(OptionError,"NoImagesDefined",
1366 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001367 break;
1368 }
1369 target=msl_info->image[n]->background_color;
1370 (void) CopyMagickString(opacity,"100",MaxTextExtent);
1371 if (attributes != (const xmlChar **) NULL)
1372 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1373 {
1374 keyword=(const char *) attributes[i++];
1375 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001376 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001377 CloneString(&value,attribute);
1378 switch (*keyword)
1379 {
1380 case 'F':
1381 case 'f':
1382 {
1383 if (LocaleCompare(keyword,"fill") == 0)
1384 {
1385 (void) QueryColorDatabase(value,&target,
1386 &msl_info->image[n]->exception);
1387 break;
1388 }
1389 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1390 keyword);
1391 break;
1392 }
1393 case 'O':
1394 case 'o':
1395 {
1396 if (LocaleCompare(keyword,"opacity") == 0)
1397 {
1398 (void) CopyMagickString(opacity,value,MaxTextExtent);
1399 break;
1400 }
1401 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1402 keyword);
1403 break;
1404 }
1405 default:
1406 {
1407 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1408 keyword);
1409 break;
1410 }
1411 }
1412 }
1413 colorize_image=ColorizeImage(msl_info->image[n],opacity,target,
1414 &msl_info->image[n]->exception);
1415 if (colorize_image == (Image *) NULL)
1416 break;
1417 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1418 msl_info->image[n]=colorize_image;
1419 break;
1420 }
cristyb988fe72009-09-16 01:01:10 +00001421 if (LocaleCompare((const char *) tag, "charcoal") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001422 {
1423 double radius = 0.0,
1424 sigma = 1.0;
1425
1426 if (msl_info->image[n] == (Image *) NULL)
1427 {
cristyb988fe72009-09-16 01:01:10 +00001428 ThrowMSLException(OptionError,"NoImagesDefined",
1429 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001430 break;
1431 }
1432 /*
1433 NOTE: charcoal can have no attributes, since we use all the defaults!
1434 */
1435 if (attributes != (const xmlChar **) NULL)
1436 {
1437 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1438 {
1439 keyword=(const char *) attributes[i++];
1440 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001441 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00001442 switch (*keyword)
1443 {
1444 case 'R':
1445 case 'r':
1446 {
1447 if (LocaleCompare(keyword, "radius") == 0)
1448 {
1449 radius = atof( value );
1450 break;
1451 }
1452 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1453 break;
1454 }
1455 case 'S':
1456 case 's':
1457 {
1458 if (LocaleCompare(keyword,"sigma") == 0)
1459 {
1460 sigma = atol( value );
1461 break;
1462 }
1463 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1464 break;
1465 }
1466 default:
1467 {
1468 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1469 break;
1470 }
1471 }
1472 }
1473 }
1474
1475 /*
1476 charcoal image.
1477 */
1478 {
1479 Image
1480 *newImage;
1481
1482 newImage=CharcoalImage(msl_info->image[n],radius,sigma,
1483 &msl_info->image[n]->exception);
1484 if (newImage == (Image *) NULL)
1485 break;
1486 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1487 msl_info->image[n]=newImage;
1488 break;
1489 }
1490 }
cristyb988fe72009-09-16 01:01:10 +00001491 if (LocaleCompare((const char *) tag,"chop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001492 {
1493 Image
1494 *chop_image;
1495
1496 /*
1497 Chop image.
1498 */
1499 if (msl_info->image[n] == (Image *) NULL)
1500 {
cristyb988fe72009-09-16 01:01:10 +00001501 ThrowMSLException(OptionError,"NoImagesDefined",
1502 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001503 break;
1504 }
1505 SetGeometry(msl_info->image[n],&geometry);
1506 if (attributes != (const xmlChar **) NULL)
1507 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1508 {
1509 keyword=(const char *) attributes[i++];
1510 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001511 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001512 CloneString(&value,attribute);
1513 switch (*keyword)
1514 {
1515 case 'G':
1516 case 'g':
1517 {
1518 if (LocaleCompare(keyword,"geometry") == 0)
1519 {
1520 flags=ParsePageGeometry(msl_info->image[n],value,
1521 &geometry,&exception);
1522 if ((flags & HeightValue) == 0)
1523 geometry.height=geometry.width;
1524 break;
1525 }
1526 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1527 keyword);
1528 break;
1529 }
1530 case 'H':
1531 case 'h':
1532 {
1533 if (LocaleCompare(keyword,"height") == 0)
1534 {
1535 geometry.height=atol(value);
1536 break;
1537 }
1538 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1539 keyword);
1540 break;
1541 }
1542 case 'W':
1543 case 'w':
1544 {
1545 if (LocaleCompare(keyword,"width") == 0)
1546 {
1547 geometry.width=atol(value);
1548 break;
1549 }
1550 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1551 keyword);
1552 break;
1553 }
1554 case 'X':
1555 case 'x':
1556 {
1557 if (LocaleCompare(keyword,"x") == 0)
1558 {
1559 geometry.x=atol(value);
1560 break;
1561 }
1562 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1563 keyword);
1564 break;
1565 }
1566 case 'Y':
1567 case 'y':
1568 {
1569 if (LocaleCompare(keyword,"y") == 0)
1570 {
1571 geometry.y=atol(value);
1572 break;
1573 }
1574 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1575 keyword);
1576 break;
1577 }
1578 default:
1579 {
1580 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1581 keyword);
1582 break;
1583 }
1584 }
1585 }
1586 chop_image=ChopImage(msl_info->image[n],&geometry,
1587 &msl_info->image[n]->exception);
1588 if (chop_image == (Image *) NULL)
1589 break;
1590 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1591 msl_info->image[n]=chop_image;
1592 break;
1593 }
cristyb988fe72009-09-16 01:01:10 +00001594 if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001595 {
1596 PaintMethod
1597 paint_method;
1598
1599 MagickPixelPacket
1600 target;
1601
1602 /*
1603 Color floodfill image.
1604 */
1605 if (msl_info->image[n] == (Image *) NULL)
1606 {
cristyb988fe72009-09-16 01:01:10 +00001607 ThrowMSLException(OptionError,"NoImagesDefined",
1608 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001609 break;
1610 }
1611 draw_info=CloneDrawInfo(msl_info->image_info[n],
1612 msl_info->draw_info[n]);
1613 SetGeometry(msl_info->image[n],&geometry);
1614 paint_method=FloodfillMethod;
1615 if (attributes != (const xmlChar **) NULL)
1616 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1617 {
1618 keyword=(const char *) attributes[i++];
1619 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001620 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001621 CloneString(&value,attribute);
1622 switch (*keyword)
1623 {
1624 case 'B':
1625 case 'b':
1626 {
1627 if (LocaleCompare(keyword,"bordercolor") == 0)
1628 {
1629 (void) QueryMagickColor(value,&target,&exception);
1630 paint_method=FillToBorderMethod;
1631 break;
1632 }
1633 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1634 keyword);
1635 break;
1636 }
1637 case 'F':
1638 case 'f':
1639 {
1640 if (LocaleCompare(keyword,"fill") == 0)
1641 {
1642 (void) QueryColorDatabase(value,&draw_info->fill,
1643 &exception);
1644 break;
1645 }
1646 if (LocaleCompare(keyword,"fuzz") == 0)
1647 {
1648 msl_info->image[n]->fuzz=atof(value);
1649 break;
1650 }
1651 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1652 keyword);
1653 break;
1654 }
1655 case 'G':
1656 case 'g':
1657 {
1658 if (LocaleCompare(keyword,"geometry") == 0)
1659 {
1660 flags=ParsePageGeometry(msl_info->image[n],value,
1661 &geometry,&exception);
1662 if ((flags & HeightValue) == 0)
1663 geometry.height=geometry.width;
1664 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1665 geometry.x,geometry.y,&target,&exception);
1666 break;
1667 }
1668 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1669 keyword);
1670 break;
1671 }
1672 case 'X':
1673 case 'x':
1674 {
1675 if (LocaleCompare(keyword,"x") == 0)
1676 {
1677 geometry.x=atol(value);
1678 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1679 geometry.x,geometry.y,&target,&exception);
1680 break;
1681 }
1682 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1683 keyword);
1684 break;
1685 }
1686 case 'Y':
1687 case 'y':
1688 {
1689 if (LocaleCompare(keyword,"y") == 0)
1690 {
1691 geometry.y=atol(value);
1692 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1693 geometry.x,geometry.y,&target,&exception);
1694 break;
1695 }
1696 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1697 keyword);
1698 break;
1699 }
1700 default:
1701 {
1702 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1703 keyword);
1704 break;
1705 }
1706 }
1707 }
1708 (void) FloodfillPaintImage(msl_info->image[n],DefaultChannels,
1709 draw_info,&target,geometry.x,geometry.y,
1710 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
1711 draw_info=DestroyDrawInfo(draw_info);
1712 break;
1713 }
cristyb988fe72009-09-16 01:01:10 +00001714 if (LocaleCompare((const char *) tag,"comment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001715 break;
cristyb988fe72009-09-16 01:01:10 +00001716 if (LocaleCompare((const char *) tag,"composite") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001717 {
1718 char
1719 composite_geometry[MaxTextExtent];
1720
1721 CompositeOperator
1722 compose;
1723
1724 Image
1725 *composite_image,
1726 *rotate_image;
1727
1728 PixelPacket
1729 target;
1730
1731 /*
1732 Composite image.
1733 */
1734 if (msl_info->image[n] == (Image *) NULL)
1735 {
cristyb988fe72009-09-16 01:01:10 +00001736 ThrowMSLException(OptionError,"NoImagesDefined",
1737 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001738 break;
1739 }
1740 composite_image=NewImageList();
1741 compose=OverCompositeOp;
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 'C':
1752 case 'c':
1753 {
1754 if (LocaleCompare(keyword,"compose") == 0)
1755 {
1756 option=ParseMagickOption(MagickComposeOptions,MagickFalse,
1757 value);
1758 if (option < 0)
1759 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1760 value);
1761 compose=(CompositeOperator) option;
1762 break;
1763 }
1764 break;
1765 }
1766 case 'I':
1767 case 'i':
1768 {
1769 if (LocaleCompare(keyword,"image") == 0)
1770 for (j=0; j < msl_info->n; j++)
1771 {
1772 const char
1773 *attribute;
cristyb988fe72009-09-16 01:01:10 +00001774
cristy3ed852e2009-09-05 21:47:34 +00001775 attribute=GetImageProperty(msl_info->attributes[j],"id");
1776 if ((attribute != (const char *) NULL) &&
1777 (LocaleCompare(attribute,value) == 0))
1778 {
1779 composite_image=CloneImage(msl_info->image[j],0,0,
1780 MagickFalse,&exception);
1781 break;
1782 }
1783 }
1784 break;
1785 }
1786 default:
1787 break;
1788 }
1789 }
1790 if (composite_image == (Image *) NULL)
1791 break;
1792 rotate_image=NewImageList();
1793 SetGeometry(msl_info->image[n],&geometry);
1794 if (attributes != (const xmlChar **) NULL)
1795 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1796 {
1797 keyword=(const char *) attributes[i++];
1798 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001799 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001800 CloneString(&value,attribute);
1801 switch (*keyword)
1802 {
1803 case 'B':
1804 case 'b':
1805 {
1806 if (LocaleCompare(keyword,"blend") == 0)
1807 {
1808 (void) SetImageArtifact(composite_image,
1809 "compose:args",value);
1810 break;
1811 }
1812 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1813 keyword);
1814 break;
1815 }
1816 case 'C':
1817 case 'c':
1818 {
1819 if (LocaleCompare(keyword,"channel") == 0)
1820 {
1821 option=ParseChannelOption(value);
1822 if (option < 0)
1823 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1824 value);
1825 channel=(ChannelType) option;
1826 break;
1827 }
1828 if (LocaleCompare(keyword, "color") == 0)
1829 {
1830 (void) QueryColorDatabase(value,
1831 &composite_image->background_color,&exception);
1832 break;
1833 }
1834 if (LocaleCompare(keyword,"compose") == 0)
1835 break;
1836 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1837 keyword);
1838 break;
1839 }
1840 case 'G':
1841 case 'g':
1842 {
1843 if (LocaleCompare(keyword,"geometry") == 0)
1844 {
1845 flags=ParsePageGeometry(msl_info->image[n],value,
1846 &geometry,&exception);
1847 if ((flags & HeightValue) == 0)
1848 geometry.height=geometry.width;
1849 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
1850 geometry.y,&target,&exception);
1851 break;
1852 }
1853 if (LocaleCompare(keyword,"gravity") == 0)
1854 {
1855 option=ParseMagickOption(MagickGravityOptions,MagickFalse,
1856 value);
1857 if (option < 0)
1858 ThrowMSLException(OptionError,"UnrecognizedGravityType",
1859 value);
1860 msl_info->image[n]->gravity=(GravityType) option;
1861 break;
1862 }
1863 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1864 keyword);
1865 break;
1866 }
1867 case 'I':
1868 case 'i':
1869 {
1870 if (LocaleCompare(keyword,"image") == 0)
1871 break;
1872 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1873 keyword);
1874 break;
1875 }
1876 case 'M':
1877 case 'm':
1878 {
1879 if (LocaleCompare(keyword,"mask") == 0)
1880 for (j=0; j < msl_info->n; j++)
1881 {
1882 const char
1883 *attribute;
1884
1885 attribute=GetImageProperty(msl_info->attributes[j],"id");
1886 if ((attribute != (const char *) NULL) &&
1887 (LocaleCompare(value,value) == 0))
1888 {
1889 SetImageType(composite_image,TrueColorMatteType);
1890 (void) CompositeImage(composite_image,
1891 CopyOpacityCompositeOp,msl_info->image[j],0,0);
1892 break;
1893 }
1894 }
1895 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1896 keyword);
1897 break;
1898 }
1899 case 'O':
1900 case 'o':
1901 {
1902 if (LocaleCompare(keyword,"opacity") == 0)
1903 {
1904 long
1905 opacity,
1906 y;
cristyb988fe72009-09-16 01:01:10 +00001907
cristy3ed852e2009-09-05 21:47:34 +00001908 register long
1909 x;
cristyb988fe72009-09-16 01:01:10 +00001910
cristy3ed852e2009-09-05 21:47:34 +00001911 register PixelPacket
1912 *q;
cristyb988fe72009-09-16 01:01:10 +00001913
cristy3ed852e2009-09-05 21:47:34 +00001914 CacheView
1915 *composite_view;
1916
1917 opacity=QuantumRange-atol(value);
1918 if (compose != DissolveCompositeOp)
1919 {
cristyb988fe72009-09-16 01:01:10 +00001920 (void) SetImageOpacity(composite_image,(Quantum)
1921 opacity);
cristy3ed852e2009-09-05 21:47:34 +00001922 break;
1923 }
1924 (void) SetImageArtifact(msl_info->image[n],
1925 "compose:args",value);
1926 if (composite_image->matte != MagickTrue)
1927 (void) SetImageOpacity(composite_image,OpaqueOpacity);
1928 composite_view=AcquireCacheView(composite_image);
1929 for (y=0; y < (long) composite_image->rows ; y++)
cristyb988fe72009-09-16 01:01:10 +00001930 {
cristy3ed852e2009-09-05 21:47:34 +00001931 q=GetCacheViewAuthenticPixels(composite_view,0,y,(long)
1932 composite_image->columns,1,&exception);
1933 for (x=0; x < (long) composite_image->columns; x++)
cristyb988fe72009-09-16 01:01:10 +00001934 {
cristy3ed852e2009-09-05 21:47:34 +00001935 if (q->opacity == OpaqueOpacity)
1936 q->opacity=RoundToQuantum(opacity);
1937 q++;
1938 }
1939 if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1940 break;
1941 }
1942 composite_view=DestroyCacheView(composite_view);
1943 break;
1944 }
1945 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1946 keyword);
1947 break;
1948 }
1949 case 'R':
1950 case 'r':
1951 {
1952 if (LocaleCompare(keyword,"rotate") == 0)
1953 {
1954 rotate_image=RotateImage(composite_image,atof(value),
1955 &exception);
1956 break;
1957 }
1958 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1959 keyword);
1960 break;
1961 }
1962 case 'T':
1963 case 't':
1964 {
1965 if (LocaleCompare(keyword,"tile") == 0)
1966 {
1967 MagickBooleanType
1968 tile;
1969
1970 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
1971 value);
1972 if (option < 0)
1973 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1974 value);
1975 tile=(MagickBooleanType) option;
1976 if (rotate_image != (Image *) NULL)
1977 (void) SetImageArtifact(rotate_image,
1978 "compose:outside-overlay","false");
1979 else
1980 (void) SetImageArtifact(composite_image,
1981 "compose:outside-overlay","false");
1982 image=msl_info->image[n];
1983 height=composite_image->rows;
1984 width=composite_image->columns;
1985 for (y=0; y < (long) image->rows; y+=height)
1986 for (x=0; x < (long) image->columns; x+=width)
1987 {
1988 if (rotate_image != (Image *) NULL)
1989 (void) CompositeImage(image,compose,rotate_image,
1990 x,y);
1991 else
1992 (void) CompositeImage(image,compose,
1993 composite_image,x,y);
1994 }
1995 if (rotate_image != (Image *) NULL)
1996 rotate_image=DestroyImage(rotate_image);
1997 break;
1998 }
1999 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2000 keyword);
2001 break;
2002 }
2003 case 'X':
2004 case 'x':
2005 {
2006 if (LocaleCompare(keyword,"x") == 0)
2007 {
2008 geometry.x=atol(value);
2009 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2010 geometry.y,&target,&exception);
2011 break;
2012 }
2013 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2014 keyword);
2015 break;
2016 }
2017 case 'Y':
2018 case 'y':
2019 {
2020 if (LocaleCompare(keyword,"y") == 0)
2021 {
2022 geometry.y=atol(value);
2023 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2024 geometry.y,&target,&exception);
2025 break;
2026 }
2027 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2028 keyword);
2029 break;
2030 }
2031 default:
2032 {
2033 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2034 keyword);
2035 break;
2036 }
2037 }
2038 }
2039 image=msl_info->image[n];
2040 (void) FormatMagickString(composite_geometry,MaxTextExtent,
2041 "%lux%lu%+ld%+ld",composite_image->columns,composite_image->rows,
2042 geometry.x,geometry.y);
2043 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2044 &exception);
2045 if (rotate_image == (Image *) NULL)
2046 CompositeImageChannel(image,channel,compose,composite_image,
2047 geometry.x,geometry.y);
2048 else
2049 {
2050 /*
2051 Rotate image.
2052 */
2053 geometry.x-=(long) (rotate_image->columns-
2054 composite_image->columns)/2;
2055 geometry.y-=(long) (rotate_image->rows-composite_image->rows)/2;
2056 CompositeImageChannel(image,channel,compose,rotate_image,
2057 geometry.x,geometry.y);
2058 rotate_image=DestroyImage(rotate_image);
2059 }
2060 composite_image=DestroyImage(composite_image);
2061 break;
2062 }
cristyb988fe72009-09-16 01:01:10 +00002063 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002064 {
2065 MagickBooleanType
2066 sharpen;
2067
2068 /*
2069 Contrast 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 sharpen=MagickFalse;
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 'S':
2088 case 's':
2089 {
2090 if (LocaleCompare(keyword,"sharpen") == 0)
2091 {
2092 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2093 value);
2094 if (option < 0)
2095 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2096 value);
2097 sharpen=(MagickBooleanType) option;
2098 break;
2099 }
2100 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2101 keyword);
2102 break;
2103 }
2104 default:
2105 {
2106 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2107 keyword);
2108 break;
2109 }
2110 }
2111 }
2112 (void) ContrastImage(msl_info->image[n],sharpen);
2113 break;
2114 }
cristyb988fe72009-09-16 01:01:10 +00002115 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002116 {
2117 Image
2118 *crop_image;
2119
2120 /*
2121 Crop image.
2122 */
2123 if (msl_info->image[n] == (Image *) NULL)
2124 {
cristyb988fe72009-09-16 01:01:10 +00002125 ThrowMSLException(OptionError,"NoImagesDefined",
2126 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002127 break;
2128 }
2129 SetGeometry(msl_info->image[n],&geometry);
2130 if (attributes != (const xmlChar **) NULL)
2131 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2132 {
2133 keyword=(const char *) attributes[i++];
2134 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002135 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002136 CloneString(&value,attribute);
2137 switch (*keyword)
2138 {
2139 case 'G':
2140 case 'g':
2141 {
2142 if (LocaleCompare(keyword,"geometry") == 0)
2143 {
2144 flags=ParsePageGeometry(msl_info->image[n],value,
2145 &geometry,&exception);
2146 if ((flags & HeightValue) == 0)
2147 geometry.height=geometry.width;
2148 break;
2149 }
2150 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2151 keyword);
2152 break;
2153 }
2154 case 'H':
2155 case 'h':
2156 {
2157 if (LocaleCompare(keyword,"height") == 0)
2158 {
2159 geometry.height=atol(value);
2160 break;
2161 }
2162 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2163 keyword);
2164 break;
2165 }
2166 case 'W':
2167 case 'w':
2168 {
2169 if (LocaleCompare(keyword,"width") == 0)
2170 {
2171 geometry.width=atol(value);
2172 break;
2173 }
2174 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2175 keyword);
2176 break;
2177 }
2178 case 'X':
2179 case 'x':
2180 {
2181 if (LocaleCompare(keyword,"x") == 0)
2182 {
2183 geometry.x=atol(value);
2184 break;
2185 }
2186 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2187 keyword);
2188 break;
2189 }
2190 case 'Y':
2191 case 'y':
2192 {
2193 if (LocaleCompare(keyword,"y") == 0)
2194 {
2195 geometry.y=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 crop_image=CropImage(msl_info->image[n],&geometry,
2211 &msl_info->image[n]->exception);
2212 if (crop_image == (Image *) NULL)
2213 break;
2214 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2215 msl_info->image[n]=crop_image;
2216 break;
2217 }
cristyb988fe72009-09-16 01:01:10 +00002218 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002219 {
2220 long
2221 display;
2222
2223 /*
2224 Cycle-colormap 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 display=0;
2233 if (attributes != (const xmlChar **) NULL)
2234 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2235 {
2236 keyword=(const char *) attributes[i++];
2237 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002238 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002239 CloneString(&value,attribute);
2240 switch (*keyword)
2241 {
2242 case 'D':
2243 case 'd':
2244 {
2245 if (LocaleCompare(keyword,"display") == 0)
2246 {
2247 display=atol(value);
2248 break;
2249 }
2250 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2251 keyword);
2252 break;
2253 }
2254 default:
2255 {
2256 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2257 keyword);
2258 break;
2259 }
2260 }
2261 }
2262 (void) CycleColormapImage(msl_info->image[n],display);
2263 break;
2264 }
2265 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2266 }
2267 case 'D':
2268 case 'd':
2269 {
cristyb988fe72009-09-16 01:01:10 +00002270 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002271 {
2272 Image
2273 *despeckle_image;
2274
2275 /*
2276 Despeckle image.
2277 */
2278 if (msl_info->image[n] == (Image *) NULL)
2279 {
cristyb988fe72009-09-16 01:01:10 +00002280 ThrowMSLException(OptionError,"NoImagesDefined",
2281 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002282 break;
2283 }
2284 if (attributes != (const xmlChar **) NULL)
2285 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2286 {
2287 keyword=(const char *) attributes[i++];
2288 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002289 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002290 CloneString(&value,attribute);
2291 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2292 }
2293 despeckle_image=DespeckleImage(msl_info->image[n],
2294 &msl_info->image[n]->exception);
2295 if (despeckle_image == (Image *) NULL)
2296 break;
2297 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2298 msl_info->image[n]=despeckle_image;
2299 break;
2300 }
cristyb988fe72009-09-16 01:01:10 +00002301 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002302 {
2303 if (msl_info->image[n] == (Image *) NULL)
2304 {
cristyb988fe72009-09-16 01:01:10 +00002305 ThrowMSLException(OptionError,"NoImagesDefined",
2306 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002307 break;
2308 }
2309 if (attributes != (const xmlChar **) NULL)
2310 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2311 {
2312 keyword=(const char *) attributes[i++];
2313 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002314 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002315 CloneString(&value,attribute);
2316 switch (*keyword)
2317 {
2318 default:
2319 {
2320 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2321 keyword);
2322 break;
2323 }
2324 }
2325 }
2326 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n]);
2327 break;
2328 }
cristyb988fe72009-09-16 01:01:10 +00002329 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002330 {
2331 char
2332 text[MaxTextExtent];
2333
2334 /*
2335 Annotate image.
2336 */
2337 if (msl_info->image[n] == (Image *) NULL)
2338 {
cristyb988fe72009-09-16 01:01:10 +00002339 ThrowMSLException(OptionError,"NoImagesDefined",
2340 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002341 break;
2342 }
2343 draw_info=CloneDrawInfo(msl_info->image_info[n],
2344 msl_info->draw_info[n]);
2345 angle=0.0;
2346 current=draw_info->affine;
2347 GetAffineMatrix(&affine);
2348 if (attributes != (const xmlChar **) NULL)
2349 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2350 {
2351 keyword=(const char *) attributes[i++];
2352 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002353 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002354 CloneString(&value,attribute);
2355 switch (*keyword)
2356 {
2357 case 'A':
2358 case 'a':
2359 {
2360 if (LocaleCompare(keyword,"affine") == 0)
2361 {
2362 char
2363 *p;
2364
2365 p=value;
2366 draw_info->affine.sx=strtod(p,&p);
2367 if (*p ==',')
2368 p++;
2369 draw_info->affine.rx=strtod(p,&p);
2370 if (*p ==',')
2371 p++;
2372 draw_info->affine.ry=strtod(p,&p);
2373 if (*p ==',')
2374 p++;
2375 draw_info->affine.sy=strtod(p,&p);
2376 if (*p ==',')
2377 p++;
2378 draw_info->affine.tx=strtod(p,&p);
2379 if (*p ==',')
2380 p++;
2381 draw_info->affine.ty=strtod(p,&p);
2382 break;
2383 }
2384 if (LocaleCompare(keyword,"align") == 0)
2385 {
2386 option=ParseMagickOption(MagickAlignOptions,MagickFalse,
2387 value);
2388 if (option < 0)
2389 ThrowMSLException(OptionError,"UnrecognizedAlignType",
2390 value);
2391 draw_info->align=(AlignType) option;
2392 break;
2393 }
2394 if (LocaleCompare(keyword,"antialias") == 0)
2395 {
2396 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
2397 value);
2398 if (option < 0)
2399 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2400 value);
2401 draw_info->stroke_antialias=(MagickBooleanType) option;
2402 draw_info->text_antialias=(MagickBooleanType) option;
2403 break;
2404 }
2405 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2406 keyword);
2407 break;
2408 }
2409 case 'D':
2410 case 'd':
2411 {
2412 if (LocaleCompare(keyword,"density") == 0)
2413 {
2414 CloneString(&draw_info->density,value);
2415 break;
2416 }
2417 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2418 keyword);
2419 break;
2420 }
2421 case 'E':
2422 case 'e':
2423 {
2424 if (LocaleCompare(keyword,"encoding") == 0)
2425 {
2426 CloneString(&draw_info->encoding,value);
2427 break;
2428 }
2429 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2430 keyword);
2431 break;
2432 }
2433 case 'F':
2434 case 'f':
2435 {
2436 if (LocaleCompare(keyword, "fill") == 0)
2437 {
2438 (void) QueryColorDatabase(value,&draw_info->fill,
2439 &exception);
2440 break;
2441 }
2442 if (LocaleCompare(keyword,"family") == 0)
2443 {
2444 CloneString(&draw_info->family,value);
2445 break;
2446 }
2447 if (LocaleCompare(keyword,"font") == 0)
2448 {
2449 CloneString(&draw_info->font,value);
2450 break;
2451 }
2452 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2453 keyword);
2454 break;
2455 }
2456 case 'G':
2457 case 'g':
2458 {
2459 if (LocaleCompare(keyword,"geometry") == 0)
2460 {
2461 flags=ParsePageGeometry(msl_info->image[n],value,
2462 &geometry,&exception);
2463 if ((flags & HeightValue) == 0)
2464 geometry.height=geometry.width;
2465 break;
2466 }
2467 if (LocaleCompare(keyword,"gravity") == 0)
2468 {
2469 option=ParseMagickOption(MagickGravityOptions,MagickFalse,
2470 value);
2471 if (option < 0)
2472 ThrowMSLException(OptionError,"UnrecognizedGravityType",
2473 value);
2474 draw_info->gravity=(GravityType) option;
2475 break;
2476 }
2477 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2478 keyword);
2479 break;
2480 }
2481 case 'P':
2482 case 'p':
2483 {
2484 if (LocaleCompare(keyword,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002485 {
cristy3ed852e2009-09-05 21:47:34 +00002486 CloneString(&draw_info->primitive,value);
2487 break;
2488 }
2489 if (LocaleCompare(keyword,"pointsize") == 0)
2490 {
2491 draw_info->pointsize=atof(value);
2492 break;
2493 }
2494 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2495 keyword);
2496 break;
2497 }
2498 case 'R':
2499 case 'r':
2500 {
2501 if (LocaleCompare(keyword,"rotate") == 0)
2502 {
2503 angle=atof(value);
2504 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2505 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2506 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2507 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2508 break;
2509 }
2510 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2511 keyword);
2512 break;
2513 }
2514 case 'S':
2515 case 's':
2516 {
2517 if (LocaleCompare(keyword,"scale") == 0)
2518 {
2519 flags=ParseGeometry(value,&geometry_info);
2520 if ((flags & SigmaValue) == 0)
2521 geometry_info.sigma=1.0;
2522 affine.sx=geometry_info.rho;
2523 affine.sy=geometry_info.sigma;
2524 break;
2525 }
2526 if (LocaleCompare(keyword,"skewX") == 0)
2527 {
2528 angle=atof(value);
2529 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2530 break;
2531 }
2532 if (LocaleCompare(keyword,"skewY") == 0)
2533 {
2534 angle=atof(value);
2535 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2536 break;
2537 }
2538 if (LocaleCompare(keyword,"stretch") == 0)
2539 {
2540 option=ParseMagickOption(MagickStretchOptions,MagickFalse,
2541 value);
2542 if (option < 0)
2543 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2544 value);
2545 draw_info->stretch=(StretchType) option;
2546 break;
2547 }
2548 if (LocaleCompare(keyword, "stroke") == 0)
2549 {
2550 (void) QueryColorDatabase(value,&draw_info->stroke,
2551 &exception);
2552 break;
2553 }
2554 if (LocaleCompare(keyword,"strokewidth") == 0)
2555 {
2556 draw_info->stroke_width=atol(value);
2557 break;
2558 }
2559 if (LocaleCompare(keyword,"style") == 0)
2560 {
2561 option=ParseMagickOption(MagickStyleOptions,MagickFalse,
2562 value);
2563 if (option < 0)
2564 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2565 value);
2566 draw_info->style=(StyleType) option;
2567 break;
2568 }
2569 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2570 keyword);
2571 break;
2572 }
2573 case 'T':
2574 case 't':
2575 {
2576 if (LocaleCompare(keyword,"text") == 0)
2577 {
2578 CloneString(&draw_info->text,value);
2579 break;
2580 }
2581 if (LocaleCompare(keyword,"translate") == 0)
2582 {
2583 flags=ParseGeometry(value,&geometry_info);
2584 if ((flags & SigmaValue) == 0)
2585 geometry_info.sigma=1.0;
2586 affine.tx=geometry_info.rho;
2587 affine.ty=geometry_info.sigma;
2588 break;
2589 }
2590 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2591 keyword);
2592 break;
2593 }
2594 case 'U':
2595 case 'u':
2596 {
2597 if (LocaleCompare(keyword, "undercolor") == 0)
2598 {
2599 (void) QueryColorDatabase(value,&draw_info->undercolor,
2600 &exception);
2601 break;
2602 }
2603 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2604 keyword);
2605 break;
2606 }
2607 case 'W':
2608 case 'w':
2609 {
2610 if (LocaleCompare(keyword,"weight") == 0)
2611 {
2612 draw_info->weight=atol(value);
2613 break;
2614 }
2615 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2616 keyword);
2617 break;
2618 }
2619 case 'X':
2620 case 'x':
2621 {
2622 if (LocaleCompare(keyword,"x") == 0)
2623 {
2624 geometry.x=atol(value);
2625 break;
2626 }
2627 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2628 keyword);
2629 break;
2630 }
2631 case 'Y':
2632 case 'y':
2633 {
2634 if (LocaleCompare(keyword,"y") == 0)
2635 {
2636 geometry.y=atol(value);
2637 break;
2638 }
2639 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2640 keyword);
2641 break;
2642 }
2643 default:
2644 {
2645 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2646 keyword);
2647 break;
2648 }
2649 }
2650 }
2651 (void) FormatMagickString(text,MaxTextExtent,"%lux%lu%+ld%+ld",
2652 geometry.width,geometry.height,geometry.x,geometry.y);
2653 CloneString(&draw_info->geometry,text);
2654 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
2655 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
2656 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
2657 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
2658 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
2659 current.tx;
2660 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
2661 current.ty;
2662 (void) DrawImage(msl_info->image[n],draw_info);
2663 draw_info=DestroyDrawInfo(draw_info);
2664 break;
2665 }
2666 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2667 }
2668 case 'E':
2669 case 'e':
2670 {
cristyb988fe72009-09-16 01:01:10 +00002671 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002672 {
2673 Image
2674 *edge_image;
2675
2676 /*
2677 Edge image.
2678 */
2679 if (msl_info->image[n] == (Image *) NULL)
2680 {
cristyb988fe72009-09-16 01:01:10 +00002681 ThrowMSLException(OptionError,"NoImagesDefined",
2682 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002683 break;
2684 }
2685 if (attributes != (const xmlChar **) NULL)
2686 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2687 {
2688 keyword=(const char *) attributes[i++];
2689 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002690 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002691 CloneString(&value,attribute);
2692 switch (*keyword)
2693 {
2694 case 'G':
2695 case 'g':
2696 {
2697 if (LocaleCompare(keyword,"geometry") == 0)
2698 {
2699 flags=ParseGeometry(value,&geometry_info);
2700 if ((flags & SigmaValue) == 0)
2701 geometry_info.sigma=1.0;
2702 break;
2703 }
2704 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2705 keyword);
2706 break;
2707 }
2708 case 'R':
2709 case 'r':
2710 {
2711 if (LocaleCompare(keyword,"radius") == 0)
2712 {
2713 geometry_info.rho=atof(value);
2714 break;
2715 }
2716 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2717 keyword);
2718 break;
2719 }
2720 default:
2721 {
2722 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2723 keyword);
2724 break;
2725 }
2726 }
2727 }
2728 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
2729 &msl_info->image[n]->exception);
2730 if (edge_image == (Image *) NULL)
2731 break;
2732 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2733 msl_info->image[n]=edge_image;
2734 break;
2735 }
cristyb988fe72009-09-16 01:01:10 +00002736 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002737 {
2738 Image
2739 *emboss_image;
2740
2741 /*
2742 Emboss image.
2743 */
2744 if (msl_info->image[n] == (Image *) NULL)
2745 {
cristyb988fe72009-09-16 01:01:10 +00002746 ThrowMSLException(OptionError,"NoImagesDefined",
2747 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002748 break;
2749 }
2750 if (attributes != (const xmlChar **) NULL)
2751 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2752 {
2753 keyword=(const char *) attributes[i++];
2754 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002755 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002756 CloneString(&value,attribute);
2757 switch (*keyword)
2758 {
2759 case 'G':
2760 case 'g':
2761 {
2762 if (LocaleCompare(keyword,"geometry") == 0)
2763 {
2764 flags=ParseGeometry(value,&geometry_info);
2765 if ((flags & SigmaValue) == 0)
2766 geometry_info.sigma=1.0;
2767 break;
2768 }
2769 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2770 keyword);
2771 break;
2772 }
2773 case 'R':
2774 case 'r':
2775 {
2776 if (LocaleCompare(keyword,"radius") == 0)
2777 {
2778 geometry_info.rho=atof(value);
2779 break;
2780 }
2781 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2782 keyword);
2783 break;
2784 }
2785 case 'S':
2786 case 's':
2787 {
2788 if (LocaleCompare(keyword,"sigma") == 0)
2789 {
2790 geometry_info.sigma=atol(value);
2791 break;
2792 }
2793 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2794 keyword);
2795 break;
2796 }
2797 default:
2798 {
2799 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2800 keyword);
2801 break;
2802 }
2803 }
2804 }
2805 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2806 geometry_info.sigma,&msl_info->image[n]->exception);
2807 if (emboss_image == (Image *) NULL)
2808 break;
2809 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2810 msl_info->image[n]=emboss_image;
2811 break;
2812 }
cristyb988fe72009-09-16 01:01:10 +00002813 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002814 {
2815 Image
2816 *enhance_image;
2817
2818 /*
2819 Enhance image.
2820 */
2821 if (msl_info->image[n] == (Image *) NULL)
2822 {
cristyb988fe72009-09-16 01:01:10 +00002823 ThrowMSLException(OptionError,"NoImagesDefined",
2824 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002825 break;
2826 }
2827 if (attributes != (const xmlChar **) NULL)
2828 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2829 {
2830 keyword=(const char *) attributes[i++];
2831 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002832 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002833 CloneString(&value,attribute);
2834 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2835 }
2836 enhance_image=EnhanceImage(msl_info->image[n],
2837 &msl_info->image[n]->exception);
2838 if (enhance_image == (Image *) NULL)
2839 break;
2840 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2841 msl_info->image[n]=enhance_image;
2842 break;
2843 }
cristyb988fe72009-09-16 01:01:10 +00002844 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002845 {
2846 /*
2847 Equalize image.
2848 */
2849 if (msl_info->image[n] == (Image *) NULL)
2850 {
cristyb988fe72009-09-16 01:01:10 +00002851 ThrowMSLException(OptionError,"NoImagesDefined",
2852 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002853 break;
2854 }
2855 if (attributes != (const xmlChar **) NULL)
2856 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2857 {
2858 keyword=(const char *) attributes[i++];
2859 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002860 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002861 CloneString(&value,attribute);
2862 switch (*keyword)
2863 {
2864 default:
2865 {
2866 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2867 keyword);
2868 break;
2869 }
2870 }
2871 }
2872 (void) EqualizeImage(msl_info->image[n]);
2873 break;
2874 }
2875 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2876 }
2877 case 'F':
2878 case 'f':
2879 {
cristyb988fe72009-09-16 01:01:10 +00002880 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002881 {
2882 if (msl_info->image[n] == (Image *) NULL)
2883 {
cristyb988fe72009-09-16 01:01:10 +00002884 ThrowMSLException(OptionError,"NoImagesDefined",
2885 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002886 break;
2887 }
2888
2889 /* no attributes here */
2890
2891 /* process the image */
2892 {
2893 Image
2894 *newImage;
2895
2896 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2897 &msl_info->image[n]->exception);
2898 if (newImage == (Image *) NULL)
2899 break;
2900 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2901 msl_info->image[n]=newImage;
2902 break;
2903 }
2904 }
cristyb988fe72009-09-16 01:01:10 +00002905 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002906 {
2907 Image
2908 *flip_image;
2909
2910 /*
2911 Flip image.
2912 */
2913 if (msl_info->image[n] == (Image *) NULL)
2914 {
cristyb988fe72009-09-16 01:01:10 +00002915 ThrowMSLException(OptionError,"NoImagesDefined",
2916 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002917 break;
2918 }
2919 if (attributes != (const xmlChar **) NULL)
2920 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2921 {
2922 keyword=(const char *) attributes[i++];
2923 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002924 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002925 CloneString(&value,attribute);
2926 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2927 }
2928 flip_image=FlipImage(msl_info->image[n],
2929 &msl_info->image[n]->exception);
2930 if (flip_image == (Image *) NULL)
2931 break;
2932 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2933 msl_info->image[n]=flip_image;
2934 break;
2935 }
cristyb988fe72009-09-16 01:01:10 +00002936 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002937 {
2938 Image
2939 *flop_image;
2940
2941 /*
2942 Flop image.
2943 */
2944 if (msl_info->image[n] == (Image *) NULL)
2945 {
cristyb988fe72009-09-16 01:01:10 +00002946 ThrowMSLException(OptionError,"NoImagesDefined",
2947 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002948 break;
2949 }
2950 if (attributes != (const xmlChar **) NULL)
2951 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2952 {
2953 keyword=(const char *) attributes[i++];
2954 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002955 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002956 CloneString(&value,attribute);
2957 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2958 }
2959 flop_image=FlopImage(msl_info->image[n],
2960 &msl_info->image[n]->exception);
2961 if (flop_image == (Image *) NULL)
2962 break;
2963 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2964 msl_info->image[n]=flop_image;
2965 break;
2966 }
cristyb988fe72009-09-16 01:01:10 +00002967 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002968 {
2969 FrameInfo
2970 frame_info;
2971
2972 Image
2973 *frame_image;
2974
2975 /*
2976 Frame image.
2977 */
2978 if (msl_info->image[n] == (Image *) NULL)
2979 {
cristyb988fe72009-09-16 01:01:10 +00002980 ThrowMSLException(OptionError,"NoImagesDefined",
2981 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002982 break;
2983 }
2984 SetGeometry(msl_info->image[n],&geometry);
2985 if (attributes != (const xmlChar **) NULL)
2986 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2987 {
2988 keyword=(const char *) attributes[i++];
2989 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002990 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002991 CloneString(&value,attribute);
2992 switch (*keyword)
2993 {
2994 case 'C':
2995 case 'c':
2996 {
2997 if (LocaleCompare(keyword,"compose") == 0)
2998 {
2999 option=ParseMagickOption(MagickComposeOptions,
3000 MagickFalse,value);
3001 if (option < 0)
3002 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3003 value);
3004 msl_info->image[n]->compose=(CompositeOperator) option;
3005 break;
3006 }
3007 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3008 keyword);
3009 break;
3010 }
3011 case 'F':
3012 case 'f':
3013 {
3014 if (LocaleCompare(keyword, "fill") == 0)
3015 {
3016 (void) QueryColorDatabase(value,
3017 &msl_info->image[n]->matte_color,&exception);
3018 break;
3019 }
3020 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3021 keyword);
3022 break;
3023 }
3024 case 'G':
3025 case 'g':
3026 {
3027 if (LocaleCompare(keyword,"geometry") == 0)
3028 {
3029 flags=ParsePageGeometry(msl_info->image[n],value,
3030 &geometry,&exception);
3031 if ((flags & HeightValue) == 0)
3032 geometry.height=geometry.width;
3033 frame_info.width=geometry.width;
3034 frame_info.height=geometry.height;
3035 frame_info.outer_bevel=geometry.x;
3036 frame_info.inner_bevel=geometry.y;
3037 break;
3038 }
3039 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3040 keyword);
3041 break;
3042 }
3043 case 'H':
3044 case 'h':
3045 {
3046 if (LocaleCompare(keyword,"height") == 0)
3047 {
3048 frame_info.height=atol(value);
3049 break;
3050 }
3051 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3052 keyword);
3053 break;
3054 }
3055 case 'I':
3056 case 'i':
3057 {
3058 if (LocaleCompare(keyword,"inner") == 0)
3059 {
3060 frame_info.inner_bevel=atol(value);
3061 break;
3062 }
3063 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3064 keyword);
3065 break;
3066 }
3067 case 'O':
3068 case 'o':
3069 {
3070 if (LocaleCompare(keyword,"outer") == 0)
3071 {
3072 frame_info.outer_bevel=atol(value);
3073 break;
3074 }
3075 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3076 keyword);
3077 break;
3078 }
3079 case 'W':
3080 case 'w':
3081 {
3082 if (LocaleCompare(keyword,"width") == 0)
3083 {
3084 frame_info.width=atol(value);
3085 break;
3086 }
3087 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3088 keyword);
3089 break;
3090 }
3091 default:
3092 {
3093 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3094 keyword);
3095 break;
3096 }
3097 }
3098 }
3099 frame_info.x=(long) frame_info.width;
3100 frame_info.y=(long) frame_info.height;
3101 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3102 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3103 frame_image=FrameImage(msl_info->image[n],&frame_info,
3104 &msl_info->image[n]->exception);
3105 if (frame_image == (Image *) NULL)
3106 break;
3107 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3108 msl_info->image[n]=frame_image;
3109 break;
3110 }
3111 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3112 }
3113 case 'G':
3114 case 'g':
3115 {
cristyb988fe72009-09-16 01:01:10 +00003116 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003117 {
3118 char
3119 gamma[MaxTextExtent];
3120
3121 MagickPixelPacket
3122 pixel;
3123
3124 /*
3125 Gamma image.
3126 */
3127 if (msl_info->image[n] == (Image *) NULL)
3128 {
cristyb988fe72009-09-16 01:01:10 +00003129 ThrowMSLException(OptionError,"NoImagesDefined",
3130 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003131 break;
3132 }
3133 channel=UndefinedChannel;
3134 pixel.red=0.0;
3135 pixel.green=0.0;
3136 pixel.blue=0.0;
3137 *gamma='\0';
3138 if (attributes != (const xmlChar **) NULL)
3139 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3140 {
3141 keyword=(const char *) attributes[i++];
3142 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003143 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003144 CloneString(&value,attribute);
3145 switch (*keyword)
3146 {
3147 case 'B':
3148 case 'b':
3149 {
3150 if (LocaleCompare(keyword,"blue") == 0)
3151 {
3152 pixel.blue=atof(value);
3153 break;
3154 }
3155 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3156 keyword);
3157 break;
3158 }
3159 case 'C':
3160 case 'c':
3161 {
3162 if (LocaleCompare(keyword,"channel") == 0)
3163 {
3164 option=ParseChannelOption(value);
3165 if (option < 0)
3166 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3167 value);
3168 channel=(ChannelType) option;
3169 break;
3170 }
3171 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3172 keyword);
3173 break;
3174 }
3175 case 'G':
3176 case 'g':
3177 {
3178 if (LocaleCompare(keyword,"gamma") == 0)
3179 {
3180 (void) CopyMagickString(gamma,value,MaxTextExtent);
3181 break;
3182 }
3183 if (LocaleCompare(keyword,"green") == 0)
3184 {
3185 pixel.green=atof(value);
3186 break;
3187 }
3188 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3189 keyword);
3190 break;
3191 }
3192 case 'R':
3193 case 'r':
3194 {
3195 if (LocaleCompare(keyword,"red") == 0)
3196 {
3197 pixel.red=atof(value);
3198 break;
3199 }
3200 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3201 keyword);
3202 break;
3203 }
3204 default:
3205 {
3206 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3207 keyword);
3208 break;
3209 }
3210 }
3211 }
3212 if (*gamma == '\0')
3213 (void) FormatMagickString(gamma,MaxTextExtent,"%g,%g,%g",
3214 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb988fe72009-09-16 01:01:10 +00003215 switch (channel)
cristy3ed852e2009-09-05 21:47:34 +00003216 {
3217 default:
3218 {
3219 (void) GammaImage(msl_info->image[n],gamma);
3220 break;
3221 }
3222 case RedChannel:
3223 {
3224 (void) GammaImageChannel(msl_info->image[n],RedChannel,pixel.red);
3225 break;
3226 }
3227 case GreenChannel:
3228 {
3229 (void) GammaImageChannel(msl_info->image[n],GreenChannel,
3230 pixel.green);
3231 break;
3232 }
3233 case BlueChannel:
3234 {
3235 (void) GammaImageChannel(msl_info->image[n],BlueChannel,
3236 pixel.blue);
3237 break;
3238 }
3239 }
3240 break;
3241 }
cristyb988fe72009-09-16 01:01:10 +00003242 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003243 {
3244 if (msl_info->image[n] == (Image *) NULL)
3245 {
cristyb988fe72009-09-16 01:01:10 +00003246 ThrowMSLException(OptionError,"NoImagesDefined",
3247 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003248 break;
3249 }
3250 if (attributes == (const xmlChar **) NULL)
3251 break;
3252 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3253 {
3254 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003255 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003256 (void) CopyMagickString(key,value,MaxTextExtent);
3257 switch (*keyword)
3258 {
3259 case 'H':
3260 case 'h':
3261 {
3262 if (LocaleCompare(keyword,"height") == 0)
3263 {
3264 (void) FormatMagickString(value,MaxTextExtent,"%ld",
3265 msl_info->image[n]->rows);
3266 (void) SetImageProperty(msl_info->attributes[n],key,value);
3267 break;
3268 }
3269 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3270 }
3271 case 'W':
3272 case 'w':
3273 {
3274 if (LocaleCompare(keyword,"width") == 0)
3275 {
3276 (void) FormatMagickString(value,MaxTextExtent,"%ld",
3277 msl_info->image[n]->columns);
3278 (void) SetImageProperty(msl_info->attributes[n],key,value);
3279 break;
3280 }
3281 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3282 }
3283 default:
3284 {
3285 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3286 break;
3287 }
3288 }
3289 }
3290 break;
3291 }
cristyb988fe72009-09-16 01:01:10 +00003292 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003293 {
3294 msl_info->number_groups++;
3295 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3296 msl_info->group_info,msl_info->number_groups+1UL,
3297 sizeof(*msl_info->group_info));
3298 break;
3299 }
3300 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3301 }
3302 case 'I':
3303 case 'i':
3304 {
cristyb988fe72009-09-16 01:01:10 +00003305 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003306 {
cristy3ed852e2009-09-05 21:47:34 +00003307 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003308 if (attributes == (const xmlChar **) NULL)
3309 break;
3310 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3311 {
3312 keyword=(const char *) attributes[i++];
3313 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003314 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00003315 switch (*keyword)
3316 {
cristyb988fe72009-09-16 01:01:10 +00003317 case 'C':
3318 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003319 {
cristyb988fe72009-09-16 01:01:10 +00003320 if (LocaleCompare(keyword,"color") == 0)
3321 {
3322 Image
3323 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003324
cristyb988fe72009-09-16 01:01:10 +00003325 (void) CopyMagickString(msl_info->image_info[n]->filename,
3326 "xc:",MaxTextExtent);
3327 (void) ConcatenateMagickString(msl_info->image_info[n]->
3328 filename,value,MaxTextExtent);
3329 next_image=ReadImage(msl_info->image_info[n],&exception);
3330 CatchException(&exception);
3331 if (next_image == (Image *) NULL)
3332 continue;
3333 if (msl_info->image[n] == (Image *) NULL)
3334 msl_info->image[n]=next_image;
3335 else
3336 {
3337 register Image
3338 *p;
cristy3ed852e2009-09-05 21:47:34 +00003339
cristyb988fe72009-09-16 01:01:10 +00003340 /*
3341 Link image into image list.
3342 */
3343 p=msl_info->image[n];
3344 while (p->next != (Image *) NULL)
3345 p=GetNextImageInList(p);
3346 next_image->previous=p;
3347 p->next=next_image;
3348 }
3349 break;
3350 }
cristyb20775d2009-09-16 01:51:41 +00003351 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003352 break;
3353 }
3354 default:
3355 {
cristyb20775d2009-09-16 01:51:41 +00003356 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003357 break;
3358 }
3359 }
3360 }
3361 break;
3362 }
cristyb988fe72009-09-16 01:01:10 +00003363 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003364 {
3365 Image
3366 *implode_image;
3367
3368 /*
3369 Implode image.
3370 */
3371 if (msl_info->image[n] == (Image *) NULL)
3372 {
cristyb988fe72009-09-16 01:01:10 +00003373 ThrowMSLException(OptionError,"NoImagesDefined",
3374 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003375 break;
3376 }
3377 if (attributes != (const xmlChar **) NULL)
3378 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3379 {
3380 keyword=(const char *) attributes[i++];
3381 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003382 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003383 CloneString(&value,attribute);
3384 switch (*keyword)
3385 {
3386 case 'A':
3387 case 'a':
3388 {
3389 if (LocaleCompare(keyword,"amount") == 0)
3390 {
3391 geometry_info.rho=atof(value);
3392 break;
3393 }
3394 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3395 keyword);
3396 break;
3397 }
3398 case 'G':
3399 case 'g':
3400 {
3401 if (LocaleCompare(keyword,"geometry") == 0)
3402 {
3403 flags=ParseGeometry(value,&geometry_info);
3404 if ((flags & SigmaValue) == 0)
3405 geometry_info.sigma=1.0;
3406 break;
3407 }
3408 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3409 keyword);
3410 break;
3411 }
3412 default:
3413 {
3414 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3415 keyword);
3416 break;
3417 }
3418 }
3419 }
3420 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3421 &msl_info->image[n]->exception);
3422 if (implode_image == (Image *) NULL)
3423 break;
3424 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3425 msl_info->image[n]=implode_image;
3426 break;
3427 }
3428 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3429 }
3430 case 'L':
3431 case 'l':
3432 {
cristyb988fe72009-09-16 01:01:10 +00003433 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003434 break;
cristyb988fe72009-09-16 01:01:10 +00003435 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003436 {
3437 double
3438 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3439
3440 if (msl_info->image[n] == (Image *) NULL)
3441 {
cristyb988fe72009-09-16 01:01:10 +00003442 ThrowMSLException(OptionError,"NoImagesDefined",
3443 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003444 break;
3445 }
3446 if (attributes == (const xmlChar **) NULL)
3447 break;
3448 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3449 {
3450 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003451 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003452 (void) CopyMagickString(key,value,MaxTextExtent);
3453 switch (*keyword)
3454 {
3455 case 'B':
3456 case 'b':
3457 {
3458 if (LocaleCompare(keyword,"black") == 0)
3459 {
3460 levelBlack = atof( value );
3461 break;
3462 }
3463 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3464 break;
3465 }
3466 case 'G':
3467 case 'g':
3468 {
3469 if (LocaleCompare(keyword,"gamma") == 0)
3470 {
3471 levelGamma = atof( value );
3472 break;
3473 }
3474 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3475 break;
3476 }
3477 case 'W':
3478 case 'w':
3479 {
3480 if (LocaleCompare(keyword,"white") == 0)
3481 {
3482 levelWhite = atof( value );
3483 break;
3484 }
3485 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3486 break;
3487 }
3488 default:
3489 {
3490 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3491 break;
3492 }
3493 }
3494 }
3495
3496 /* process image */
3497 {
3498 char level[MaxTextExtent + 1];
3499 (void) FormatMagickString(level,MaxTextExtent,"%3.6f/%3.6f/%3.6f/",
3500 levelBlack,levelGamma,levelWhite);
3501 LevelImage ( msl_info->image[n], level );
3502 break;
3503 }
3504 }
3505 }
3506 case 'M':
3507 case 'm':
3508 {
cristyb988fe72009-09-16 01:01:10 +00003509 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003510 {
3511 Image
3512 *magnify_image;
3513
3514 /*
3515 Magnify image.
3516 */
3517 if (msl_info->image[n] == (Image *) NULL)
3518 {
cristyb988fe72009-09-16 01:01:10 +00003519 ThrowMSLException(OptionError,"NoImagesDefined",
3520 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003521 break;
3522 }
3523 if (attributes != (const xmlChar **) NULL)
3524 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3525 {
3526 keyword=(const char *) attributes[i++];
3527 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003528 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003529 CloneString(&value,attribute);
3530 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3531 }
3532 magnify_image=MagnifyImage(msl_info->image[n],
3533 &msl_info->image[n]->exception);
3534 if (magnify_image == (Image *) NULL)
3535 break;
3536 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3537 msl_info->image[n]=magnify_image;
3538 break;
3539 }
cristyb988fe72009-09-16 01:01:10 +00003540 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003541 {
3542 Image
3543 *affinity_image;
3544
3545 MagickBooleanType
3546 dither;
3547
3548 QuantizeInfo
3549 *quantize_info;
3550
3551 /*
3552 Map image.
3553 */
3554 if (msl_info->image[n] == (Image *) NULL)
3555 {
cristyb988fe72009-09-16 01:01:10 +00003556 ThrowMSLException(OptionError,"NoImagesDefined",
3557 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003558 break;
3559 }
3560 affinity_image=NewImageList();
3561 dither=MagickFalse;
3562 if (attributes != (const xmlChar **) NULL)
3563 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3564 {
3565 keyword=(const char *) attributes[i++];
3566 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003567 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003568 CloneString(&value,attribute);
3569 switch (*keyword)
3570 {
3571 case 'D':
3572 case 'd':
3573 {
3574 if (LocaleCompare(keyword,"dither") == 0)
3575 {
3576 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
3577 value);
3578 if (option < 0)
3579 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3580 value);
3581 dither=(MagickBooleanType) option;
3582 break;
3583 }
3584 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3585 keyword);
3586 break;
3587 }
3588 case 'I':
3589 case 'i':
3590 {
3591 if (LocaleCompare(keyword,"image") == 0)
3592 for (j=0; j < msl_info->n; j++)
3593 {
3594 const char
3595 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003596
cristy3ed852e2009-09-05 21:47:34 +00003597 attribute=GetImageProperty(msl_info->attributes[j],"id");
3598 if ((attribute != (const char *) NULL) &&
3599 (LocaleCompare(attribute,value) == 0))
3600 {
3601 affinity_image=CloneImage(msl_info->image[j],0,0,
3602 MagickFalse,&exception);
3603 break;
3604 }
3605 }
3606 break;
3607 }
3608 default:
3609 {
3610 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3611 keyword);
3612 break;
3613 }
3614 }
3615 }
3616 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3617 quantize_info->dither=dither;
3618 (void) RemapImages(quantize_info,msl_info->image[n],
3619 affinity_image);
3620 quantize_info=DestroyQuantizeInfo(quantize_info);
3621 affinity_image=DestroyImage(affinity_image);
3622 break;
3623 }
cristyb988fe72009-09-16 01:01:10 +00003624 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003625 {
3626 double
3627 opacity;
3628
3629 MagickPixelPacket
3630 target;
3631
3632 PaintMethod
3633 paint_method;
3634
3635 /*
3636 Matte floodfill image.
3637 */
3638 opacity=0.0;
3639 if (msl_info->image[n] == (Image *) NULL)
3640 {
cristyb988fe72009-09-16 01:01:10 +00003641 ThrowMSLException(OptionError,"NoImagesDefined",
3642 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003643 break;
3644 }
3645 SetGeometry(msl_info->image[n],&geometry);
3646 paint_method=FloodfillMethod;
3647 if (attributes != (const xmlChar **) NULL)
3648 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3649 {
3650 keyword=(const char *) attributes[i++];
3651 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003652 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003653 CloneString(&value,attribute);
3654 switch (*keyword)
3655 {
3656 case 'B':
3657 case 'b':
3658 {
3659 if (LocaleCompare(keyword,"bordercolor") == 0)
3660 {
3661 (void) QueryMagickColor(value,&target,&exception);
3662 paint_method=FillToBorderMethod;
3663 break;
3664 }
3665 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3666 keyword);
3667 break;
3668 }
3669 case 'F':
3670 case 'f':
3671 {
3672 if (LocaleCompare(keyword,"fuzz") == 0)
3673 {
3674 msl_info->image[n]->fuzz=atof(value);
3675 break;
3676 }
3677 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3678 keyword);
3679 break;
3680 }
3681 case 'G':
3682 case 'g':
3683 {
3684 if (LocaleCompare(keyword,"geometry") == 0)
3685 {
3686 flags=ParsePageGeometry(msl_info->image[n],value,
3687 &geometry,&exception);
3688 if ((flags & HeightValue) == 0)
3689 geometry.height=geometry.width;
3690 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3691 geometry.x,geometry.y,&target,&exception);
3692 break;
3693 }
3694 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3695 keyword);
3696 break;
3697 }
3698 case 'O':
3699 case 'o':
3700 {
3701 if (LocaleCompare(keyword,"opacity") == 0)
3702 {
3703 opacity=atof(value);
3704 break;
3705 }
3706 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3707 keyword);
3708 break;
3709 }
3710 case 'X':
3711 case 'x':
3712 {
3713 if (LocaleCompare(keyword,"x") == 0)
3714 {
3715 geometry.x=atol(value);
3716 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3717 geometry.x,geometry.y,&target,&exception);
3718 break;
3719 }
3720 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3721 keyword);
3722 break;
3723 }
3724 case 'Y':
3725 case 'y':
3726 {
3727 if (LocaleCompare(keyword,"y") == 0)
3728 {
3729 geometry.y=atol(value);
3730 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3731 geometry.x,geometry.y,&target,&exception);
3732 break;
3733 }
3734 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3735 keyword);
3736 break;
3737 }
3738 default:
3739 {
3740 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3741 keyword);
3742 break;
3743 }
3744 }
3745 }
3746 draw_info=CloneDrawInfo(msl_info->image_info[n],
3747 msl_info->draw_info[n]);
3748 draw_info->fill.opacity=RoundToQuantum(opacity);
3749 (void) FloodfillPaintImage(msl_info->image[n],OpacityChannel,
3750 draw_info,&target,geometry.x,geometry.y,
3751 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
3752 draw_info=DestroyDrawInfo(draw_info);
3753 break;
3754 }
cristyb988fe72009-09-16 01:01:10 +00003755 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003756 {
3757 Image
3758 *median_image;
3759
3760 /*
3761 Median-filter image.
3762 */
3763 if (msl_info->image[n] == (Image *) NULL)
3764 {
cristyb988fe72009-09-16 01:01:10 +00003765 ThrowMSLException(OptionError,"NoImagesDefined",
3766 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003767 break;
3768 }
3769 if (attributes != (const xmlChar **) NULL)
3770 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3771 {
3772 keyword=(const char *) attributes[i++];
3773 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003774 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003775 CloneString(&value,attribute);
3776 switch (*keyword)
3777 {
3778 case 'G':
3779 case 'g':
3780 {
3781 if (LocaleCompare(keyword,"geometry") == 0)
3782 {
3783 flags=ParseGeometry(value,&geometry_info);
3784 if ((flags & SigmaValue) == 0)
3785 geometry_info.sigma=1.0;
3786 break;
3787 }
3788 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3789 keyword);
3790 break;
3791 }
3792 case 'R':
3793 case 'r':
3794 {
3795 if (LocaleCompare(keyword,"radius") == 0)
3796 {
3797 geometry_info.rho=atof(value);
3798 break;
3799 }
3800 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3801 keyword);
3802 break;
3803 }
3804 default:
3805 {
3806 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3807 keyword);
3808 break;
3809 }
3810 }
3811 }
3812 median_image=MedianFilterImage(msl_info->image[n],geometry_info.rho,
3813 &msl_info->image[n]->exception);
3814 if (median_image == (Image *) NULL)
3815 break;
3816 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3817 msl_info->image[n]=median_image;
3818 break;
3819 }
cristyb988fe72009-09-16 01:01:10 +00003820 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003821 {
3822 Image
3823 *minify_image;
3824
3825 /*
3826 Minify image.
3827 */
3828 if (msl_info->image[n] == (Image *) NULL)
3829 {
cristyb988fe72009-09-16 01:01:10 +00003830 ThrowMSLException(OptionError,"NoImagesDefined",
3831 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003832 break;
3833 }
3834 if (attributes != (const xmlChar **) NULL)
3835 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3836 {
3837 keyword=(const char *) attributes[i++];
3838 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003839 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003840 CloneString(&value,attribute);
3841 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3842 }
3843 minify_image=MinifyImage(msl_info->image[n],
3844 &msl_info->image[n]->exception);
3845 if (minify_image == (Image *) NULL)
3846 break;
3847 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3848 msl_info->image[n]=minify_image;
3849 break;
3850 }
cristyb988fe72009-09-16 01:01:10 +00003851 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003852 break;
cristyb988fe72009-09-16 01:01:10 +00003853 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003854 {
3855 char
3856 modulate[MaxTextExtent];
3857
3858 /*
3859 Modulate image.
3860 */
3861 if (msl_info->image[n] == (Image *) NULL)
3862 {
cristyb988fe72009-09-16 01:01:10 +00003863 ThrowMSLException(OptionError,"NoImagesDefined",
3864 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003865 break;
3866 }
3867 geometry_info.rho=100.0;
3868 geometry_info.sigma=100.0;
3869 geometry_info.xi=100.0;
3870 if (attributes != (const xmlChar **) NULL)
3871 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3872 {
3873 keyword=(const char *) attributes[i++];
3874 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003875 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003876 CloneString(&value,attribute);
3877 switch (*keyword)
3878 {
3879 case 'B':
3880 case 'b':
3881 {
3882 if (LocaleCompare(keyword,"blackness") == 0)
3883 {
3884 geometry_info.rho=atof(value);
3885 break;
3886 }
3887 if (LocaleCompare(keyword,"brightness") == 0)
3888 {
3889 geometry_info.rho=atof(value);
3890 break;
3891 }
3892 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3893 keyword);
3894 break;
3895 }
3896 case 'F':
3897 case 'f':
3898 {
3899 if (LocaleCompare(keyword,"factor") == 0)
3900 {
3901 flags=ParseGeometry(value,&geometry_info);
3902 break;
3903 }
3904 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3905 keyword);
3906 break;
3907 }
3908 case 'H':
3909 case 'h':
3910 {
3911 if (LocaleCompare(keyword,"hue") == 0)
3912 {
3913 geometry_info.xi=atof(value);
3914 break;
3915 }
3916 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3917 keyword);
3918 break;
3919 }
3920 case 'L':
3921 case 'l':
3922 {
3923 if (LocaleCompare(keyword,"lightness") == 0)
3924 {
3925 geometry_info.rho=atof(value);
3926 break;
3927 }
3928 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3929 keyword);
3930 break;
3931 }
3932 case 'S':
3933 case 's':
3934 {
3935 if (LocaleCompare(keyword,"saturation") == 0)
3936 {
3937 geometry_info.sigma=atof(value);
3938 break;
3939 }
3940 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3941 keyword);
3942 break;
3943 }
3944 case 'W':
3945 case 'w':
3946 {
3947 if (LocaleCompare(keyword,"whiteness") == 0)
3948 {
3949 geometry_info.sigma=atof(value);
3950 break;
3951 }
3952 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3953 keyword);
3954 break;
3955 }
3956 default:
3957 {
3958 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3959 keyword);
3960 break;
3961 }
3962 }
3963 }
3964 (void) FormatMagickString(modulate,MaxTextExtent,"%g,%g,%g",
3965 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
3966 (void) ModulateImage(msl_info->image[n],modulate);
3967 break;
3968 }
3969 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3970 }
3971 case 'N':
3972 case 'n':
3973 {
cristyb988fe72009-09-16 01:01:10 +00003974 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003975 {
3976 MagickBooleanType
3977 gray;
3978
3979 /*
3980 Negate image.
3981 */
3982 if (msl_info->image[n] == (Image *) NULL)
3983 {
cristyb988fe72009-09-16 01:01:10 +00003984 ThrowMSLException(OptionError,"NoImagesDefined",
3985 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003986 break;
3987 }
3988 gray=MagickFalse;
3989 if (attributes != (const xmlChar **) NULL)
3990 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3991 {
3992 keyword=(const char *) attributes[i++];
3993 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003994 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003995 CloneString(&value,attribute);
3996 switch (*keyword)
3997 {
3998 case 'C':
3999 case 'c':
4000 {
4001 if (LocaleCompare(keyword,"channel") == 0)
4002 {
4003 option=ParseChannelOption(value);
4004 if (option < 0)
4005 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4006 value);
4007 channel=(ChannelType) option;
4008 break;
4009 }
4010 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4011 keyword);
4012 break;
4013 }
4014 case 'G':
4015 case 'g':
4016 {
4017 if (LocaleCompare(keyword,"gray") == 0)
4018 {
4019 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4020 value);
4021 if (option < 0)
4022 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4023 value);
4024 gray=(MagickBooleanType) option;
4025 break;
4026 }
4027 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4028 keyword);
4029 break;
4030 }
4031 default:
4032 {
4033 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4034 keyword);
4035 break;
4036 }
4037 }
4038 }
4039 (void) NegateImageChannel(msl_info->image[n],channel,gray);
4040 break;
4041 }
cristyb988fe72009-09-16 01:01:10 +00004042 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004043 {
4044 /*
4045 Normalize image.
4046 */
4047 if (msl_info->image[n] == (Image *) NULL)
4048 {
cristyb988fe72009-09-16 01:01:10 +00004049 ThrowMSLException(OptionError,"NoImagesDefined",
4050 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004051 break;
4052 }
4053 if (attributes != (const xmlChar **) NULL)
4054 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4055 {
4056 keyword=(const char *) attributes[i++];
4057 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004058 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004059 CloneString(&value,attribute);
4060 switch (*keyword)
4061 {
4062 case 'C':
4063 case 'c':
4064 {
4065 if (LocaleCompare(keyword,"channel") == 0)
4066 {
4067 option=ParseChannelOption(value);
4068 if (option < 0)
4069 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4070 value);
4071 channel=(ChannelType) option;
4072 break;
4073 }
4074 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4075 keyword);
4076 break;
4077 }
4078 default:
4079 {
4080 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4081 keyword);
4082 break;
4083 }
4084 }
4085 }
4086 (void) NormalizeImageChannel(msl_info->image[n],channel);
4087 break;
4088 }
4089 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4090 }
4091 case 'O':
4092 case 'o':
4093 {
cristyb988fe72009-09-16 01:01:10 +00004094 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004095 {
4096 Image
4097 *paint_image;
4098
4099 /*
4100 Oil-paint image.
4101 */
4102 if (msl_info->image[n] == (Image *) NULL)
4103 {
cristyb988fe72009-09-16 01:01:10 +00004104 ThrowMSLException(OptionError,"NoImagesDefined",
4105 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004106 break;
4107 }
4108 if (attributes != (const xmlChar **) NULL)
4109 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4110 {
4111 keyword=(const char *) attributes[i++];
4112 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004113 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004114 CloneString(&value,attribute);
4115 switch (*keyword)
4116 {
4117 case 'G':
4118 case 'g':
4119 {
4120 if (LocaleCompare(keyword,"geometry") == 0)
4121 {
4122 flags=ParseGeometry(value,&geometry_info);
4123 if ((flags & SigmaValue) == 0)
4124 geometry_info.sigma=1.0;
4125 break;
4126 }
4127 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4128 keyword);
4129 break;
4130 }
4131 case 'R':
4132 case 'r':
4133 {
4134 if (LocaleCompare(keyword,"radius") == 0)
4135 {
4136 geometry_info.rho=atof(value);
4137 break;
4138 }
4139 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4140 keyword);
4141 break;
4142 }
4143 default:
4144 {
4145 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4146 keyword);
4147 break;
4148 }
4149 }
4150 }
4151 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4152 &msl_info->image[n]->exception);
4153 if (paint_image == (Image *) NULL)
4154 break;
4155 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4156 msl_info->image[n]=paint_image;
4157 break;
4158 }
cristyb988fe72009-09-16 01:01:10 +00004159 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004160 {
4161 MagickPixelPacket
4162 fill_color,
4163 target;
4164
4165 /*
4166 Opaque image.
4167 */
4168 if (msl_info->image[n] == (Image *) NULL)
4169 {
cristyb988fe72009-09-16 01:01:10 +00004170 ThrowMSLException(OptionError,"NoImagesDefined",
4171 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004172 break;
4173 }
4174 (void) QueryMagickColor("none",&target,&exception);
4175 (void) QueryMagickColor("none",&fill_color,&exception);
4176 if (attributes != (const xmlChar **) NULL)
4177 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4178 {
4179 keyword=(const char *) attributes[i++];
4180 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004181 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004182 CloneString(&value,attribute);
4183 switch (*keyword)
4184 {
4185 case 'C':
4186 case 'c':
4187 {
4188 if (LocaleCompare(keyword,"channel") == 0)
4189 {
4190 option=ParseChannelOption(value);
4191 if (option < 0)
4192 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4193 value);
4194 channel=(ChannelType) option;
4195 break;
4196 }
4197 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4198 keyword);
4199 break;
4200 }
4201 case 'F':
4202 case 'f':
4203 {
4204 if (LocaleCompare(keyword,"fill") == 0)
4205 {
4206 (void) QueryMagickColor(value,&fill_color,&exception);
4207 break;
4208 }
4209 if (LocaleCompare(keyword,"fuzz") == 0)
4210 {
4211 msl_info->image[n]->fuzz=atof(value);
4212 break;
4213 }
4214 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4215 keyword);
4216 break;
4217 }
4218 default:
4219 {
4220 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4221 keyword);
4222 break;
4223 }
4224 }
4225 }
4226 (void) OpaquePaintImageChannel(msl_info->image[n],channel,
4227 &target,&fill_color,MagickFalse);
4228 break;
4229 }
4230 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4231 }
4232 case 'P':
4233 case 'p':
4234 {
cristyb988fe72009-09-16 01:01:10 +00004235 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004236 {
4237 if (attributes == (const xmlChar **) NULL)
4238 break;
4239 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4240 {
4241 keyword=(const char *) attributes[i++];
4242 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004243 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004244 CloneString(&value,attribute);
4245 switch (*keyword)
4246 {
4247 case 'O':
4248 case 'o':
4249 {
4250 if (LocaleCompare(keyword,"output") == 0)
4251 {
4252 (void) fprintf(stdout,"%s",value);
4253 break;
4254 }
4255 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4256 break;
4257 }
4258 default:
4259 {
4260 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4261 break;
4262 }
4263 }
4264 }
4265 break;
4266 }
cristy4fa36e42009-09-18 14:24:06 +00004267 if (LocaleCompare((const char *) tag, "profile") == 0)
4268 {
cristy4fa36e42009-09-18 14:24:06 +00004269 if (msl_info->image[n] == (Image *) NULL)
4270 {
4271 ThrowMSLException(OptionError,"NoImagesDefined",
4272 (const char *) tag);
4273 break;
4274 }
4275 if (attributes == (const xmlChar **) NULL)
4276 break;
4277 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4278 {
4279 const char
4280 *name;
4281
4282 const StringInfo
4283 *profile;
4284
4285 Image
4286 *profile_image;
4287
4288 ImageInfo
4289 *profile_info;
4290
4291 keyword=(const char *) attributes[i++];
4292 attribute=InterpretImageProperties(msl_info->image_info[n],
4293 msl_info->attributes[n],(const char *) attributes[i]);
4294 CloneString(&value,attribute);
4295 if (*keyword == '+')
4296 {
4297 /*
4298 Remove a profile from the image.
4299 */
4300 (void) ProfileImage(msl_info->image[n],keyword,
4301 (const unsigned char *) NULL,0,MagickTrue);
4302 continue;
4303 }
4304 /*
4305 Associate a profile with the image.
4306 */
4307 profile_info=CloneImageInfo(msl_info->image_info[n]);
4308 profile=GetImageProfile(msl_info->image[n],"iptc");
4309 if (profile != (StringInfo *) NULL)
4310 profile_info->profile=(void *) CloneStringInfo(profile);
4311 profile_image=GetImageCache(profile_info,keyword,&exception);
4312 profile_info=DestroyImageInfo(profile_info);
4313 if (profile_image == (Image *) NULL)
4314 {
4315 char
4316 name[MaxTextExtent],
4317 filename[MaxTextExtent];
4318
4319 register char
4320 *p;
4321
4322 StringInfo
4323 *profile;
4324
4325 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4326 (void) CopyMagickString(name,keyword,MaxTextExtent);
4327 for (p=filename; *p != '\0'; p++)
4328 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4329 (IsPathAccessible(keyword) == MagickFalse))
4330 {
4331 register char
4332 *q;
4333
4334 /*
4335 Look for profile name (e.g. name:profile).
4336 */
4337 (void) CopyMagickString(name,filename,(size_t)
4338 (p-filename+1));
4339 for (q=filename; *q != '\0'; q++)
4340 *q=(*++p);
4341 break;
4342 }
4343 profile=FileToStringInfo(filename,~0UL,&exception);
4344 if (profile != (StringInfo *) NULL)
4345 {
4346 (void) ProfileImage(msl_info->image[n],name,
4347 GetStringInfoDatum(profile),(unsigned long)
4348 GetStringInfoLength(profile),MagickFalse);
4349 profile=DestroyStringInfo(profile);
4350 }
4351 continue;
4352 }
4353 ResetImageProfileIterator(profile_image);
4354 name=GetNextImageProfile(profile_image);
4355 while (name != (const char *) NULL)
4356 {
4357 profile=GetImageProfile(profile_image,name);
4358 if (profile != (StringInfo *) NULL)
4359 (void) ProfileImage(msl_info->image[n],name,
4360 GetStringInfoDatum(profile),(unsigned long)
4361 GetStringInfoLength(profile),MagickFalse);
4362 name=GetNextImageProfile(profile_image);
4363 }
4364 profile_image=DestroyImage(profile_image);
4365 }
4366 break;
4367 }
cristy3ed852e2009-09-05 21:47:34 +00004368 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4369 }
4370 case 'Q':
4371 case 'q':
4372 {
cristyb988fe72009-09-16 01:01:10 +00004373 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004374 {
4375 QuantizeInfo
4376 quantize_info;
4377
4378 /*
4379 Quantize image.
4380 */
4381 if (msl_info->image[n] == (Image *) NULL)
4382 {
cristyb988fe72009-09-16 01:01:10 +00004383 ThrowMSLException(OptionError,"NoImagesDefined",
4384 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004385 break;
4386 }
4387 GetQuantizeInfo(&quantize_info);
4388 if (attributes != (const xmlChar **) NULL)
4389 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4390 {
4391 keyword=(const char *) attributes[i++];
4392 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004393 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004394 CloneString(&value,attribute);
4395 switch (*keyword)
4396 {
4397 case 'C':
4398 case 'c':
4399 {
4400 if (LocaleCompare(keyword,"colors") == 0)
4401 {
4402 quantize_info.number_colors=atol(value);
4403 break;
4404 }
4405 if (LocaleCompare(keyword,"colorspace") == 0)
4406 {
4407 option=ParseMagickOption(MagickColorspaceOptions,
4408 MagickFalse,value);
4409 if (option < 0)
4410 ThrowMSLException(OptionError,
4411 "UnrecognizedColorspaceType",value);
4412 quantize_info.colorspace=(ColorspaceType) option;
4413 break;
4414 }
4415 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4416 keyword);
4417 break;
4418 }
4419 case 'D':
4420 case 'd':
4421 {
4422 if (LocaleCompare(keyword,"dither") == 0)
4423 {
4424 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4425 value);
4426 if (option < 0)
4427 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4428 value);
4429 quantize_info.dither=(MagickBooleanType) option;
4430 break;
4431 }
4432 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4433 keyword);
4434 break;
4435 }
4436 case 'M':
4437 case 'm':
4438 {
4439 if (LocaleCompare(keyword,"measure") == 0)
4440 {
4441 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4442 value);
4443 if (option < 0)
4444 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4445 value);
4446 quantize_info.measure_error=(MagickBooleanType) option;
4447 break;
4448 }
4449 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4450 keyword);
4451 break;
4452 }
4453 case 'T':
4454 case 't':
4455 {
4456 if (LocaleCompare(keyword,"treedepth") == 0)
4457 {
4458 quantize_info.tree_depth=atol(value);
4459 break;
4460 }
4461 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4462 keyword);
4463 break;
4464 }
4465 default:
4466 {
4467 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4468 keyword);
4469 break;
4470 }
4471 }
4472 }
4473 (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4474 break;
4475 }
cristyb988fe72009-09-16 01:01:10 +00004476 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004477 {
4478 char
4479 text[MaxTextExtent];
4480
4481 MagickBooleanType
4482 status;
4483
4484 TypeMetric
4485 metrics;
4486
4487 /*
4488 Query font metrics.
4489 */
4490 draw_info=CloneDrawInfo(msl_info->image_info[n],
4491 msl_info->draw_info[n]);
4492 angle=0.0;
4493 current=draw_info->affine;
4494 GetAffineMatrix(&affine);
4495 if (attributes != (const xmlChar **) NULL)
4496 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4497 {
4498 keyword=(const char *) attributes[i++];
4499 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004500 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004501 CloneString(&value,attribute);
4502 switch (*keyword)
4503 {
4504 case 'A':
4505 case 'a':
4506 {
4507 if (LocaleCompare(keyword,"affine") == 0)
4508 {
4509 char
4510 *p;
4511
4512 p=value;
4513 draw_info->affine.sx=strtod(p,&p);
4514 if (*p ==',')
4515 p++;
4516 draw_info->affine.rx=strtod(p,&p);
4517 if (*p ==',')
4518 p++;
4519 draw_info->affine.ry=strtod(p,&p);
4520 if (*p ==',')
4521 p++;
4522 draw_info->affine.sy=strtod(p,&p);
4523 if (*p ==',')
4524 p++;
4525 draw_info->affine.tx=strtod(p,&p);
4526 if (*p ==',')
4527 p++;
4528 draw_info->affine.ty=strtod(p,&p);
4529 break;
4530 }
4531 if (LocaleCompare(keyword,"align") == 0)
4532 {
4533 option=ParseMagickOption(MagickAlignOptions,MagickFalse,
4534 value);
4535 if (option < 0)
4536 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4537 value);
4538 draw_info->align=(AlignType) option;
4539 break;
4540 }
4541 if (LocaleCompare(keyword,"antialias") == 0)
4542 {
4543 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4544 value);
4545 if (option < 0)
4546 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4547 value);
4548 draw_info->stroke_antialias=(MagickBooleanType) option;
4549 draw_info->text_antialias=(MagickBooleanType) option;
4550 break;
4551 }
4552 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4553 keyword);
4554 break;
4555 }
4556 case 'D':
4557 case 'd':
4558 {
4559 if (LocaleCompare(keyword,"density") == 0)
4560 {
4561 CloneString(&draw_info->density,value);
4562 break;
4563 }
4564 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4565 keyword);
4566 break;
4567 }
4568 case 'E':
4569 case 'e':
4570 {
4571 if (LocaleCompare(keyword,"encoding") == 0)
4572 {
4573 CloneString(&draw_info->encoding,value);
4574 break;
4575 }
4576 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4577 keyword);
4578 break;
4579 }
4580 case 'F':
4581 case 'f':
4582 {
4583 if (LocaleCompare(keyword, "fill") == 0)
4584 {
4585 (void) QueryColorDatabase(value,&draw_info->fill,
4586 &exception);
4587 break;
4588 }
4589 if (LocaleCompare(keyword,"family") == 0)
4590 {
4591 CloneString(&draw_info->family,value);
4592 break;
4593 }
4594 if (LocaleCompare(keyword,"font") == 0)
4595 {
4596 CloneString(&draw_info->font,value);
4597 break;
4598 }
4599 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4600 keyword);
4601 break;
4602 }
4603 case 'G':
4604 case 'g':
4605 {
4606 if (LocaleCompare(keyword,"geometry") == 0)
4607 {
4608 flags=ParsePageGeometry(msl_info->image[n],value,
4609 &geometry,&exception);
4610 if ((flags & HeightValue) == 0)
4611 geometry.height=geometry.width;
4612 break;
4613 }
4614 if (LocaleCompare(keyword,"gravity") == 0)
4615 {
4616 option=ParseMagickOption(MagickGravityOptions,MagickFalse,
4617 value);
4618 if (option < 0)
4619 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4620 value);
4621 draw_info->gravity=(GravityType) option;
4622 break;
4623 }
4624 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4625 keyword);
4626 break;
4627 }
4628 case 'P':
4629 case 'p':
4630 {
4631 if (LocaleCompare(keyword,"pointsize") == 0)
4632 {
4633 draw_info->pointsize=atof(value);
4634 break;
4635 }
4636 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4637 keyword);
4638 break;
4639 }
4640 case 'R':
4641 case 'r':
4642 {
4643 if (LocaleCompare(keyword,"rotate") == 0)
4644 {
4645 angle=atof(value);
4646 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4647 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4648 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4649 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4650 break;
4651 }
4652 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4653 keyword);
4654 break;
4655 }
4656 case 'S':
4657 case 's':
4658 {
4659 if (LocaleCompare(keyword,"scale") == 0)
4660 {
4661 flags=ParseGeometry(value,&geometry_info);
4662 if ((flags & SigmaValue) == 0)
4663 geometry_info.sigma=1.0;
4664 affine.sx=geometry_info.rho;
4665 affine.sy=geometry_info.sigma;
4666 break;
4667 }
4668 if (LocaleCompare(keyword,"skewX") == 0)
4669 {
4670 angle=atof(value);
4671 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4672 break;
4673 }
4674 if (LocaleCompare(keyword,"skewY") == 0)
4675 {
4676 angle=atof(value);
4677 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4678 break;
4679 }
4680 if (LocaleCompare(keyword,"stretch") == 0)
4681 {
4682 option=ParseMagickOption(MagickStretchOptions,MagickFalse,
4683 value);
4684 if (option < 0)
4685 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4686 value);
4687 draw_info->stretch=(StretchType) option;
4688 break;
4689 }
4690 if (LocaleCompare(keyword, "stroke") == 0)
4691 {
4692 (void) QueryColorDatabase(value,&draw_info->stroke,
4693 &exception);
4694 break;
4695 }
4696 if (LocaleCompare(keyword,"strokewidth") == 0)
4697 {
4698 draw_info->stroke_width=atol(value);
4699 break;
4700 }
4701 if (LocaleCompare(keyword,"style") == 0)
4702 {
4703 option=ParseMagickOption(MagickStyleOptions,MagickFalse,
4704 value);
4705 if (option < 0)
4706 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4707 value);
4708 draw_info->style=(StyleType) option;
4709 break;
4710 }
4711 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4712 keyword);
4713 break;
4714 }
4715 case 'T':
4716 case 't':
4717 {
4718 if (LocaleCompare(keyword,"text") == 0)
4719 {
4720 CloneString(&draw_info->text,value);
4721 break;
4722 }
4723 if (LocaleCompare(keyword,"translate") == 0)
4724 {
4725 flags=ParseGeometry(value,&geometry_info);
4726 if ((flags & SigmaValue) == 0)
4727 geometry_info.sigma=1.0;
4728 affine.tx=geometry_info.rho;
4729 affine.ty=geometry_info.sigma;
4730 break;
4731 }
4732 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4733 keyword);
4734 break;
4735 }
4736 case 'U':
4737 case 'u':
4738 {
4739 if (LocaleCompare(keyword, "undercolor") == 0)
4740 {
4741 (void) QueryColorDatabase(value,&draw_info->undercolor,
4742 &exception);
4743 break;
4744 }
4745 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4746 keyword);
4747 break;
4748 }
4749 case 'W':
4750 case 'w':
4751 {
4752 if (LocaleCompare(keyword,"weight") == 0)
4753 {
4754 draw_info->weight=atol(value);
4755 break;
4756 }
4757 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4758 keyword);
4759 break;
4760 }
4761 case 'X':
4762 case 'x':
4763 {
4764 if (LocaleCompare(keyword,"x") == 0)
4765 {
4766 geometry.x=atol(value);
4767 break;
4768 }
4769 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4770 keyword);
4771 break;
4772 }
4773 case 'Y':
4774 case 'y':
4775 {
4776 if (LocaleCompare(keyword,"y") == 0)
4777 {
4778 geometry.y=atol(value);
4779 break;
4780 }
4781 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4782 keyword);
4783 break;
4784 }
4785 default:
4786 {
4787 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4788 keyword);
4789 break;
4790 }
4791 }
4792 }
4793 (void) FormatMagickString(text,MaxTextExtent,"%lux%lu%+ld%+ld",
4794 geometry.width,geometry.height,geometry.x,geometry.y);
4795 CloneString(&draw_info->geometry,text);
4796 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
4797 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
4798 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
4799 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
4800 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
4801 current.tx;
4802 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
4803 current.ty;
4804 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4805 if (status != MagickFalse)
4806 {
4807 Image
4808 *image;
4809
4810 image=msl_info->attributes[n];
4811 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x","%g",
4812 metrics.pixels_per_em.x);
4813 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y","%g",
4814 metrics.pixels_per_em.y);
4815 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
4816 metrics.ascent);
4817 FormatImageProperty(image,"msl:font-metrics.descent","%g",
4818 metrics.descent);
4819 FormatImageProperty(image,"msl:font-metrics.width","%g",
4820 metrics.width);
4821 FormatImageProperty(image,"msl:font-metrics.height","%g",
4822 metrics.height);
4823 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
4824 metrics.max_advance);
4825 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
4826 metrics.bounds.x1);
4827 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
4828 metrics.bounds.y1);
4829 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
4830 metrics.bounds.x2);
4831 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
4832 metrics.bounds.y2);
4833 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
4834 metrics.origin.x);
4835 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
4836 metrics.origin.y);
4837 }
4838 draw_info=DestroyDrawInfo(draw_info);
4839 break;
4840 }
4841 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4842 }
4843 case 'R':
4844 case 'r':
4845 {
cristyb988fe72009-09-16 01:01:10 +00004846 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004847 {
4848 MagickBooleanType
4849 raise;
4850
4851 /*
4852 Raise image.
4853 */
4854 if (msl_info->image[n] == (Image *) NULL)
4855 {
cristyb988fe72009-09-16 01:01:10 +00004856 ThrowMSLException(OptionError,"NoImagesDefined",
4857 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004858 break;
4859 }
4860 raise=MagickFalse;
4861 SetGeometry(msl_info->image[n],&geometry);
4862 if (attributes != (const xmlChar **) NULL)
4863 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4864 {
4865 keyword=(const char *) attributes[i++];
4866 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004867 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004868 CloneString(&value,attribute);
4869 switch (*keyword)
4870 {
4871 case 'G':
4872 case 'g':
4873 {
4874 if (LocaleCompare(keyword,"geometry") == 0)
4875 {
4876 flags=ParsePageGeometry(msl_info->image[n],value,
4877 &geometry,&exception);
4878 if ((flags & HeightValue) == 0)
4879 geometry.height=geometry.width;
4880 break;
4881 }
4882 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4883 keyword);
4884 break;
4885 }
4886 case 'H':
4887 case 'h':
4888 {
4889 if (LocaleCompare(keyword,"height") == 0)
4890 {
4891 geometry.height=atol(value);
4892 break;
4893 }
4894 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4895 keyword);
4896 break;
4897 }
4898 case 'R':
4899 case 'r':
4900 {
4901 if (LocaleCompare(keyword,"raise") == 0)
4902 {
4903 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
4904 value);
4905 if (option < 0)
4906 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4907 value);
4908 raise=(MagickBooleanType) option;
4909 break;
4910 }
4911 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4912 keyword);
4913 break;
4914 }
4915 case 'W':
4916 case 'w':
4917 {
4918 if (LocaleCompare(keyword,"width") == 0)
4919 {
4920 geometry.width=atol(value);
4921 break;
4922 }
4923 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4924 keyword);
4925 break;
4926 }
4927 default:
4928 {
4929 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4930 keyword);
4931 break;
4932 }
4933 }
4934 }
4935 (void) RaiseImage(msl_info->image[n],&geometry,raise);
4936 break;
4937 }
cristyb988fe72009-09-16 01:01:10 +00004938 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004939 {
4940 if (attributes == (const xmlChar **) NULL)
4941 break;
4942 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4943 {
4944 keyword=(const char *) attributes[i++];
4945 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004946 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00004947 switch (*keyword)
4948 {
4949 case 'F':
4950 case 'f':
4951 {
4952 if (LocaleCompare(keyword,"filename") == 0)
4953 {
4954 Image
4955 *image;
4956
4957 (void) CopyMagickString(msl_info->image_info[n]->filename,
4958 value,MaxTextExtent);
4959 image=ReadImage(msl_info->image_info[n],&exception);
4960 CatchException(&exception);
4961 if (image == (Image *) NULL)
4962 continue;
4963 AppendImageToList(&msl_info->image[n],image);
4964 break;
4965 }
cristy4582cbb2009-09-23 00:35:43 +00004966 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004967 break;
4968 }
4969 default:
4970 {
cristy4582cbb2009-09-23 00:35:43 +00004971 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004972 break;
4973 }
4974 }
4975 }
4976 break;
4977 }
cristyb988fe72009-09-16 01:01:10 +00004978 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004979 {
4980 Image
4981 *paint_image;
4982
4983 /*
4984 Reduce-noise image.
4985 */
4986 if (msl_info->image[n] == (Image *) NULL)
4987 {
cristyb988fe72009-09-16 01:01:10 +00004988 ThrowMSLException(OptionError,"NoImagesDefined",
4989 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004990 break;
4991 }
4992 if (attributes != (const xmlChar **) NULL)
4993 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4994 {
4995 keyword=(const char *) attributes[i++];
4996 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004997 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004998 CloneString(&value,attribute);
4999 switch (*keyword)
5000 {
5001 case 'G':
5002 case 'g':
5003 {
5004 if (LocaleCompare(keyword,"geometry") == 0)
5005 {
5006 flags=ParseGeometry(value,&geometry_info);
5007 if ((flags & SigmaValue) == 0)
5008 geometry_info.sigma=1.0;
5009 break;
5010 }
5011 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5012 keyword);
5013 break;
5014 }
5015 case 'R':
5016 case 'r':
5017 {
5018 if (LocaleCompare(keyword,"radius") == 0)
5019 {
5020 geometry_info.rho=atof(value);
5021 break;
5022 }
5023 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5024 keyword);
5025 break;
5026 }
5027 default:
5028 {
5029 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5030 keyword);
5031 break;
5032 }
5033 }
5034 }
5035 paint_image=ReduceNoiseImage(msl_info->image[n],geometry_info.rho,
5036 &msl_info->image[n]->exception);
5037 if (paint_image == (Image *) NULL)
5038 break;
5039 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5040 msl_info->image[n]=paint_image;
5041 break;
5042 }
cristyb988fe72009-09-16 01:01:10 +00005043 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005044 {
5045 /* init the values */
5046 width=msl_info->image[n]->page.width;
5047 height=msl_info->image[n]->page.height;
5048 x=msl_info->image[n]->page.x;
5049 y=msl_info->image[n]->page.y;
5050
5051 if (msl_info->image[n] == (Image *) NULL)
5052 {
cristyb988fe72009-09-16 01:01:10 +00005053 ThrowMSLException(OptionError,"NoImagesDefined",
5054 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005055 break;
5056 }
5057 if (attributes == (const xmlChar **) NULL)
5058 break;
5059 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5060 {
5061 keyword=(const char *) attributes[i++];
5062 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005063 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005064 switch (*keyword)
5065 {
5066 case 'G':
5067 case 'g':
5068 {
5069 if (LocaleCompare(keyword,"geometry") == 0)
5070 {
5071 int
5072 flags;
5073
5074 RectangleInfo
5075 geometry;
5076
5077 flags=ParseAbsoluteGeometry(value,&geometry);
5078 if ((flags & WidthValue) != 0)
5079 {
5080 if ((flags & HeightValue) == 0)
5081 geometry.height=geometry.width;
5082 width=geometry.width;
5083 height=geometry.height;
5084 }
5085 if ((flags & AspectValue) != 0)
5086 {
5087 if ((flags & XValue) != 0)
5088 x+=geometry.x;
5089 if ((flags & YValue) != 0)
5090 y+=geometry.y;
5091 }
5092 else
5093 {
5094 if ((flags & XValue) != 0)
5095 {
5096 x=geometry.x;
5097 if ((width == 0) && (geometry.x > 0))
5098 width=msl_info->image[n]->columns+geometry.x;
5099 }
5100 if ((flags & YValue) != 0)
5101 {
5102 y=geometry.y;
5103 if ((height == 0) && (geometry.y > 0))
5104 height=msl_info->image[n]->rows+geometry.y;
5105 }
5106 }
5107 break;
5108 }
5109 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5110 break;
5111 }
5112 case 'H':
5113 case 'h':
5114 {
5115 if (LocaleCompare(keyword,"height") == 0)
5116 {
5117 height = atol( value );
5118 break;
5119 }
5120 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5121 break;
5122 }
5123 case 'W':
5124 case 'w':
5125 {
5126 if (LocaleCompare(keyword,"width") == 0)
5127 {
5128 width = atol( value );
5129 break;
5130 }
5131 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5132 break;
5133 }
5134 case 'X':
5135 case 'x':
5136 {
5137 if (LocaleCompare(keyword,"x") == 0)
5138 {
5139 x = atol( value );
5140 break;
5141 }
5142 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5143 break;
5144 }
5145 case 'Y':
5146 case 'y':
5147 {
5148 if (LocaleCompare(keyword,"y") == 0)
5149 {
5150 y = atol( value );
5151 break;
5152 }
5153 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5154 break;
5155 }
5156 default:
5157 {
5158 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5159 break;
5160 }
5161 }
5162 }
5163
cristyb988fe72009-09-16 01:01:10 +00005164 msl_info->image[n]->page.width=width;
5165 msl_info->image[n]->page.height=height;
5166 msl_info->image[n]->page.x=x;
5167 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005168 break;
5169 }
cristyb988fe72009-09-16 01:01:10 +00005170 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005171 {
5172 double
5173 x_resolution,
5174 y_resolution;
5175
5176 if (msl_info->image[n] == (Image *) NULL)
5177 {
cristyb988fe72009-09-16 01:01:10 +00005178 ThrowMSLException(OptionError,"NoImagesDefined",
5179 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005180 break;
5181 }
5182 if (attributes == (const xmlChar **) NULL)
5183 break;
5184 x_resolution=DefaultResolution;
5185 y_resolution=DefaultResolution;
5186 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5187 {
5188 keyword=(const char *) attributes[i++];
5189 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005190 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005191 switch (*keyword)
5192 {
5193 case 'b':
5194 {
5195 if (LocaleCompare(keyword,"blur") == 0)
5196 {
5197 msl_info->image[n]->blur=atof(value);
5198 break;
5199 }
5200 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5201 break;
5202 }
5203 case 'G':
5204 case 'g':
5205 {
5206 if (LocaleCompare(keyword,"geometry") == 0)
5207 {
5208 long
5209 flags;
5210
5211 flags=ParseGeometry(value,&geometry_info);
5212 if ((flags & SigmaValue) == 0)
5213 geometry_info.sigma*=geometry_info.rho;
5214 x_resolution=geometry_info.rho;
5215 y_resolution=geometry_info.sigma;
5216 break;
5217 }
5218 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5219 break;
5220 }
5221 case 'X':
5222 case 'x':
5223 {
5224 if (LocaleCompare(keyword,"x-resolution") == 0)
5225 {
5226 x_resolution=atof(value);
5227 break;
5228 }
5229 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5230 break;
5231 }
5232 case 'Y':
5233 case 'y':
5234 {
5235 if (LocaleCompare(keyword,"y-resolution") == 0)
5236 {
5237 y_resolution=atof(value);
5238 break;
5239 }
5240 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5241 break;
5242 }
5243 default:
5244 {
5245 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5246 break;
5247 }
5248 }
5249 }
5250 /*
5251 Resample image.
5252 */
5253 {
5254 double
5255 factor;
5256
5257 Image
5258 *resample_image;
5259
5260 factor=1.0;
5261 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5262 factor=2.54;
5263 width=(unsigned long) (x_resolution*msl_info->image[n]->columns/
5264 (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5265 msl_info->image[n]->x_resolution))+0.5);
5266 height=(unsigned long) (y_resolution*msl_info->image[n]->rows/
5267 (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5268 msl_info->image[n]->y_resolution))+0.5);
5269 resample_image=ResizeImage(msl_info->image[n],width,height,
5270 msl_info->image[n]->filter,msl_info->image[n]->blur,
5271 &msl_info->image[n]->exception);
5272 if (resample_image == (Image *) NULL)
5273 break;
5274 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5275 msl_info->image[n]=resample_image;
5276 }
5277 break;
5278 }
cristyb988fe72009-09-16 01:01:10 +00005279 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005280 {
5281 double
5282 blur;
5283
5284 FilterTypes
5285 filter;
5286
5287 Image
5288 *resize_image;
5289
5290 /*
5291 Resize image.
5292 */
5293 if (msl_info->image[n] == (Image *) NULL)
5294 {
cristyb988fe72009-09-16 01:01:10 +00005295 ThrowMSLException(OptionError,"NoImagesDefined",
5296 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005297 break;
5298 }
5299 filter=UndefinedFilter;
5300 blur=1.0;
5301 if (attributes != (const xmlChar **) NULL)
5302 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5303 {
5304 keyword=(const char *) attributes[i++];
5305 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005306 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005307 CloneString(&value,attribute);
5308 switch (*keyword)
5309 {
5310 case 'F':
5311 case 'f':
5312 {
5313 if (LocaleCompare(keyword,"filter") == 0)
5314 {
5315 option=ParseMagickOption(MagickFilterOptions,MagickFalse,
5316 value);
5317 if (option < 0)
5318 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5319 value);
5320 filter=(FilterTypes) option;
5321 break;
5322 }
5323 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5324 keyword);
5325 break;
5326 }
5327 case 'G':
5328 case 'g':
5329 {
5330 if (LocaleCompare(keyword,"geometry") == 0)
5331 {
5332 flags=ParseRegionGeometry(msl_info->image[n],value,
5333 &geometry,&exception);
5334 break;
5335 }
5336 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5337 keyword);
5338 break;
5339 }
5340 case 'H':
5341 case 'h':
5342 {
5343 if (LocaleCompare(keyword,"height") == 0)
5344 {
5345 geometry.height=(unsigned long) atol(value);
5346 break;
5347 }
5348 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5349 keyword);
5350 break;
5351 }
5352 case 'S':
5353 case 's':
5354 {
5355 if (LocaleCompare(keyword,"support") == 0)
5356 {
5357 blur=atof(value);
5358 break;
5359 }
5360 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5361 keyword);
5362 break;
5363 }
5364 case 'W':
5365 case 'w':
5366 {
5367 if (LocaleCompare(keyword,"width") == 0)
5368 {
5369 geometry.width=atol(value);
5370 break;
5371 }
5372 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5373 keyword);
5374 break;
5375 }
5376 default:
5377 {
5378 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5379 keyword);
5380 break;
5381 }
5382 }
5383 }
5384 resize_image=ResizeImage(msl_info->image[n],geometry.width,
5385 geometry.height,filter,blur,&msl_info->image[n]->exception);
5386 if (resize_image == (Image *) NULL)
5387 break;
5388 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5389 msl_info->image[n]=resize_image;
5390 break;
5391 }
cristyb988fe72009-09-16 01:01:10 +00005392 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005393 {
5394 Image
5395 *roll_image;
5396
5397 /*
5398 Roll image.
5399 */
5400 if (msl_info->image[n] == (Image *) NULL)
5401 {
cristyb988fe72009-09-16 01:01:10 +00005402 ThrowMSLException(OptionError,"NoImagesDefined",
5403 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005404 break;
5405 }
5406 SetGeometry(msl_info->image[n],&geometry);
5407 if (attributes != (const xmlChar **) NULL)
5408 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5409 {
5410 keyword=(const char *) attributes[i++];
5411 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005412 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005413 CloneString(&value,attribute);
5414 switch (*keyword)
5415 {
5416 case 'G':
5417 case 'g':
5418 {
5419 if (LocaleCompare(keyword,"geometry") == 0)
5420 {
5421 flags=ParsePageGeometry(msl_info->image[n],value,
5422 &geometry,&exception);
5423 if ((flags & HeightValue) == 0)
5424 geometry.height=geometry.width;
5425 break;
5426 }
5427 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5428 keyword);
5429 break;
5430 }
5431 case 'X':
5432 case 'x':
5433 {
5434 if (LocaleCompare(keyword,"x") == 0)
5435 {
5436 geometry.x=atol(value);
5437 break;
5438 }
5439 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5440 keyword);
5441 break;
5442 }
5443 case 'Y':
5444 case 'y':
5445 {
5446 if (LocaleCompare(keyword,"y") == 0)
5447 {
5448 geometry.y=atol(value);
5449 break;
5450 }
5451 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5452 keyword);
5453 break;
5454 }
5455 default:
5456 {
5457 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5458 keyword);
5459 break;
5460 }
5461 }
5462 }
5463 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5464 &msl_info->image[n]->exception);
5465 if (roll_image == (Image *) NULL)
5466 break;
5467 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5468 msl_info->image[n]=roll_image;
5469 break;
5470 }
cristyb988fe72009-09-16 01:01:10 +00005471 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005472 {
5473 /* init the values */
5474 width=msl_info->image[n]->columns;
5475 height=msl_info->image[n]->rows;
5476 x = y = 0;
5477
5478 if (msl_info->image[n] == (Image *) NULL)
5479 {
cristyb988fe72009-09-16 01:01:10 +00005480 ThrowMSLException(OptionError,"NoImagesDefined",
5481 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005482 break;
5483 }
5484 if (attributes == (const xmlChar **) NULL)
5485 break;
5486 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5487 {
5488 keyword=(const char *) attributes[i++];
5489 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005490 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005491 switch (*keyword)
5492 {
5493 case 'G':
5494 case 'g':
5495 {
5496 if (LocaleCompare(keyword,"geometry") == 0)
5497 {
5498 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5499 break;
5500 }
5501 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5502 break;
5503 }
5504 case 'X':
5505 case 'x':
5506 {
5507 if (LocaleCompare(keyword,"x") == 0)
5508 {
5509 x = atol( value );
5510 break;
5511 }
5512 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5513 break;
5514 }
5515 case 'Y':
5516 case 'y':
5517 {
5518 if (LocaleCompare(keyword,"y") == 0)
5519 {
5520 y = atol( value );
5521 break;
5522 }
5523 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5524 break;
5525 }
5526 default:
5527 {
5528 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5529 break;
5530 }
5531 }
5532 }
5533
5534 /*
5535 process image.
5536 */
5537 {
5538 Image
5539 *newImage;
5540
5541 newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5542 if (newImage == (Image *) NULL)
5543 break;
5544 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5545 msl_info->image[n]=newImage;
5546 }
5547
5548 break;
5549 }
cristyb988fe72009-09-16 01:01:10 +00005550 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005551 {
5552 Image
5553 *rotate_image;
5554
5555 /*
5556 Rotate image.
5557 */
5558 if (msl_info->image[n] == (Image *) NULL)
5559 {
cristyb988fe72009-09-16 01:01:10 +00005560 ThrowMSLException(OptionError,"NoImagesDefined",
5561 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005562 break;
5563 }
5564 if (attributes != (const xmlChar **) NULL)
5565 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5566 {
5567 keyword=(const char *) attributes[i++];
5568 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005569 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005570 CloneString(&value,attribute);
5571 switch (*keyword)
5572 {
5573 case 'D':
5574 case 'd':
5575 {
5576 if (LocaleCompare(keyword,"degrees") == 0)
5577 {
5578 geometry_info.rho=atof(value);
5579 break;
5580 }
5581 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5582 keyword);
5583 break;
5584 }
5585 case 'G':
5586 case 'g':
5587 {
5588 if (LocaleCompare(keyword,"geometry") == 0)
5589 {
5590 flags=ParseGeometry(value,&geometry_info);
5591 if ((flags & SigmaValue) == 0)
5592 geometry_info.sigma=1.0;
5593 break;
5594 }
5595 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5596 keyword);
5597 break;
5598 }
5599 default:
5600 {
5601 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5602 keyword);
5603 break;
5604 }
5605 }
5606 }
5607 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5608 &msl_info->image[n]->exception);
5609 if (rotate_image == (Image *) NULL)
5610 break;
5611 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5612 msl_info->image[n]=rotate_image;
5613 break;
5614 }
cristyb988fe72009-09-16 01:01:10 +00005615 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005616 {
5617 /* init the values */
5618 double degrees = 0;
5619
5620 if (msl_info->image[n] == (Image *) NULL)
5621 {
cristyb988fe72009-09-16 01:01:10 +00005622 ThrowMSLException(OptionError,"NoImagesDefined",
5623 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005624 break;
5625 }
5626 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005627 break;
cristy3ed852e2009-09-05 21:47:34 +00005628 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5629 {
5630 keyword=(const char *) attributes[i++];
5631 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005632 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005633 switch (*keyword)
5634 {
5635 case 'D':
5636 case 'd':
5637 {
5638 if (LocaleCompare(keyword,"degrees") == 0)
5639 {
5640 degrees = atof( value );
5641 break;
5642 }
5643 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5644 break;
5645 }
5646 default:
5647 {
5648 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5649 break;
5650 }
5651 }
5652 }
5653
5654 /*
5655 process image.
5656 */
5657 {
5658 Image
5659 *newImage;
5660
5661 newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5662 if (newImage == (Image *) NULL)
5663 break;
5664 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5665 msl_info->image[n]=newImage;
5666 }
5667
5668 break;
5669 }
5670 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5671 }
5672 case 'S':
5673 case 's':
5674 {
cristyb988fe72009-09-16 01:01:10 +00005675 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005676 {
5677 Image
5678 *sample_image;
5679
5680 /*
5681 Sample image.
5682 */
5683 if (msl_info->image[n] == (Image *) NULL)
5684 {
cristyb988fe72009-09-16 01:01:10 +00005685 ThrowMSLException(OptionError,"NoImagesDefined",
5686 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005687 break;
5688 }
5689 if (attributes != (const xmlChar **) NULL)
5690 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5691 {
5692 keyword=(const char *) attributes[i++];
5693 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005694 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005695 CloneString(&value,attribute);
5696 switch (*keyword)
5697 {
5698 case 'G':
5699 case 'g':
5700 {
5701 if (LocaleCompare(keyword,"geometry") == 0)
5702 {
5703 flags=ParseRegionGeometry(msl_info->image[n],value,
5704 &geometry,&exception);
5705 break;
5706 }
5707 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5708 keyword);
5709 break;
5710 }
5711 case 'H':
5712 case 'h':
5713 {
5714 if (LocaleCompare(keyword,"height") == 0)
5715 {
5716 geometry.height=(unsigned long) atol(value);
5717 break;
5718 }
5719 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5720 keyword);
5721 break;
5722 }
5723 case 'W':
5724 case 'w':
5725 {
5726 if (LocaleCompare(keyword,"width") == 0)
5727 {
5728 geometry.width=atol(value);
5729 break;
5730 }
5731 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5732 keyword);
5733 break;
5734 }
5735 default:
5736 {
5737 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5738 keyword);
5739 break;
5740 }
5741 }
5742 }
5743 sample_image=SampleImage(msl_info->image[n],geometry.width,
5744 geometry.height,&msl_info->image[n]->exception);
5745 if (sample_image == (Image *) NULL)
5746 break;
5747 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5748 msl_info->image[n]=sample_image;
5749 break;
5750 }
cristyb988fe72009-09-16 01:01:10 +00005751 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005752 {
5753 Image
5754 *scale_image;
5755
5756 /*
5757 Scale image.
5758 */
5759 if (msl_info->image[n] == (Image *) NULL)
5760 {
cristyb988fe72009-09-16 01:01:10 +00005761 ThrowMSLException(OptionError,"NoImagesDefined",
5762 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005763 break;
5764 }
5765 if (attributes != (const xmlChar **) NULL)
5766 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5767 {
5768 keyword=(const char *) attributes[i++];
5769 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005770 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005771 CloneString(&value,attribute);
5772 switch (*keyword)
5773 {
5774 case 'G':
5775 case 'g':
5776 {
5777 if (LocaleCompare(keyword,"geometry") == 0)
5778 {
5779 flags=ParseRegionGeometry(msl_info->image[n],value,
5780 &geometry,&exception);
5781 break;
5782 }
5783 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5784 keyword);
5785 break;
5786 }
5787 case 'H':
5788 case 'h':
5789 {
5790 if (LocaleCompare(keyword,"height") == 0)
5791 {
5792 geometry.height=(unsigned long) atol(value);
5793 break;
5794 }
5795 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5796 keyword);
5797 break;
5798 }
5799 case 'W':
5800 case 'w':
5801 {
5802 if (LocaleCompare(keyword,"width") == 0)
5803 {
5804 geometry.width=atol(value);
5805 break;
5806 }
5807 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5808 keyword);
5809 break;
5810 }
5811 default:
5812 {
5813 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5814 keyword);
5815 break;
5816 }
5817 }
5818 }
5819 scale_image=ScaleImage(msl_info->image[n],geometry.width,
5820 geometry.height,&msl_info->image[n]->exception);
5821 if (scale_image == (Image *) NULL)
5822 break;
5823 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5824 msl_info->image[n]=scale_image;
5825 break;
5826 }
cristyb988fe72009-09-16 01:01:10 +00005827 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005828 {
5829 ColorspaceType
5830 colorspace;
5831
5832 MagickBooleanType
5833 verbose;
cristyb988fe72009-09-16 01:01:10 +00005834
cristy3ed852e2009-09-05 21:47:34 +00005835 /*
5836 Segment image.
5837 */
5838 if (msl_info->image[n] == (Image *) NULL)
5839 {
cristyb988fe72009-09-16 01:01:10 +00005840 ThrowMSLException(OptionError,"NoImagesDefined",
5841 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005842 break;
5843 }
5844 geometry_info.rho=1.0;
5845 geometry_info.sigma=1.5;
5846 colorspace=RGBColorspace;
5847 verbose=MagickFalse;
5848 if (attributes != (const xmlChar **) NULL)
5849 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5850 {
5851 keyword=(const char *) attributes[i++];
5852 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005853 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005854 CloneString(&value,attribute);
5855 switch (*keyword)
5856 {
5857 case 'C':
5858 case 'c':
5859 {
5860 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5861 {
5862 geometry_info.rho=atof(value);
5863 break;
5864 }
5865 if (LocaleCompare(keyword,"colorspace") == 0)
5866 {
5867 option=ParseMagickOption(MagickColorspaceOptions,
5868 MagickFalse,value);
5869 if (option < 0)
5870 ThrowMSLException(OptionError,
5871 "UnrecognizedColorspaceType",value);
5872 colorspace=(ColorspaceType) option;
5873 break;
5874 }
5875 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5876 keyword);
5877 break;
5878 }
5879 case 'G':
5880 case 'g':
5881 {
5882 if (LocaleCompare(keyword,"geometry") == 0)
5883 {
5884 flags=ParseGeometry(value,&geometry_info);
5885 if ((flags & SigmaValue) == 0)
5886 geometry_info.sigma=1.5;
5887 break;
5888 }
5889 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5890 keyword);
5891 break;
5892 }
5893 case 'S':
5894 case 's':
5895 {
5896 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5897 {
5898 geometry_info.sigma=atof(value);
5899 break;
5900 }
5901 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5902 keyword);
5903 break;
5904 }
5905 default:
5906 {
5907 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5908 keyword);
5909 break;
5910 }
5911 }
5912 }
5913 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5914 geometry_info.rho,geometry_info.sigma);
5915 break;
5916 }
cristyb988fe72009-09-16 01:01:10 +00005917 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005918 {
5919 if (msl_info->image[n] == (Image *) NULL)
5920 {
cristyb988fe72009-09-16 01:01:10 +00005921 ThrowMSLException(OptionError,"NoImagesDefined",
5922 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005923 break;
5924 }
5925
5926 if (attributes == (const xmlChar **) NULL)
5927 break;
5928 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5929 {
5930 keyword=(const char *) attributes[i++];
5931 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005932 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005933 switch (*keyword)
5934 {
cristy3ed852e2009-09-05 21:47:34 +00005935 case 'C':
5936 case 'c':
5937 {
5938 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005939 {
cristy2c8b6312009-09-16 02:37:23 +00005940 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005941 {
cristy2c8b6312009-09-16 02:37:23 +00005942 const char
5943 *property;
5944
5945 property=GetImageProperty(msl_info->attributes[j],"id");
5946 if (LocaleCompare(property,value) == 0)
5947 {
5948 SetImageMask(msl_info->image[n],msl_info->image[j]);
5949 break;
5950 }
cristy3ed852e2009-09-05 21:47:34 +00005951 }
cristy2c8b6312009-09-16 02:37:23 +00005952 break;
cristy3ed852e2009-09-05 21:47:34 +00005953 }
cristy3ed852e2009-09-05 21:47:34 +00005954 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005955 {
cristy2c8b6312009-09-16 02:37:23 +00005956 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005957 {
cristy2c8b6312009-09-16 02:37:23 +00005958 const char
5959 *property;
5960
5961 property=GetImageProperty(msl_info->attributes[j],"id");
5962 if (LocaleCompare(property,value) == 0)
5963 {
5964 SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5965 break;
5966 }
cristy3ed852e2009-09-05 21:47:34 +00005967 }
cristy2c8b6312009-09-16 02:37:23 +00005968 break;
cristy3ed852e2009-09-05 21:47:34 +00005969 }
cristy2c8b6312009-09-16 02:37:23 +00005970 if (LocaleCompare(keyword,"colorspace") == 0)
5971 {
5972 long
5973 colorspace;
5974
5975 colorspace=(ColorspaceType) ParseMagickOption(
5976 MagickColorspaceOptions,MagickFalse,keyword);
5977 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00005978 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00005979 value);
5980 (void) TransformImageColorspace(msl_info->image[n],
5981 (ColorspaceType) colorspace);
5982 break;
5983 }
5984 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005985 break;
5986 }
5987 case 'D':
5988 case 'd':
5989 {
cristy2c8b6312009-09-16 02:37:23 +00005990 if (LocaleCompare(keyword,"density") == 0)
5991 {
5992 flags=ParseGeometry(value,&geometry_info);
5993 msl_info->image[n]->x_resolution=geometry_info.rho;
5994 msl_info->image[n]->y_resolution=geometry_info.sigma;
5995 if ((flags & SigmaValue) == 0)
5996 msl_info->image[n]->y_resolution=
5997 msl_info->image[n]->x_resolution;
5998 break;
5999 }
6000 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006001 break;
6002 }
6003 case 'O':
6004 case 'o':
6005 {
6006 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006007 {
6008 long opac = OpaqueOpacity,
cristy3ed852e2009-09-05 21:47:34 +00006009 len = (long) strlen( value );
6010
cristy2c8b6312009-09-16 02:37:23 +00006011 if (value[len-1] == '%') {
6012 char tmp[100];
6013 (void) CopyMagickString(tmp,value,len);
6014 opac = atol( tmp );
6015 opac = (int)(QuantumRange * ((float)opac/100));
6016 } else
6017 opac = atol( value );
6018 (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6019 break;
cristy3ed852e2009-09-05 21:47:34 +00006020 }
cristy2c8b6312009-09-16 02:37:23 +00006021 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006022 break;
6023 }
6024 case 'P':
6025 case 'p':
6026 {
6027 if (LocaleCompare(keyword, "page") == 0)
6028 {
6029 char
6030 page[MaxTextExtent];
6031
6032 const char
6033 *image_option;
6034
6035 MagickStatusType
6036 flags;
6037
6038 RectangleInfo
6039 geometry;
6040
6041 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6042 image_option=GetImageOption(msl_info->image_info[n],"page");
6043 if (image_option != (const char *) NULL)
6044 flags=ParseAbsoluteGeometry(image_option,&geometry);
6045 flags=ParseAbsoluteGeometry(value,&geometry);
6046 (void) FormatMagickString(page,MaxTextExtent,"%lux%lu",
6047 geometry.width,geometry.height);
6048 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
6049 (void) FormatMagickString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
6050 geometry.width,geometry.height,geometry.x,geometry.y);
6051 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6052 msl_info->image_info[n]->page=GetPageGeometry(page);
6053 break;
6054 }
cristy2c8b6312009-09-16 02:37:23 +00006055 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006056 break;
6057 }
6058 default:
6059 {
cristy2c8b6312009-09-16 02:37:23 +00006060 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006061 break;
6062 }
6063 }
6064 }
6065 break;
6066 }
cristyb988fe72009-09-16 01:01:10 +00006067 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006068 {
6069 Image
6070 *shade_image;
6071
6072 MagickBooleanType
6073 gray;
6074
6075 /*
6076 Shade image.
6077 */
6078 if (msl_info->image[n] == (Image *) NULL)
6079 {
cristyb988fe72009-09-16 01:01:10 +00006080 ThrowMSLException(OptionError,"NoImagesDefined",
6081 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006082 break;
6083 }
6084 gray=MagickFalse;
6085 if (attributes != (const xmlChar **) NULL)
6086 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6087 {
6088 keyword=(const char *) attributes[i++];
6089 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006090 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006091 CloneString(&value,attribute);
6092 switch (*keyword)
6093 {
6094 case 'A':
6095 case 'a':
6096 {
6097 if (LocaleCompare(keyword,"azimuth") == 0)
6098 {
6099 geometry_info.rho=atof(value);
6100 break;
6101 }
6102 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6103 keyword);
6104 break;
6105 }
6106 case 'E':
6107 case 'e':
6108 {
6109 if (LocaleCompare(keyword,"elevation") == 0)
6110 {
6111 geometry_info.sigma=atof(value);
6112 break;
6113 }
6114 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6115 keyword);
6116 break;
6117 }
6118 case 'G':
6119 case 'g':
6120 {
6121 if (LocaleCompare(keyword,"geometry") == 0)
6122 {
6123 flags=ParseGeometry(value,&geometry_info);
6124 if ((flags & SigmaValue) == 0)
6125 geometry_info.sigma=1.0;
6126 break;
6127 }
6128 if (LocaleCompare(keyword,"gray") == 0)
6129 {
6130 option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
6131 value);
6132 if (option < 0)
6133 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6134 value);
6135 gray=(MagickBooleanType) option;
6136 break;
6137 }
6138 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6139 keyword);
6140 break;
6141 }
6142 default:
6143 {
6144 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6145 keyword);
6146 break;
6147 }
6148 }
6149 }
6150 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6151 geometry_info.sigma,&msl_info->image[n]->exception);
6152 if (shade_image == (Image *) NULL)
6153 break;
6154 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6155 msl_info->image[n]=shade_image;
6156 break;
6157 }
cristyb988fe72009-09-16 01:01:10 +00006158 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006159 {
6160 Image
6161 *shadow_image;
6162
6163 /*
6164 Shear image.
6165 */
6166 if (msl_info->image[n] == (Image *) NULL)
6167 {
cristyb988fe72009-09-16 01:01:10 +00006168 ThrowMSLException(OptionError,"NoImagesDefined",
6169 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006170 break;
6171 }
6172 if (attributes != (const xmlChar **) NULL)
6173 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6174 {
6175 keyword=(const char *) attributes[i++];
6176 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006177 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006178 CloneString(&value,attribute);
6179 switch (*keyword)
6180 {
6181 case 'G':
6182 case 'g':
6183 {
6184 if (LocaleCompare(keyword,"geometry") == 0)
6185 {
6186 flags=ParseGeometry(value,&geometry_info);
6187 if ((flags & SigmaValue) == 0)
6188 geometry_info.sigma=1.0;
6189 break;
6190 }
6191 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6192 keyword);
6193 break;
6194 }
6195 case 'O':
6196 case 'o':
6197 {
6198 if (LocaleCompare(keyword,"opacity") == 0)
6199 {
6200 geometry_info.rho=atol(value);
6201 break;
6202 }
6203 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6204 keyword);
6205 break;
6206 }
6207 case 'S':
6208 case 's':
6209 {
6210 if (LocaleCompare(keyword,"sigma") == 0)
6211 {
6212 geometry_info.sigma=atol(value);
6213 break;
6214 }
6215 break;
6216 }
6217 case 'X':
6218 case 'x':
6219 {
6220 if (LocaleCompare(keyword,"x") == 0)
6221 {
6222 geometry_info.xi=atof(value);
6223 break;
6224 }
6225 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6226 keyword);
6227 break;
6228 }
6229 case 'Y':
6230 case 'y':
6231 {
6232 if (LocaleCompare(keyword,"y") == 0)
6233 {
6234 geometry_info.psi=atol(value);
6235 break;
6236 }
6237 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6238 keyword);
6239 break;
6240 }
6241 default:
6242 {
6243 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6244 keyword);
6245 break;
6246 }
6247 }
6248 }
6249 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
6250 geometry_info.sigma,(long) (geometry_info.xi+0.5),(long)
6251 (geometry_info.psi+0.5),&msl_info->image[n]->exception);
6252 if (shadow_image == (Image *) NULL)
6253 break;
6254 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6255 msl_info->image[n]=shadow_image;
6256 break;
6257 }
cristyb988fe72009-09-16 01:01:10 +00006258 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006259 {
6260 double radius = 0.0,
6261 sigma = 1.0;
6262
6263 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006264 {
6265 ThrowMSLException(OptionError,"NoImagesDefined",
6266 (const char *) tag);
6267 break;
6268 }
cristy3ed852e2009-09-05 21:47:34 +00006269 /*
6270 NOTE: sharpen can have no attributes, since we use all the defaults!
6271 */
6272 if (attributes != (const xmlChar **) NULL)
6273 {
6274 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6275 {
6276 keyword=(const char *) attributes[i++];
6277 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006278 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006279 switch (*keyword)
6280 {
6281 case 'R':
6282 case 'r':
6283 {
6284 if (LocaleCompare(keyword, "radius") == 0)
6285 {
6286 radius = atof( value );
6287 break;
6288 }
6289 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6290 break;
6291 }
6292 case 'S':
6293 case 's':
6294 {
6295 if (LocaleCompare(keyword,"sigma") == 0)
6296 {
6297 sigma = atol( value );
6298 break;
6299 }
6300 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6301 break;
6302 }
6303 default:
6304 {
6305 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6306 break;
6307 }
6308 }
6309 }
6310 }
6311
6312 /*
6313 sharpen image.
6314 */
6315 {
6316 Image
6317 *newImage;
6318
6319 newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6320 if (newImage == (Image *) NULL)
6321 break;
6322 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6323 msl_info->image[n]=newImage;
6324 break;
6325 }
6326 }
cristyb988fe72009-09-16 01:01:10 +00006327 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006328 {
6329 /* init the values */
6330 width = height = 0;
6331 x = y = 0;
6332
6333 if (msl_info->image[n] == (Image *) NULL)
6334 {
cristyb988fe72009-09-16 01:01:10 +00006335 ThrowMSLException(OptionError,"NoImagesDefined",
6336 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006337 break;
6338 }
6339 if (attributes == (const xmlChar **) NULL)
6340 break;
6341 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6342 {
6343 keyword=(const char *) attributes[i++];
6344 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006345 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006346 switch (*keyword)
6347 {
6348 case 'G':
6349 case 'g':
6350 {
6351 if (LocaleCompare(keyword,"geometry") == 0)
6352 {
6353 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6354 break;
6355 }
6356 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6357 break;
6358 }
6359 case 'H':
6360 case 'h':
6361 {
6362 if (LocaleCompare(keyword,"height") == 0)
6363 {
6364 height = atol( value );
6365 break;
6366 }
6367 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6368 break;
6369 }
6370 case 'W':
6371 case 'w':
6372 {
6373 if (LocaleCompare(keyword,"width") == 0)
6374 {
6375 width = atol( value );
6376 break;
6377 }
6378 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6379 break;
6380 }
6381 default:
6382 {
6383 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6384 break;
6385 }
6386 }
6387 }
6388
6389 /*
6390 process image.
6391 */
6392 {
6393 Image
6394 *newImage;
6395 RectangleInfo
6396 rectInfo;
6397
6398 rectInfo.height = height;
6399 rectInfo.width = width;
6400 rectInfo.x = x;
6401 rectInfo.y = y;
6402
6403
6404 newImage=ShaveImage(msl_info->image[n], &rectInfo,
6405 &msl_info->image[n]->exception);
6406 if (newImage == (Image *) NULL)
6407 break;
6408 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6409 msl_info->image[n]=newImage;
6410 }
6411
6412 break;
6413 }
cristyb988fe72009-09-16 01:01:10 +00006414 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006415 {
6416 Image
6417 *shear_image;
6418
6419 /*
6420 Shear image.
6421 */
6422 if (msl_info->image[n] == (Image *) NULL)
6423 {
cristyb988fe72009-09-16 01:01:10 +00006424 ThrowMSLException(OptionError,"NoImagesDefined",
6425 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006426 break;
6427 }
6428 if (attributes != (const xmlChar **) NULL)
6429 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6430 {
6431 keyword=(const char *) attributes[i++];
6432 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006433 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006434 CloneString(&value,attribute);
6435 switch (*keyword)
6436 {
6437 case 'F':
6438 case 'f':
6439 {
6440 if (LocaleCompare(keyword, "fill") == 0)
6441 {
6442 (void) QueryColorDatabase(value,
6443 &msl_info->image[n]->background_color,&exception);
6444 break;
6445 }
6446 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6447 keyword);
6448 break;
6449 }
6450 case 'G':
6451 case 'g':
6452 {
6453 if (LocaleCompare(keyword,"geometry") == 0)
6454 {
6455 flags=ParseGeometry(value,&geometry_info);
6456 if ((flags & SigmaValue) == 0)
6457 geometry_info.sigma=1.0;
6458 break;
6459 }
6460 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6461 keyword);
6462 break;
6463 }
6464 case 'X':
6465 case 'x':
6466 {
6467 if (LocaleCompare(keyword,"x") == 0)
6468 {
6469 geometry_info.rho=atof(value);
6470 break;
6471 }
6472 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6473 keyword);
6474 break;
6475 }
6476 case 'Y':
6477 case 'y':
6478 {
6479 if (LocaleCompare(keyword,"y") == 0)
6480 {
6481 geometry_info.sigma=atol(value);
6482 break;
6483 }
6484 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6485 keyword);
6486 break;
6487 }
6488 default:
6489 {
6490 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6491 keyword);
6492 break;
6493 }
6494 }
6495 }
6496 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6497 geometry_info.sigma,&msl_info->image[n]->exception);
6498 if (shear_image == (Image *) NULL)
6499 break;
6500 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6501 msl_info->image[n]=shear_image;
6502 break;
6503 }
cristyb988fe72009-09-16 01:01:10 +00006504 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006505 {
6506 /*
6507 Signature image.
6508 */
6509 if (msl_info->image[n] == (Image *) NULL)
6510 {
cristyb988fe72009-09-16 01:01:10 +00006511 ThrowMSLException(OptionError,"NoImagesDefined",
6512 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006513 break;
6514 }
6515 if (attributes != (const xmlChar **) NULL)
6516 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6517 {
6518 keyword=(const char *) attributes[i++];
6519 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006520 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006521 CloneString(&value,attribute);
6522 switch (*keyword)
6523 {
6524 default:
6525 {
6526 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6527 keyword);
6528 break;
6529 }
6530 }
6531 }
6532 (void) SignatureImage(msl_info->image[n]);
6533 break;
6534 }
cristyb988fe72009-09-16 01:01:10 +00006535 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006536 {
6537 /*
6538 Solarize image.
6539 */
6540 if (msl_info->image[n] == (Image *) NULL)
6541 {
cristyb988fe72009-09-16 01:01:10 +00006542 ThrowMSLException(OptionError,"NoImagesDefined",
6543 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006544 break;
6545 }
6546 geometry_info.rho=QuantumRange/2.0;
6547 if (attributes != (const xmlChar **) NULL)
6548 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6549 {
6550 keyword=(const char *) attributes[i++];
6551 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006552 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006553 CloneString(&value,attribute);
6554 switch (*keyword)
6555 {
6556 case 'G':
6557 case 'g':
6558 {
6559 if (LocaleCompare(keyword,"geometry") == 0)
6560 {
6561 flags=ParseGeometry(value,&geometry_info);
6562 break;
6563 }
6564 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6565 keyword);
6566 break;
6567 }
6568 case 'T':
6569 case 't':
6570 {
6571 if (LocaleCompare(keyword,"threshold") == 0)
6572 {
6573 geometry_info.rho=atof(value);
6574 break;
6575 }
6576 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6577 keyword);
6578 break;
6579 }
6580 default:
6581 {
6582 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6583 keyword);
6584 break;
6585 }
6586 }
6587 }
6588 (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6589 break;
6590 }
cristyb988fe72009-09-16 01:01:10 +00006591 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006592 {
6593 Image
6594 *spread_image;
6595
6596 /*
6597 Spread image.
6598 */
6599 if (msl_info->image[n] == (Image *) NULL)
6600 {
cristyb988fe72009-09-16 01:01:10 +00006601 ThrowMSLException(OptionError,"NoImagesDefined",
6602 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006603 break;
6604 }
6605 if (attributes != (const xmlChar **) NULL)
6606 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6607 {
6608 keyword=(const char *) attributes[i++];
6609 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006610 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006611 CloneString(&value,attribute);
6612 switch (*keyword)
6613 {
6614 case 'G':
6615 case 'g':
6616 {
6617 if (LocaleCompare(keyword,"geometry") == 0)
6618 {
6619 flags=ParseGeometry(value,&geometry_info);
6620 if ((flags & SigmaValue) == 0)
6621 geometry_info.sigma=1.0;
6622 break;
6623 }
6624 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6625 keyword);
6626 break;
6627 }
6628 case 'R':
6629 case 'r':
6630 {
6631 if (LocaleCompare(keyword,"radius") == 0)
6632 {
6633 geometry_info.rho=atof(value);
6634 break;
6635 }
6636 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6637 keyword);
6638 break;
6639 }
6640 default:
6641 {
6642 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6643 keyword);
6644 break;
6645 }
6646 }
6647 }
6648 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6649 &msl_info->image[n]->exception);
6650 if (spread_image == (Image *) NULL)
6651 break;
6652 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6653 msl_info->image[n]=spread_image;
6654 break;
6655 }
cristyb988fe72009-09-16 01:01:10 +00006656 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006657 {
6658 Image *
6659 watermark = (Image*)NULL;
6660
6661 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006662 {
6663 ThrowMSLException(OptionError,"NoImagesDefined",
6664 (const char *) tag);
6665 break;
6666 }
cristy3ed852e2009-09-05 21:47:34 +00006667 if (attributes == (const xmlChar **) NULL)
6668 break;
6669 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6670 {
6671 keyword=(const char *) attributes[i++];
6672 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006673 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006674 switch (*keyword)
6675 {
6676 case 'I':
6677 case 'i':
6678 {
6679 if (LocaleCompare(keyword,"image") == 0)
6680 {
6681 for (j=0; j<msl_info->n;j++)
6682 {
6683 const char *
6684 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6685 if (theAttr && LocaleCompare(theAttr, value) == 0)
6686 {
6687 watermark = msl_info->image[j];
6688 break;
6689 }
6690 }
6691 break;
6692 }
6693 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6694 break;
6695 }
6696 default:
6697 {
6698 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6699 break;
6700 }
6701 }
6702 }
6703
6704 /*
6705 process image.
6706 */
6707 if ( watermark != (Image*) NULL )
6708 {
6709 Image
6710 *newImage;
6711
6712 newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6713 if (newImage == (Image *) NULL)
6714 break;
6715 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6716 msl_info->image[n]=newImage;
6717 break;
6718 } else
6719 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6720 }
cristyb988fe72009-09-16 01:01:10 +00006721 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006722 {
6723 Image *
6724 stereoImage = (Image*)NULL;
6725
6726 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006727 {
6728 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6729 break;
6730 }
cristy3ed852e2009-09-05 21:47:34 +00006731 if (attributes == (const xmlChar **) NULL)
6732 break;
6733 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6734 {
6735 keyword=(const char *) attributes[i++];
6736 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006737 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006738 switch (*keyword)
6739 {
6740 case 'I':
6741 case 'i':
6742 {
6743 if (LocaleCompare(keyword,"image") == 0)
6744 {
6745 for (j=0; j<msl_info->n;j++)
6746 {
6747 const char *
6748 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6749 if (theAttr && LocaleCompare(theAttr, value) == 0)
6750 {
6751 stereoImage = msl_info->image[j];
6752 break;
6753 }
6754 }
6755 break;
6756 }
6757 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6758 break;
6759 }
6760 default:
6761 {
6762 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6763 break;
6764 }
6765 }
6766 }
6767
6768 /*
6769 process image.
6770 */
6771 if ( stereoImage != (Image*) NULL )
6772 {
6773 Image
6774 *newImage;
6775
6776 newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6777 if (newImage == (Image *) NULL)
6778 break;
6779 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6780 msl_info->image[n]=newImage;
6781 break;
6782 } else
6783 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6784 }
cristyb988fe72009-09-16 01:01:10 +00006785 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006786 {
6787 Image
6788 *p,
6789 *q,
6790 *swap;
6791
6792 long
6793 index,
6794 swap_index;
6795
6796 if (msl_info->image[n] == (Image *) NULL)
6797 {
cristyb988fe72009-09-16 01:01:10 +00006798 ThrowMSLException(OptionError,"NoImagesDefined",
6799 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006800 break;
6801 }
6802 index=(-1);
6803 swap_index=(-2);
6804 if (attributes != (const xmlChar **) NULL)
6805 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6806 {
6807 keyword=(const char *) attributes[i++];
6808 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006809 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006810 CloneString(&value,attribute);
6811 switch (*keyword)
6812 {
6813 case 'G':
6814 case 'g':
6815 {
6816 if (LocaleCompare(keyword,"indexes") == 0)
6817 {
6818 flags=ParseGeometry(value,&geometry_info);
6819 index=(long) geometry_info.rho;
6820 if ((flags & SigmaValue) == 0)
6821 swap_index=(long) geometry_info.sigma;
6822 break;
6823 }
6824 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6825 keyword);
6826 break;
6827 }
6828 default:
6829 {
6830 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6831 keyword);
6832 break;
6833 }
6834 }
6835 }
6836 /*
6837 Swap images.
6838 */
6839 p=GetImageFromList(msl_info->image[n],index);
6840 q=GetImageFromList(msl_info->image[n],swap_index);
6841 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6842 {
cristyb988fe72009-09-16 01:01:10 +00006843 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006844 break;
6845 }
6846 swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6847 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6848 ReplaceImageInList(&q,swap);
6849 msl_info->image[n]=GetFirstImageInList(q);
6850 break;
6851 }
cristyb988fe72009-09-16 01:01:10 +00006852 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006853 {
6854 Image
6855 *swirl_image;
6856
6857 /*
6858 Swirl image.
6859 */
6860 if (msl_info->image[n] == (Image *) NULL)
6861 {
cristyb988fe72009-09-16 01:01:10 +00006862 ThrowMSLException(OptionError,"NoImagesDefined",
6863 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006864 break;
6865 }
6866 if (attributes != (const xmlChar **) NULL)
6867 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6868 {
6869 keyword=(const char *) attributes[i++];
6870 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006871 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006872 CloneString(&value,attribute);
6873 switch (*keyword)
6874 {
6875 case 'D':
6876 case 'd':
6877 {
6878 if (LocaleCompare(keyword,"degrees") == 0)
6879 {
6880 geometry_info.rho=atof(value);
6881 break;
6882 }
6883 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6884 keyword);
6885 break;
6886 }
6887 case 'G':
6888 case 'g':
6889 {
6890 if (LocaleCompare(keyword,"geometry") == 0)
6891 {
6892 flags=ParseGeometry(value,&geometry_info);
6893 if ((flags & SigmaValue) == 0)
6894 geometry_info.sigma=1.0;
6895 break;
6896 }
6897 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6898 keyword);
6899 break;
6900 }
6901 default:
6902 {
6903 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6904 keyword);
6905 break;
6906 }
6907 }
6908 }
6909 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6910 &msl_info->image[n]->exception);
6911 if (swirl_image == (Image *) NULL)
6912 break;
6913 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6914 msl_info->image[n]=swirl_image;
6915 break;
6916 }
cristyb988fe72009-09-16 01:01:10 +00006917 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006918 {
6919 /*
6920 Sync image.
6921 */
6922 if (msl_info->image[n] == (Image *) NULL)
6923 {
cristyb988fe72009-09-16 01:01:10 +00006924 ThrowMSLException(OptionError,"NoImagesDefined",
6925 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006926 break;
6927 }
6928 if (attributes != (const xmlChar **) NULL)
6929 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6930 {
6931 keyword=(const char *) attributes[i++];
6932 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006933 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006934 CloneString(&value,attribute);
6935 switch (*keyword)
6936 {
6937 default:
6938 {
6939 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6940 keyword);
6941 break;
6942 }
6943 }
6944 }
6945 (void) SyncImage(msl_info->image[n]);
6946 break;
6947 }
6948 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6949 }
6950 case 'T':
6951 case 't':
6952 {
cristyb988fe72009-09-16 01:01:10 +00006953 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006954 {
6955 Image
6956 *texture_image;
6957
6958 /*
6959 Texture image.
6960 */
6961 if (msl_info->image[n] == (Image *) NULL)
6962 {
cristyb988fe72009-09-16 01:01:10 +00006963 ThrowMSLException(OptionError,"NoImagesDefined",
6964 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006965 break;
6966 }
6967 texture_image=NewImageList();
6968 if (attributes != (const xmlChar **) NULL)
6969 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6970 {
6971 keyword=(const char *) attributes[i++];
6972 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006973 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006974 CloneString(&value,attribute);
6975 switch (*keyword)
6976 {
6977 case 'I':
6978 case 'i':
6979 {
6980 if (LocaleCompare(keyword,"image") == 0)
6981 for (j=0; j < msl_info->n; j++)
6982 {
6983 const char
6984 *attribute;
cristyb988fe72009-09-16 01:01:10 +00006985
cristy3ed852e2009-09-05 21:47:34 +00006986 attribute=GetImageProperty(msl_info->attributes[j],"id");
6987 if ((attribute != (const char *) NULL) &&
6988 (LocaleCompare(attribute,value) == 0))
6989 {
6990 texture_image=CloneImage(msl_info->image[j],0,0,
6991 MagickFalse,&exception);
6992 break;
6993 }
6994 }
6995 break;
6996 }
6997 default:
6998 {
6999 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7000 keyword);
7001 break;
7002 }
7003 }
7004 }
7005 (void) TextureImage(msl_info->image[n],texture_image);
7006 texture_image=DestroyImage(texture_image);
7007 break;
7008 }
cristyb988fe72009-09-16 01:01:10 +00007009 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007010 {
7011 /* init the values */
7012 double threshold = 0;
7013
7014 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007015 {
7016 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7017 break;
7018 }
cristy3ed852e2009-09-05 21:47:34 +00007019 if (attributes == (const xmlChar **) NULL)
7020 break;
7021 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7022 {
7023 keyword=(const char *) attributes[i++];
7024 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007025 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007026 switch (*keyword)
7027 {
7028 case 'T':
7029 case 't':
7030 {
7031 if (LocaleCompare(keyword,"threshold") == 0)
7032 {
7033 threshold = atof( value );
7034 break;
7035 }
7036 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7037 break;
7038 }
7039 default:
7040 {
7041 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7042 break;
7043 }
7044 }
7045 }
7046
7047 /*
7048 process image.
7049 */
7050 {
7051 BilevelImageChannel(msl_info->image[n],
7052 (ChannelType) ((long) (AllChannels &~ (long) OpacityChannel)),
7053 threshold);
7054 break;
7055 }
7056 }
cristyb988fe72009-09-16 01:01:10 +00007057 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007058 {
7059 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007060 {
7061 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7062 break;
7063 }
cristy3ed852e2009-09-05 21:47:34 +00007064 if (attributes == (const xmlChar **) NULL)
7065 break;
7066 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7067 {
7068 keyword=(const char *) attributes[i++];
7069 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007070 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007071 switch (*keyword)
7072 {
7073 case 'C':
7074 case 'c':
7075 {
7076 if (LocaleCompare(keyword,"color") == 0)
7077 {
7078 MagickPixelPacket
7079 target;
7080
7081 (void) QueryMagickColor(value,&target,&exception);
7082 (void) TransparentPaintImage(msl_info->image[n],&target,
7083 TransparentOpacity,MagickFalse);
7084 break;
7085 }
7086 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7087 break;
7088 }
7089 default:
7090 {
7091 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7092 break;
7093 }
7094 }
7095 }
7096 break;
7097 }
cristyb988fe72009-09-16 01:01:10 +00007098 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007099 {
7100 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007101 {
7102 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7103 break;
7104 }
cristy3ed852e2009-09-05 21:47:34 +00007105
7106 /* no attributes here */
7107
7108 /* process the image */
7109 {
7110 Image
7111 *newImage;
7112 RectangleInfo
7113 rectInfo;
7114
7115 /* all zeros on a crop == trim edges! */
7116 rectInfo.height = rectInfo.width = 0;
7117 rectInfo.x = rectInfo.y = 0;
7118
7119 newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7120 if (newImage == (Image *) NULL)
7121 break;
7122 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7123 msl_info->image[n]=newImage;
7124 break;
7125 }
7126 }
7127 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7128 }
7129 case 'W':
7130 case 'w':
7131 {
cristyb988fe72009-09-16 01:01:10 +00007132 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007133 {
7134 if (msl_info->image[n] == (Image *) NULL)
7135 {
cristyb988fe72009-09-16 01:01:10 +00007136 ThrowMSLException(OptionError,"NoImagesDefined",
7137 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007138 break;
7139 }
7140 if (attributes == (const xmlChar **) NULL)
7141 break;
7142 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7143 {
7144 keyword=(const char *) attributes[i++];
7145 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007146 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007147 switch (*keyword)
7148 {
7149 case 'F':
7150 case 'f':
7151 {
7152 if (LocaleCompare(keyword,"filename") == 0)
7153 {
7154 (void) CopyMagickString(msl_info->image[n]->filename,value,
7155 MaxTextExtent);
7156 break;
7157 }
cristy4582cbb2009-09-23 00:35:43 +00007158 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007159 }
7160 default:
7161 {
cristy4582cbb2009-09-23 00:35:43 +00007162 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007163 break;
7164 }
7165 }
7166 }
7167
7168 /* process */
7169 {
7170 (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7171 break;
7172 }
7173 }
7174 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7175 }
7176 default:
7177 {
7178 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7179 break;
7180 }
7181 }
7182 if ( value != NULL )
7183 value=DestroyString(value);
7184 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7185}
7186
7187static void MSLEndElement(void *context,const xmlChar *tag)
7188{
7189 long
7190 n;
7191
7192 MSLInfo
7193 *msl_info;
7194
7195 /*
7196 Called when the end of an element has been detected.
7197 */
7198 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7199 tag);
7200 msl_info=(MSLInfo *) context;
7201 n=msl_info->n;
7202 switch (*tag)
7203 {
7204 case 'C':
7205 case 'c':
7206 {
cristyb988fe72009-09-16 01:01:10 +00007207 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007208 {
7209 (void) DeleteImageProperty(msl_info->image[n],"comment");
7210 if (msl_info->content == (char *) NULL)
7211 break;
7212 StripString(msl_info->content);
7213 (void) SetImageProperty(msl_info->image[n],"comment",
7214 msl_info->content);
7215 break;
7216 }
7217 break;
7218 }
7219 case 'G':
7220 case 'g':
7221 {
cristyb988fe72009-09-16 01:01:10 +00007222 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007223 {
7224 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7225 {
7226 long i = (long)
7227 (msl_info->group_info[msl_info->number_groups-1].numImages);
7228 while ( i-- )
7229 {
7230 if (msl_info->image[msl_info->n] != (Image *) NULL)
7231 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7232 msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7233 msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7234 msl_info->n--;
7235 }
7236 }
7237 msl_info->number_groups--;
7238 }
7239 break;
7240 }
7241 case 'I':
7242 case 'i':
7243 {
cristyb988fe72009-09-16 01:01:10 +00007244 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007245 MSLPopImage(msl_info);
7246 break;
7247 }
7248 case 'L':
7249 case 'l':
7250 {
cristyb988fe72009-09-16 01:01:10 +00007251 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007252 {
7253 (void) DeleteImageProperty(msl_info->image[n],"label");
7254 if (msl_info->content == (char *) NULL)
7255 break;
7256 StripString(msl_info->content);
7257 (void) SetImageProperty(msl_info->image[n],"label",
7258 msl_info->content);
7259 break;
7260 }
7261 break;
7262 }
7263 case 'M':
7264 case 'm':
7265 {
cristyb988fe72009-09-16 01:01:10 +00007266 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007267 {
7268 /*
7269 This our base element.
7270 at the moment we don't do anything special
7271 but someday we might!
7272 */
7273 }
7274 break;
7275 }
7276 default:
7277 break;
7278 }
7279 if (msl_info->content != (char *) NULL)
7280 msl_info->content=DestroyString(msl_info->content);
7281}
7282
7283static void MSLCharacters(void *context,const xmlChar *c,int length)
7284{
7285 MSLInfo
7286 *msl_info;
7287
7288 register char
7289 *p;
7290
7291 register long
7292 i;
7293
7294 /*
7295 Receiving some characters from the parser.
7296 */
7297 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7298 " SAX.characters(%s,%d)",c,length);
7299 msl_info=(MSLInfo *) context;
7300 if (msl_info->content != (char *) NULL)
7301 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7302 strlen(msl_info->content)+length+MaxTextExtent,
7303 sizeof(*msl_info->content));
7304 else
7305 {
7306 msl_info->content=(char *) NULL;
7307 if (~length >= MaxTextExtent)
7308 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7309 sizeof(*msl_info->content));
7310 if (msl_info->content != (char *) NULL)
7311 *msl_info->content='\0';
7312 }
7313 if (msl_info->content == (char *) NULL)
7314 return;
7315 p=msl_info->content+strlen(msl_info->content);
7316 for (i=0; i < length; i++)
7317 *p++=c[i];
7318 *p='\0';
7319}
7320
7321static void MSLReference(void *context,const xmlChar *name)
7322{
7323 MSLInfo
7324 *msl_info;
7325
7326 xmlParserCtxtPtr
7327 parser;
7328
7329 /*
7330 Called when an entity reference is detected.
7331 */
7332 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7333 " SAX.reference(%s)",name);
7334 msl_info=(MSLInfo *) context;
7335 parser=msl_info->parser;
7336 if (*name == '#')
7337 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7338 else
7339 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7340}
7341
7342static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7343{
7344 MSLInfo
7345 *msl_info;
7346
7347 /*
7348 Receiving some ignorable whitespaces from the parser.
7349 */
7350 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7351 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7352 msl_info=(MSLInfo *) context;
7353}
7354
7355static void MSLProcessingInstructions(void *context,const xmlChar *target,
7356 const xmlChar *data)
7357{
7358 MSLInfo
7359 *msl_info;
7360
7361 /*
7362 A processing instruction has been parsed.
7363 */
7364 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7365 " SAX.processingInstruction(%s, %s)",
7366 target,data);
7367 msl_info=(MSLInfo *) context;
7368}
7369
7370static void MSLComment(void *context,const xmlChar *value)
7371{
7372 MSLInfo
7373 *msl_info;
7374
7375 /*
7376 A comment has been parsed.
7377 */
7378 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7379 " SAX.comment(%s)",value);
7380 msl_info=(MSLInfo *) context;
7381}
7382
7383static void MSLWarning(void *context,const char *format,...)
7384{
7385 char
7386 *message,
7387 reason[MaxTextExtent];
7388
7389 MSLInfo
7390 *msl_info;
7391
7392 va_list
7393 operands;
7394
7395 /**
7396 Display and format a warning messages, gives file, line, position and
7397 extra parameters.
7398 */
7399 va_start(operands,format);
7400 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7401 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7402 msl_info=(MSLInfo *) context;
7403#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7404 (void) vsprintf(reason,format,operands);
7405#else
7406 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7407#endif
7408 message=GetExceptionMessage(errno);
7409 ThrowMSLException(CoderError,reason,message);
7410 message=DestroyString(message);
7411 va_end(operands);
7412}
7413
7414static void MSLError(void *context,const char *format,...)
7415{
7416 char
7417 reason[MaxTextExtent];
7418
7419 MSLInfo
7420 *msl_info;
7421
7422 va_list
7423 operands;
7424
7425 /*
7426 Display and format a error formats, gives file, line, position and
7427 extra parameters.
7428 */
7429 va_start(operands,format);
7430 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7431 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7432 msl_info=(MSLInfo *) context;
7433#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7434 (void) vsprintf(reason,format,operands);
7435#else
7436 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7437#endif
7438 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7439 va_end(operands);
7440}
7441
7442static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7443{
7444 MSLInfo
7445 *msl_info;
7446
7447 xmlNodePtr
7448 child;
7449
7450 xmlParserCtxtPtr
7451 parser;
7452
7453 /*
7454 Called when a pcdata block has been parsed.
7455 */
7456 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7457 " SAX.pcdata(%s, %d)",value,length);
7458 msl_info=(MSLInfo *) context;
7459 parser=msl_info->parser;
7460 child=xmlGetLastChild(parser->node);
7461 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7462 {
7463 xmlTextConcat(child,value,length);
7464 return;
7465 }
7466 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7467}
7468
7469static void MSLExternalSubset(void *context,const xmlChar *name,
7470 const xmlChar *external_id,const xmlChar *system_id)
7471{
7472 MSLInfo
7473 *msl_info;
7474
7475 xmlParserCtxt
7476 parser_context;
7477
7478 xmlParserCtxtPtr
7479 parser;
7480
7481 xmlParserInputPtr
7482 input;
7483
7484 /*
7485 Does this document has an external subset?
7486 */
7487 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7488 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007489 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7490 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007491 msl_info=(MSLInfo *) context;
7492 parser=msl_info->parser;
7493 if (((external_id == NULL) && (system_id == NULL)) ||
7494 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7495 (msl_info->document == 0)))
7496 return;
7497 input=MSLResolveEntity(context,external_id,system_id);
7498 if (input == NULL)
7499 return;
7500 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7501 parser_context=(*parser);
7502 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7503 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7504 {
7505 parser->errNo=XML_ERR_NO_MEMORY;
7506 parser->input=parser_context.input;
7507 parser->inputNr=parser_context.inputNr;
7508 parser->inputMax=parser_context.inputMax;
7509 parser->inputTab=parser_context.inputTab;
7510 return;
7511 }
7512 parser->inputNr=0;
7513 parser->inputMax=5;
7514 parser->input=NULL;
7515 xmlPushInput(parser,input);
7516 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7517 if (input->filename == (char *) NULL)
7518 input->filename=(char *) xmlStrdup(system_id);
7519 input->line=1;
7520 input->col=1;
7521 input->base=parser->input->cur;
7522 input->cur=parser->input->cur;
7523 input->free=NULL;
7524 xmlParseExternalSubset(parser,external_id,system_id);
7525 while (parser->inputNr > 1)
7526 (void) xmlPopInput(parser);
7527 xmlFreeInputStream(parser->input);
7528 xmlFree(parser->inputTab);
7529 parser->input=parser_context.input;
7530 parser->inputNr=parser_context.inputNr;
7531 parser->inputMax=parser_context.inputMax;
7532 parser->inputTab=parser_context.inputTab;
7533}
7534
7535#if defined(__cplusplus) || defined(c_plusplus)
7536}
7537#endif
7538
7539static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7540 ExceptionInfo *exception)
7541{
cristy3ed852e2009-09-05 21:47:34 +00007542 char
7543 message[MaxTextExtent];
7544
7545 Image
7546 *msl_image;
7547
7548 int
7549 status;
7550
7551 long
7552 n;
7553
7554 MSLInfo
7555 msl_info;
7556
cristy5f6f01c2009-11-19 19:36:42 +00007557 xmlSAXHandler
7558 sax_modules;
7559
cristy3ed852e2009-09-05 21:47:34 +00007560 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007561 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007562
7563 /*
7564 Open image file.
7565 */
7566 assert(image_info != (const ImageInfo *) NULL);
7567 assert(image_info->signature == MagickSignature);
7568 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007569 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7570 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007571 assert(image != (Image **) NULL);
7572 msl_image=AcquireImage(image_info);
7573 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7574 if (status == MagickFalse)
7575 {
7576 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7577 msl_image->filename);
7578 msl_image=DestroyImageList(msl_image);
7579 return(MagickFalse);
7580 }
7581 msl_image->columns=1;
7582 msl_image->rows=1;
7583 /*
7584 Parse MSL file.
7585 */
7586 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7587 msl_info.exception=exception;
7588 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7589 sizeof(*msl_info.image_info));
7590 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7591 sizeof(*msl_info.draw_info));
7592 /* top of the stack is the MSL file itself */
cristy90823212009-12-12 20:48:33 +00007593 msl_info.image=(Image **) AcquireAlignedMemory(1,sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007594 msl_info.attributes=(Image **) AcquireMagickMemory(
7595 sizeof(*msl_info.attributes));
7596 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7597 sizeof(*msl_info.group_info));
7598 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7599 (msl_info.image == (Image **) NULL) ||
7600 (msl_info.attributes == (Image **) NULL) ||
7601 (msl_info.group_info == (MSLGroupInfo *) NULL))
7602 ThrowFatalException(ResourceLimitFatalError,
7603 "UnableToInterpretMSLImage");
7604 *msl_info.image_info=CloneImageInfo(image_info);
7605 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7606 *msl_info.attributes=AcquireImage(image_info);
7607 msl_info.group_info[0].numImages=0;
7608 /* the first slot is used to point to the MSL file image */
7609 *msl_info.image=msl_image;
7610 if (*image != (Image *) NULL)
7611 MSLPushImage(&msl_info,*image);
7612 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007613 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7614 sax_modules.internalSubset=MSLInternalSubset;
7615 sax_modules.isStandalone=MSLIsStandalone;
7616 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7617 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7618 sax_modules.resolveEntity=MSLResolveEntity;
7619 sax_modules.getEntity=MSLGetEntity;
7620 sax_modules.entityDecl=MSLEntityDeclaration;
7621 sax_modules.notationDecl=MSLNotationDeclaration;
7622 sax_modules.attributeDecl=MSLAttributeDeclaration;
7623 sax_modules.elementDecl=MSLElementDeclaration;
7624 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7625 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7626 sax_modules.startDocument=MSLStartDocument;
7627 sax_modules.endDocument=MSLEndDocument;
7628 sax_modules.startElement=MSLStartElement;
7629 sax_modules.endElement=MSLEndElement;
7630 sax_modules.reference=MSLReference;
7631 sax_modules.characters=MSLCharacters;
7632 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7633 sax_modules.processingInstruction=MSLProcessingInstructions;
7634 sax_modules.comment=MSLComment;
7635 sax_modules.warning=MSLWarning;
7636 sax_modules.error=MSLError;
7637 sax_modules.fatalError=MSLError;
7638 sax_modules.getParameterEntity=MSLGetParameterEntity;
7639 sax_modules.cdataBlock=MSLCDataBlock;
7640 sax_modules.externalSubset=MSLExternalSubset;
7641 sax_handler=(&sax_modules);
7642 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007643 msl_image->filename);
7644 while (ReadBlobString(msl_image,message) != (char *) NULL)
7645 {
7646 n=(long) strlen(message);
7647 if (n == 0)
7648 continue;
7649 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7650 if (status != 0)
7651 break;
7652 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7653 if (msl_info.exception->severity >= ErrorException)
7654 break;
7655 }
7656 if (msl_info.exception->severity == UndefinedException)
7657 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7658 xmlFreeParserCtxt(msl_info.parser);
7659 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7660 xmlCleanupParser();
7661 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7662 msl_info.group_info);
7663 if (*image == (Image *) NULL)
7664 *image=(*msl_info.image);
cristy5f6f01c2009-11-19 19:36:42 +00007665 if ((*msl_info.image)->exception.severity != UndefinedException)
7666 return(MagickFalse);
7667 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007668}
7669
7670static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7671{
7672 Image
7673 *image;
7674
7675 /*
7676 Open image file.
7677 */
7678 assert(image_info != (const ImageInfo *) NULL);
7679 assert(image_info->signature == MagickSignature);
7680 if (image_info->debug != MagickFalse)
7681 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7682 image_info->filename);
7683 assert(exception != (ExceptionInfo *) NULL);
7684 assert(exception->signature == MagickSignature);
7685 image=(Image *) NULL;
7686 (void) ProcessMSLScript(image_info,&image,exception);
7687 return(GetFirstImageInList(image));
7688}
7689#endif
7690
7691/*
7692%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7693% %
7694% %
7695% %
7696% R e g i s t e r M S L I m a g e %
7697% %
7698% %
7699% %
7700%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7701%
7702% RegisterMSLImage() adds attributes for the MSL image format to
7703% the list of supported formats. The attributes include the image format
7704% tag, a method to read and/or write the format, whether the format
7705% supports the saving of more than one frame to the same file or blob,
7706% whether the format supports native in-memory I/O, and a brief
7707% description of the format.
7708%
7709% The format of the RegisterMSLImage method is:
7710%
7711% unsigned long RegisterMSLImage(void)
7712%
7713*/
7714ModuleExport unsigned long RegisterMSLImage(void)
7715{
7716 MagickInfo
7717 *entry;
7718
7719 entry=SetMagickInfo("MSL");
7720#if defined(MAGICKCORE_XML_DELEGATE)
7721 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7722 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7723#endif
7724 entry->description=ConstantString("Magick Scripting Language");
7725 entry->module=ConstantString("MSL");
7726 (void) RegisterMagickInfo(entry);
7727 return(MagickImageCoderSignature);
7728}
7729
7730/*
7731%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7732% %
7733% %
7734% %
cristyb988fe72009-09-16 01:01:10 +00007735% S e t M S L A t t r i b u t e s %
7736% %
7737% %
7738% %
7739%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7740%
7741% SetMSLAttributes() ...
7742%
7743% The format of the SetMSLAttributes method is:
7744%
7745% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007746% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007747%
7748% A description of each parameter follows:
7749%
7750% o msl_info: the MSL info.
7751%
cristyb20775d2009-09-16 01:51:41 +00007752% o keyword: the keyword.
7753%
7754% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007755%
7756*/
cristyb20775d2009-09-16 01:51:41 +00007757static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7758 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007759{
cristy4582cbb2009-09-23 00:35:43 +00007760 Image
7761 *attributes;
7762
cristyb20775d2009-09-16 01:51:41 +00007763 DrawInfo
7764 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007765
7766 ExceptionInfo
7767 *exception;
7768
cristy4582cbb2009-09-23 00:35:43 +00007769 GeometryInfo
7770 geometry_info;
7771
cristy4fa36e42009-09-18 14:24:06 +00007772 Image
7773 *image;
7774
cristyb20775d2009-09-16 01:51:41 +00007775 ImageInfo
7776 *image_info;
7777
cristy4582cbb2009-09-23 00:35:43 +00007778 int
7779 flags;
7780
cristyb988fe72009-09-16 01:01:10 +00007781 long
7782 n;
7783
cristyb988fe72009-09-16 01:01:10 +00007784 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007785 if (keyword == (const char *) NULL)
7786 return(MagickTrue);
7787 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007788 return(MagickTrue);
7789 exception=msl_info->exception;
7790 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007791 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007792 image_info=msl_info->image_info[n];
7793 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007794 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007795 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007796 {
cristyfb758a52009-09-16 14:36:08 +00007797 case 'A':
7798 case 'a':
7799 {
7800 if (LocaleCompare(keyword,"adjoin") == 0)
7801 {
7802 long
7803 adjoin;
7804
7805 adjoin=ParseMagickOption(MagickBooleanOptions,MagickFalse,value);
7806 if (adjoin < 0)
7807 ThrowMSLException(OptionError,"UnrecognizedType",value);
7808 image_info->adjoin=(MagickBooleanType) adjoin;
7809 break;
7810 }
cristy4fa36e42009-09-18 14:24:06 +00007811 if (LocaleCompare(keyword,"alpha") == 0)
7812 {
7813 long
7814 alpha;
7815
7816 alpha=ParseMagickOption(MagickAlphaOptions,MagickFalse,value);
7817 if (alpha < 0)
7818 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007819 if (image != (Image *) NULL)
7820 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha);
7821 break;
7822 }
7823 if (LocaleCompare(keyword,"antialias") == 0)
7824 {
7825 long
7826 antialias;
7827
7828 antialias=ParseMagickOption(MagickBooleanOptions,MagickFalse,value);
7829 if (antialias < 0)
7830 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7831 image_info->antialias=(MagickBooleanType) antialias;
7832 break;
7833 }
7834 if (LocaleCompare(keyword,"area-limit") == 0)
7835 {
7836 MagickSizeType
7837 limit;
7838
7839 limit=MagickResourceInfinity;
7840 if (LocaleCompare(value,"unlimited") != 0)
7841 limit=(MagickSizeType) StringToDouble(value,100.0);
7842 (void) SetMagickResourceLimit(AreaResource,limit);
7843 break;
7844 }
7845 if (LocaleCompare(keyword,"attenuate") == 0)
7846 {
7847 (void) SetImageOption(image_info,keyword,value);
7848 break;
7849 }
7850 if (LocaleCompare(keyword,"authenticate") == 0)
7851 {
7852 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007853 break;
7854 }
cristyfb758a52009-09-16 14:36:08 +00007855 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7856 break;
7857 }
cristyb20775d2009-09-16 01:51:41 +00007858 case 'B':
7859 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007860 {
cristyb20775d2009-09-16 01:51:41 +00007861 if (LocaleCompare(keyword,"background") == 0)
7862 {
cristy2c8b6312009-09-16 02:37:23 +00007863 (void) QueryColorDatabase(value,&image_info->background_color,
cristyb20775d2009-09-16 01:51:41 +00007864 exception);
7865 break;
7866 }
cristy4582cbb2009-09-23 00:35:43 +00007867 if (LocaleCompare(keyword,"bias") == 0)
7868 {
7869 if (image == (Image *) NULL)
7870 break;
7871 image->bias=StringToDouble(value,QuantumRange);
7872 break;
7873 }
7874 if (LocaleCompare(keyword,"blue-primary") == 0)
7875 {
7876 if (image == (Image *) NULL)
7877 break;
7878 flags=ParseGeometry(value,&geometry_info);
7879 image->chromaticity.blue_primary.x=geometry_info.rho;
7880 image->chromaticity.blue_primary.y=geometry_info.sigma;
7881 if ((flags & SigmaValue) == 0)
7882 image->chromaticity.blue_primary.y=
7883 image->chromaticity.blue_primary.x;
7884 break;
7885 }
cristy2c8b6312009-09-16 02:37:23 +00007886 if (LocaleCompare(keyword,"bordercolor") == 0)
7887 {
7888 (void) QueryColorDatabase(value,&image_info->border_color,
7889 exception);
7890 break;
7891 }
7892 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7893 break;
7894 }
7895 case 'D':
7896 case 'd':
7897 {
7898 if (LocaleCompare(keyword,"density") == 0)
7899 {
7900 (void) CloneString(&image_info->density,value);
7901 (void) CloneString(&draw_info->density,value);
7902 break;
7903 }
cristyb20775d2009-09-16 01:51:41 +00007904 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7905 break;
7906 }
7907 case 'F':
7908 case 'f':
7909 {
7910 if (LocaleCompare(keyword,"fill") == 0)
7911 {
cristy2c8b6312009-09-16 02:37:23 +00007912 (void) QueryColorDatabase(value,&draw_info->fill,exception);
cristya30afaf2009-09-22 13:42:12 +00007913 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00007914 break;
7915 }
cristy4582cbb2009-09-23 00:35:43 +00007916 if (LocaleCompare(keyword,"filename") == 0)
7917 {
7918 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7919 break;
7920 }
7921 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7922 break;
7923 }
7924 case 'G':
7925 case 'g':
7926 {
7927 if (LocaleCompare(keyword,"gravity") == 0)
7928 {
7929 long
7930 gravity;
7931
7932 gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,value);
7933 if (gravity < 0)
7934 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7935 (void) SetImageOption(image_info,keyword,value);
7936 break;
7937 }
cristyb20775d2009-09-16 01:51:41 +00007938 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7939 break;
7940 }
7941 case 'I':
7942 case 'i':
7943 {
7944 if (LocaleCompare(keyword,"id") == 0)
7945 {
cristy4582cbb2009-09-23 00:35:43 +00007946 (void) SetImageProperty(attributes,keyword,value);
cristy2c8b6312009-09-16 02:37:23 +00007947 break;
7948 }
7949 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7950 break;
7951 }
7952 case 'M':
7953 case 'm':
7954 {
7955 if (LocaleCompare(keyword,"magick") == 0)
7956 {
7957 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
7958 break;
7959 }
cristy2c8b6312009-09-16 02:37:23 +00007960 if (LocaleCompare(keyword,"mattecolor") == 0)
7961 {
7962 (void) QueryColorDatabase(value,&image_info->matte_color,
7963 exception);
cristyb20775d2009-09-16 01:51:41 +00007964 break;
7965 }
7966 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7967 break;
7968 }
7969 case 'P':
7970 case 'p':
7971 {
7972 if (LocaleCompare(keyword,"pointsize") == 0)
7973 {
cristy4582cbb2009-09-23 00:35:43 +00007974 image_info->pointsize=atof(value);
cristy2c8b6312009-09-16 02:37:23 +00007975 draw_info->pointsize=atof(value);
cristyb20775d2009-09-16 01:51:41 +00007976 break;
7977 }
7978 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7979 break;
7980 }
cristy4582cbb2009-09-23 00:35:43 +00007981 case 'Q':
7982 case 'q':
7983 {
7984 if (LocaleCompare(keyword,"quality") == 0)
7985 {
7986 image_info->quality=atol(value);
7987 if (image == (Image *) NULL)
7988 break;
7989 image->quality=atol(value);
7990 break;
7991 }
7992 break;
7993 }
cristyb20775d2009-09-16 01:51:41 +00007994 case 'S':
7995 case 's':
7996 {
7997 if (LocaleCompare(keyword,"size") == 0)
7998 {
cristy2c8b6312009-09-16 02:37:23 +00007999 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008000 break;
8001 }
8002 if (LocaleCompare(keyword,"stroke") == 0)
8003 {
cristy2c8b6312009-09-16 02:37:23 +00008004 (void) QueryColorDatabase(value,&draw_info->stroke,exception);
cristya30afaf2009-09-22 13:42:12 +00008005 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008006 break;
8007 }
8008 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8009 break;
8010 }
8011 default:
8012 {
8013 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8014 break;
cristyb988fe72009-09-16 01:01:10 +00008015 }
8016 }
8017 return(MagickTrue);
8018}
8019
8020/*
8021%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8022% %
8023% %
8024% %
cristy3ed852e2009-09-05 21:47:34 +00008025% U n r e g i s t e r M S L I m a g e %
8026% %
8027% %
8028% %
8029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8030%
8031% UnregisterMSLImage() removes format registrations made by the
8032% MSL module from the list of supported formats.
8033%
8034% The format of the UnregisterMSLImage method is:
8035%
8036% UnregisterMSLImage(void)
8037%
8038*/
8039ModuleExport void UnregisterMSLImage(void)
8040{
8041 (void) UnregisterMagickInfo("MSL");
8042}
8043
8044#if defined(MAGICKCORE_XML_DELEGATE)
8045/*
8046%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8047% %
8048% %
8049% %
8050% W r i t e M S L I m a g e %
8051% %
8052% %
8053% %
8054%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8055%
8056% WriteMSLImage() writes an image to a file in MVG image format.
8057%
8058% The format of the WriteMSLImage method is:
8059%
8060% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8061%
8062% A description of each parameter follows.
8063%
8064% o image_info: the image info.
8065%
8066% o image: The image.
8067%
8068*/
8069static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8070{
8071 assert(image_info != (const ImageInfo *) NULL);
8072 assert(image_info->signature == MagickSignature);
8073 assert(image != (Image *) NULL);
8074 assert(image->signature == MagickSignature);
8075 if (image->debug != MagickFalse)
8076 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8077 (void) ReferenceImage(image);
8078 (void) ProcessMSLScript(image_info,&image,&image->exception);
8079 return(MagickTrue);
8080}
8081#endif