blob: 3d77fdd686a9ce7173e6467528e9e3d9bb6b3931 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% M M SSSSS L %
7% MM MM SS L %
8% M M M SSS L %
9% M M SS L %
10% M M SSSSS LLLLL %
11% %
12% %
13% Execute Magick Scripting Language Scripts. %
14% %
15% Software Design %
16% John Cristy %
17% Leonard Rosenthol %
18% William Radcliffe %
19% December 2001 %
20% %
21% %
cristy7e41fe82010-12-04 23:12:08 +000022% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000023% dedicated to making software imaging solutions freely available. %
24% %
25% You may not use this file except in compliance with the License. You may %
26% obtain a copy of the License at %
27% %
28% http://www.imagemagick.org/script/license.php %
29% %
30% Unless required by applicable law or agreed to in writing, software %
31% distributed under the License is distributed on an "AS IS" BASIS, %
32% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
33% See the License for the specific language governing permissions and %
34% limitations under the License. %
35% %
36%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37%
38%
39*/
40
41/*
42 Include declarations.
43*/
cristy4c08aed2011-07-01 19:47:50 +000044#include "MagickCore/studio.h"
45#include "MagickCore/annotate.h"
46#include "MagickCore/artifact.h"
47#include "MagickCore/blob.h"
48#include "MagickCore/blob-private.h"
49#include "MagickCore/cache.h"
50#include "MagickCore/cache-view.h"
51#include "MagickCore/color.h"
52#include "MagickCore/colormap.h"
53#include "MagickCore/color-private.h"
54#include "MagickCore/composite.h"
55#include "MagickCore/constitute.h"
56#include "MagickCore/decorate.h"
57#include "MagickCore/display.h"
58#include "MagickCore/draw.h"
59#include "MagickCore/effect.h"
60#include "MagickCore/enhance.h"
61#include "MagickCore/exception.h"
62#include "MagickCore/exception-private.h"
63#include "MagickCore/fx.h"
64#include "MagickCore/geometry.h"
65#include "MagickCore/image.h"
66#include "MagickCore/image-private.h"
67#include "MagickCore/list.h"
68#include "MagickCore/log.h"
69#include "MagickCore/magick.h"
70#include "MagickCore/memory_.h"
71#include "MagickCore/module.h"
72#include "MagickCore/option.h"
73#include "MagickCore/paint.h"
74#include "MagickCore/pixel-accessor.h"
75#include "MagickCore/profile.h"
76#include "MagickCore/property.h"
77#include "MagickCore/quantize.h"
78#include "MagickCore/quantum-private.h"
79#include "MagickCore/registry.h"
80#include "MagickCore/resize.h"
81#include "MagickCore/resource_.h"
82#include "MagickCore/segment.h"
83#include "MagickCore/shear.h"
84#include "MagickCore/signature.h"
85#include "MagickCore/static.h"
86#include "MagickCore/string_.h"
87#include "MagickCore/string-private.h"
88#include "MagickCore/transform.h"
89#include "MagickCore/threshold.h"
90#include "MagickCore/utility.h"
cristy3ed852e2009-09-05 21:47:34 +000091#if defined(MAGICKCORE_XML_DELEGATE)
cristy0157aea2010-04-24 21:12:18 +000092# if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000093# if defined(__MINGW32__)
94# define _MSC_VER
95# else
96# include <win32config.h>
97# endif
98# endif
99# include <libxml/parser.h>
100# include <libxml/xmlmemory.h>
101# include <libxml/parserInternals.h>
102# include <libxml/xmlerror.h>
103#endif
104
105/*
106 Define Declatations.
107*/
108#define ThrowMSLException(severity,tag,reason) \
109 (void) ThrowMagickException(msl_info->exception,GetMagickModule(),severity, \
110 tag,"`%s'",reason);
111
112/*
113 Typedef declaractions.
114*/
115typedef struct _MSLGroupInfo
116{
cristybb503372010-05-27 20:51:26 +0000117 size_t
cristy3ed852e2009-09-05 21:47:34 +0000118 numImages; /* how many images are in this group */
119} MSLGroupInfo;
120
121typedef struct _MSLInfo
122{
123 ExceptionInfo
124 *exception;
125
cristybb503372010-05-27 20:51:26 +0000126 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000127 n,
128 number_groups;
129
130 ImageInfo
131 **image_info;
132
133 DrawInfo
134 **draw_info;
135
136 Image
137 **attributes,
138 **image;
139
140 char
141 *content;
142
143 MSLGroupInfo
144 *group_info;
145
146#if defined(MAGICKCORE_XML_DELEGATE)
147 xmlParserCtxtPtr
148 parser;
149
150 xmlDocPtr
151 document;
152#endif
153} MSLInfo;
154
155/*
156 Forward declarations.
157*/
158#if defined(MAGICKCORE_XML_DELEGATE)
159static MagickBooleanType
160 WriteMSLImage(const ImageInfo *,Image *);
cristyb988fe72009-09-16 01:01:10 +0000161
162static MagickBooleanType
cristyb20775d2009-09-16 01:51:41 +0000163 SetMSLAttributes(MSLInfo *,const char *,const char *);
cristy3ed852e2009-09-05 21:47:34 +0000164#endif
165
166#if defined(MAGICKCORE_XML_DELEGATE)
cristyb988fe72009-09-16 01:01:10 +0000167
cristy3ed852e2009-09-05 21:47:34 +0000168/*
169%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170% %
171% %
172% %
173% R e a d M S L I m a g e %
174% %
175% %
176% %
177%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178%
179% ReadMSLImage() reads a Magick Scripting Language file and returns it.
180% It allocates the memory necessary for the new Image structure and returns a
181% pointer to the new image.
182%
183% The format of the ReadMSLImage method is:
184%
185% Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
186%
187% A description of each parameter follows:
188%
189% o image_info: the image info.
190%
191% o exception: return any errors or warnings in this structure.
192%
cristy3ed852e2009-09-05 21:47:34 +0000193*/
194
195#if defined(__cplusplus) || defined(c_plusplus)
196extern "C" {
197#endif
198
cristy4fa36e42009-09-18 14:24:06 +0000199static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
200 ExceptionInfo *exception)
201{
202 char
203 key[MaxTextExtent];
204
205 ExceptionInfo
206 *sans_exception;
207
208 Image
209 *image;
210
211 ImageInfo
212 *read_info;
213
cristyb51dff52011-05-19 16:55:47 +0000214 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
cristy4fa36e42009-09-18 14:24:06 +0000215 sans_exception=AcquireExceptionInfo();
216 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
217 sans_exception=DestroyExceptionInfo(sans_exception);
218 if (image != (Image *) NULL)
219 return(image);
220 read_info=CloneImageInfo(image_info);
221 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
222 image=ReadImage(read_info,exception);
223 read_info=DestroyImageInfo(read_info);
224 if (image != (Image *) NULL)
225 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
226 return(image);
227}
228
229static int IsPathDirectory(const char *path)
230{
231 MagickBooleanType
232 status;
233
234 struct stat
235 attributes;
236
237 if ((path == (const char *) NULL) || (*path == '\0'))
238 return(MagickFalse);
239 status=GetPathAttributes(path,&attributes);
240 if (status == MagickFalse)
241 return(-1);
242 if (S_ISDIR(attributes.st_mode) == 0)
243 return(0);
244 return(1);
245}
246
cristy3ed852e2009-09-05 21:47:34 +0000247static int MSLIsStandalone(void *context)
248{
249 MSLInfo
250 *msl_info;
251
252 /*
253 Is this document tagged standalone?
254 */
255 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.MSLIsStandalone()");
256 msl_info=(MSLInfo *) context;
257 return(msl_info->document->standalone == 1);
258}
259
260static int MSLHasInternalSubset(void *context)
261{
262 MSLInfo
263 *msl_info;
264
265 /*
266 Does this document has an internal subset?
267 */
268 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
269 " SAX.MSLHasInternalSubset()");
270 msl_info=(MSLInfo *) context;
271 return(msl_info->document->intSubset != NULL);
272}
273
274static int MSLHasExternalSubset(void *context)
275{
276 MSLInfo
277 *msl_info;
278
279 /*
280 Does this document has an external subset?
281 */
282 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
283 " SAX.MSLHasExternalSubset()");
284 msl_info=(MSLInfo *) context;
285 return(msl_info->document->extSubset != NULL);
286}
287
288static void MSLInternalSubset(void *context,const xmlChar *name,
289 const xmlChar *external_id,const xmlChar *system_id)
290{
291 MSLInfo
292 *msl_info;
293
294 /*
295 Does this document has an internal subset?
296 */
297 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
298 " SAX.internalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000299 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
300 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +0000301 msl_info=(MSLInfo *) context;
302 (void) xmlCreateIntSubset(msl_info->document,name,external_id,system_id);
303}
304
305static xmlParserInputPtr MSLResolveEntity(void *context,
306 const xmlChar *public_id,const xmlChar *system_id)
307{
308 MSLInfo
309 *msl_info;
310
311 xmlParserInputPtr
312 stream;
313
314 /*
315 Special entity resolver, better left to the parser, it has more
316 context than the application layer. The default behaviour is to
317 not resolve the entities, in that case the ENTITY_REF nodes are
318 built in the structure (and the parameter values).
319 */
320 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
321 " SAX.resolveEntity(%s, %s)",
cristyb988fe72009-09-16 01:01:10 +0000322 (public_id != (const xmlChar *) NULL ? (const char *) public_id : "none"),
323 (system_id != (const xmlChar *) NULL ? (const char *) system_id : "none"));
cristy3ed852e2009-09-05 21:47:34 +0000324 msl_info=(MSLInfo *) context;
325 stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
326 public_id,msl_info->parser);
327 return(stream);
328}
329
330static xmlEntityPtr MSLGetEntity(void *context,const xmlChar *name)
331{
332 MSLInfo
333 *msl_info;
334
335 /*
336 Get an entity by name.
337 */
338 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000339 " SAX.MSLGetEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000340 msl_info=(MSLInfo *) context;
341 return(xmlGetDocEntity(msl_info->document,name));
342}
343
344static xmlEntityPtr MSLGetParameterEntity(void *context,const xmlChar *name)
345{
346 MSLInfo
347 *msl_info;
348
349 /*
350 Get a parameter entity by name.
351 */
352 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000353 " SAX.getParameterEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000354 msl_info=(MSLInfo *) context;
355 return(xmlGetParameterEntity(msl_info->document,name));
356}
357
358static void MSLEntityDeclaration(void *context,const xmlChar *name,int type,
359 const xmlChar *public_id,const xmlChar *system_id,xmlChar *content)
360{
361 MSLInfo
362 *msl_info;
363
364 /*
365 An entity definition has been parsed.
366 */
367 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
368 " SAX.entityDecl(%s, %d, %s, %s, %s)",name,type,
cristyb988fe72009-09-16 01:01:10 +0000369 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
370 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
371 content);
cristy3ed852e2009-09-05 21:47:34 +0000372 msl_info=(MSLInfo *) context;
373 if (msl_info->parser->inSubset == 1)
374 (void) xmlAddDocEntity(msl_info->document,name,type,public_id,system_id,
375 content);
376 else
377 if (msl_info->parser->inSubset == 2)
378 (void) xmlAddDtdEntity(msl_info->document,name,type,public_id,system_id,
379 content);
380}
381
382static void MSLAttributeDeclaration(void *context,const xmlChar *element,
383 const xmlChar *name,int type,int value,const xmlChar *default_value,
384 xmlEnumerationPtr tree)
385{
386 MSLInfo
387 *msl_info;
388
389 xmlChar
390 *fullname,
391 *prefix;
392
393 xmlParserCtxtPtr
394 parser;
395
396 /*
397 An attribute definition has been parsed.
398 */
399 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
400 " SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",element,name,type,value,
401 default_value);
402 msl_info=(MSLInfo *) context;
403 fullname=(xmlChar *) NULL;
404 prefix=(xmlChar *) NULL;
405 parser=msl_info->parser;
406 fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
407 if (parser->inSubset == 1)
408 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->intSubset,
409 element,fullname,prefix,(xmlAttributeType) type,
410 (xmlAttributeDefault) value,default_value,tree);
411 else
412 if (parser->inSubset == 2)
413 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->extSubset,
414 element,fullname,prefix,(xmlAttributeType) type,
415 (xmlAttributeDefault) value,default_value,tree);
416 if (prefix != (xmlChar *) NULL)
417 xmlFree(prefix);
418 if (fullname != (xmlChar *) NULL)
419 xmlFree(fullname);
420}
421
422static void MSLElementDeclaration(void *context,const xmlChar *name,int type,
423 xmlElementContentPtr content)
424{
425 MSLInfo
426 *msl_info;
427
428 xmlParserCtxtPtr
429 parser;
430
431 /*
432 An element definition has been parsed.
433 */
434 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
435 " SAX.elementDecl(%s, %d, ...)",name,type);
436 msl_info=(MSLInfo *) context;
437 parser=msl_info->parser;
438 if (parser->inSubset == 1)
439 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->intSubset,
440 name,(xmlElementTypeVal) type,content);
441 else
442 if (parser->inSubset == 2)
443 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->extSubset,
444 name,(xmlElementTypeVal) type,content);
445}
446
447static void MSLNotationDeclaration(void *context,const xmlChar *name,
448 const xmlChar *public_id,const xmlChar *system_id)
449{
450 MSLInfo
451 *msl_info;
452
453 xmlParserCtxtPtr
454 parser;
455
456 /*
457 What to do when a notation declaration has been parsed.
458 */
459 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
460 " SAX.notationDecl(%s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000461 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
462 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none");
cristy3ed852e2009-09-05 21:47:34 +0000463 msl_info=(MSLInfo *) context;
464 parser=msl_info->parser;
465 if (parser->inSubset == 1)
466 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
467 name,public_id,system_id);
468 else
469 if (parser->inSubset == 2)
470 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
471 name,public_id,system_id);
472}
473
474static void MSLUnparsedEntityDeclaration(void *context,const xmlChar *name,
475 const xmlChar *public_id,const xmlChar *system_id,const xmlChar *notation)
476{
477 MSLInfo
478 *msl_info;
479
480 /*
481 What to do when an unparsed entity declaration is parsed.
482 */
483 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
484 " SAX.unparsedEntityDecl(%s, %s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000485 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
486 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
487 notation);
cristy3ed852e2009-09-05 21:47:34 +0000488 msl_info=(MSLInfo *) context;
489 (void) xmlAddDocEntity(msl_info->document,name,
490 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,public_id,system_id,notation);
491
492}
493
494static void MSLSetDocumentLocator(void *context,xmlSAXLocatorPtr location)
495{
496 MSLInfo
497 *msl_info;
498
499 /*
500 Receive the document locator at startup, actually xmlDefaultSAXLocator.
501 */
502 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
503 " SAX.setDocumentLocator()\n");
504 (void) location;
505 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +0000506 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +0000507}
508
509static void MSLStartDocument(void *context)
510{
511 MSLInfo
512 *msl_info;
513
514 xmlParserCtxtPtr
515 parser;
516
517 /*
518 Called when the document start being processed.
519 */
520 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
521 " SAX.startDocument()");
522 msl_info=(MSLInfo *) context;
523 parser=msl_info->parser;
524 msl_info->document=xmlNewDoc(parser->version);
525 if (msl_info->document == (xmlDocPtr) NULL)
526 return;
527 if (parser->encoding == NULL)
528 msl_info->document->encoding=NULL;
529 else
530 msl_info->document->encoding=xmlStrdup(parser->encoding);
531 msl_info->document->standalone=parser->standalone;
532}
533
534static void MSLEndDocument(void *context)
535{
536 MSLInfo
537 *msl_info;
538
539 /*
540 Called when the document end has been detected.
541 */
542 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endDocument()");
543 msl_info=(MSLInfo *) context;
544 if (msl_info->content != (char *) NULL)
545 msl_info->content=DestroyString(msl_info->content);
546}
547
548static void MSLPushImage(MSLInfo *msl_info,Image *image)
549{
cristybb503372010-05-27 20:51:26 +0000550 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000551 n;
552
553 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
554 assert(msl_info != (MSLInfo *) NULL);
555 msl_info->n++;
556 n=msl_info->n;
557 msl_info->image_info=(ImageInfo **) ResizeQuantumMemory(msl_info->image_info,
558 (n+1),sizeof(*msl_info->image_info));
559 msl_info->draw_info=(DrawInfo **) ResizeQuantumMemory(msl_info->draw_info,
560 (n+1),sizeof(*msl_info->draw_info));
561 msl_info->attributes=(Image **) ResizeQuantumMemory(msl_info->attributes,
562 (n+1),sizeof(*msl_info->attributes));
563 msl_info->image=(Image **) ResizeQuantumMemory(msl_info->image,(n+1),
564 sizeof(*msl_info->image));
565 if ((msl_info->image_info == (ImageInfo **) NULL) ||
566 (msl_info->draw_info == (DrawInfo **) NULL) ||
567 (msl_info->attributes == (Image **) NULL) ||
568 (msl_info->image == (Image **) NULL))
569 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
570 msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
571 msl_info->draw_info[n]=CloneDrawInfo(msl_info->image_info[n-1],
572 msl_info->draw_info[n-1]);
573 if (image == (Image *) NULL)
574 msl_info->attributes[n]=AcquireImage(msl_info->image_info[n]);
575 else
576 msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,&image->exception);
577 msl_info->image[n]=(Image *) image;
578 if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
579 (msl_info->attributes[n] == (Image *) NULL))
580 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
581 if (msl_info->number_groups != 0)
582 msl_info->group_info[msl_info->number_groups-1].numImages++;
583}
584
585static void MSLPopImage(MSLInfo *msl_info)
586{
587 if (msl_info->number_groups != 0)
588 return;
589 if (msl_info->image[msl_info->n] != (Image *) NULL)
590 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
591 msl_info->attributes[msl_info->n]=DestroyImage(
592 msl_info->attributes[msl_info->n]);
593 msl_info->image_info[msl_info->n]=DestroyImageInfo(
594 msl_info->image_info[msl_info->n]);
595 msl_info->n--;
596}
597
598static void MSLStartElement(void *context,const xmlChar *tag,
599 const xmlChar **attributes)
600{
601 AffineMatrix
602 affine,
603 current;
604
605 ChannelType
606 channel;
607
608 char
609 key[MaxTextExtent],
610 *value;
611
612 const char
613 *attribute,
614 *keyword;
615
616 double
617 angle;
618
619 DrawInfo
620 *draw_info;
621
622 ExceptionInfo
623 exception;
624
625 GeometryInfo
626 geometry_info;
627
628 Image
629 *image;
630
631 int
632 flags;
633
cristybb503372010-05-27 20:51:26 +0000634 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000635 option,
636 j,
637 n,
638 x,
639 y;
640
641 MSLInfo
642 *msl_info;
643
644 RectangleInfo
645 geometry;
646
cristybb503372010-05-27 20:51:26 +0000647 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000648 i;
649
cristybb503372010-05-27 20:51:26 +0000650 size_t
cristy3ed852e2009-09-05 21:47:34 +0000651 height,
652 width;
653
654 /*
655 Called when an opening tag has been processed.
656 */
657 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
658 " SAX.startElement(%s",tag);
659 GetExceptionInfo(&exception);
660 msl_info=(MSLInfo *) context;
661 n=msl_info->n;
662 keyword=(const char *) NULL;
663 value=(char *) NULL;
664 SetGeometryInfo(&geometry_info);
665 channel=DefaultChannels;
666 switch (*tag)
667 {
668 case 'A':
669 case 'a':
670 {
cristyb988fe72009-09-16 01:01:10 +0000671 if (LocaleCompare((const char *) tag,"add-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000672 {
673 Image
674 *noise_image;
675
676 NoiseType
677 noise;
678
679 /*
680 Add noise image.
681 */
682 if (msl_info->image[n] == (Image *) NULL)
683 {
cristyb988fe72009-09-16 01:01:10 +0000684 ThrowMSLException(OptionError,"NoImagesDefined",
685 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000686 break;
687 }
688 noise=UniformNoise;
689 if (attributes != (const xmlChar **) NULL)
690 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
691 {
692 keyword=(const char *) attributes[i++];
693 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +0000694 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +0000695 CloneString(&value,attribute);
696 switch (*keyword)
697 {
698 case 'C':
699 case 'c':
700 {
701 if (LocaleCompare(keyword,"channel") == 0)
702 {
703 option=ParseChannelOption(value);
704 if (option < 0)
705 ThrowMSLException(OptionError,"UnrecognizedChannelType",
706 value);
707 channel=(ChannelType) option;
708 break;
709 }
710 ThrowMSLException(OptionError,"UnrecognizedAttribute",
711 keyword);
712 break;
713 }
714 case 'N':
715 case 'n':
716 {
717 if (LocaleCompare(keyword,"noise") == 0)
718 {
cristy042ee782011-04-22 18:48:30 +0000719 option=ParseCommandOption(MagickNoiseOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000720 value);
721 if (option < 0)
722 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
723 value);
724 noise=(NoiseType) option;
725 break;
726 }
727 ThrowMSLException(OptionError,"UnrecognizedAttribute",
728 keyword);
729 break;
730 }
731 default:
732 {
733 ThrowMSLException(OptionError,"UnrecognizedAttribute",
734 keyword);
735 break;
736 }
737 }
738 }
739 noise_image=AddNoiseImageChannel(msl_info->image[n],channel,noise,
740 &msl_info->image[n]->exception);
741 if (noise_image == (Image *) NULL)
742 break;
743 msl_info->image[n]=DestroyImage(msl_info->image[n]);
744 msl_info->image[n]=noise_image;
745 break;
746 }
cristyb988fe72009-09-16 01:01:10 +0000747 if (LocaleCompare((const char *) tag,"annotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000748 {
749 char
750 text[MaxTextExtent];
751
752 /*
753 Annotate image.
754 */
755 if (msl_info->image[n] == (Image *) NULL)
756 {
cristyb988fe72009-09-16 01:01:10 +0000757 ThrowMSLException(OptionError,"NoImagesDefined",
758 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000759 break;
760 }
761 draw_info=CloneDrawInfo(msl_info->image_info[n],
762 msl_info->draw_info[n]);
763 angle=0.0;
764 current=draw_info->affine;
765 GetAffineMatrix(&affine);
766 if (attributes != (const xmlChar **) NULL)
767 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
768 {
769 keyword=(const char *) attributes[i++];
770 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +0000771 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +0000772 CloneString(&value,attribute);
773 switch (*keyword)
774 {
775 case 'A':
776 case 'a':
777 {
778 if (LocaleCompare(keyword,"affine") == 0)
779 {
780 char
781 *p;
782
783 p=value;
cristyc1acd842011-05-19 23:05:47 +0000784 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000785 if (*p ==',')
786 p++;
cristyc1acd842011-05-19 23:05:47 +0000787 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000788 if (*p ==',')
789 p++;
cristyc1acd842011-05-19 23:05:47 +0000790 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000791 if (*p ==',')
792 p++;
cristyc1acd842011-05-19 23:05:47 +0000793 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000794 if (*p ==',')
795 p++;
cristyc1acd842011-05-19 23:05:47 +0000796 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000797 if (*p ==',')
798 p++;
cristyc1acd842011-05-19 23:05:47 +0000799 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000800 break;
801 }
802 if (LocaleCompare(keyword,"align") == 0)
803 {
cristy042ee782011-04-22 18:48:30 +0000804 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000805 value);
806 if (option < 0)
807 ThrowMSLException(OptionError,"UnrecognizedAlignType",
808 value);
809 draw_info->align=(AlignType) option;
810 break;
811 }
812 if (LocaleCompare(keyword,"antialias") == 0)
813 {
cristy042ee782011-04-22 18:48:30 +0000814 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000815 value);
816 if (option < 0)
817 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
818 value);
819 draw_info->stroke_antialias=(MagickBooleanType) option;
820 draw_info->text_antialias=(MagickBooleanType) option;
821 break;
822 }
823 ThrowMSLException(OptionError,"UnrecognizedAttribute",
824 keyword);
825 break;
826 }
827 case 'D':
828 case 'd':
829 {
830 if (LocaleCompare(keyword,"density") == 0)
831 {
832 CloneString(&draw_info->density,value);
833 break;
834 }
835 ThrowMSLException(OptionError,"UnrecognizedAttribute",
836 keyword);
837 break;
838 }
839 case 'E':
840 case 'e':
841 {
842 if (LocaleCompare(keyword,"encoding") == 0)
843 {
844 CloneString(&draw_info->encoding,value);
845 break;
846 }
847 ThrowMSLException(OptionError,"UnrecognizedAttribute",
848 keyword);
849 break;
850 }
851 case 'F':
852 case 'f':
853 {
854 if (LocaleCompare(keyword, "fill") == 0)
855 {
856 (void) QueryColorDatabase(value,&draw_info->fill,
857 &exception);
858 break;
859 }
860 if (LocaleCompare(keyword,"family") == 0)
861 {
862 CloneString(&draw_info->family,value);
863 break;
864 }
865 if (LocaleCompare(keyword,"font") == 0)
866 {
867 CloneString(&draw_info->font,value);
868 break;
869 }
870 ThrowMSLException(OptionError,"UnrecognizedAttribute",
871 keyword);
872 break;
873 }
874 case 'G':
875 case 'g':
876 {
877 if (LocaleCompare(keyword,"geometry") == 0)
878 {
879 flags=ParsePageGeometry(msl_info->image[n],value,
880 &geometry,&exception);
881 if ((flags & HeightValue) == 0)
882 geometry.height=geometry.width;
883 break;
884 }
885 if (LocaleCompare(keyword,"gravity") == 0)
886 {
cristy042ee782011-04-22 18:48:30 +0000887 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000888 value);
889 if (option < 0)
890 ThrowMSLException(OptionError,"UnrecognizedGravityType",
891 value);
892 draw_info->gravity=(GravityType) option;
893 break;
894 }
895 ThrowMSLException(OptionError,"UnrecognizedAttribute",
896 keyword);
897 break;
898 }
899 case 'P':
900 case 'p':
901 {
902 if (LocaleCompare(keyword,"pointsize") == 0)
903 {
cristyc1acd842011-05-19 23:05:47 +0000904 draw_info->pointsize=InterpretLocaleValue(value,
905 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000906 break;
907 }
908 ThrowMSLException(OptionError,"UnrecognizedAttribute",
909 keyword);
910 break;
911 }
912 case 'R':
913 case 'r':
914 {
915 if (LocaleCompare(keyword,"rotate") == 0)
916 {
cristyc1acd842011-05-19 23:05:47 +0000917 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000918 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
919 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
920 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
921 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
922 break;
923 }
924 ThrowMSLException(OptionError,"UnrecognizedAttribute",
925 keyword);
926 break;
927 }
928 case 'S':
929 case 's':
930 {
931 if (LocaleCompare(keyword,"scale") == 0)
932 {
933 flags=ParseGeometry(value,&geometry_info);
934 if ((flags & SigmaValue) == 0)
935 geometry_info.sigma=1.0;
936 affine.sx=geometry_info.rho;
937 affine.sy=geometry_info.sigma;
938 break;
939 }
940 if (LocaleCompare(keyword,"skewX") == 0)
941 {
cristyc1acd842011-05-19 23:05:47 +0000942 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000943 affine.ry=tan(DegreesToRadians(fmod((double) angle,
944 360.0)));
945 break;
946 }
947 if (LocaleCompare(keyword,"skewY") == 0)
948 {
cristyc1acd842011-05-19 23:05:47 +0000949 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000950 affine.rx=tan(DegreesToRadians(fmod((double) angle,
951 360.0)));
952 break;
953 }
954 if (LocaleCompare(keyword,"stretch") == 0)
955 {
cristy042ee782011-04-22 18:48:30 +0000956 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000957 value);
958 if (option < 0)
959 ThrowMSLException(OptionError,"UnrecognizedStretchType",
960 value);
961 draw_info->stretch=(StretchType) option;
962 break;
963 }
964 if (LocaleCompare(keyword, "stroke") == 0)
965 {
966 (void) QueryColorDatabase(value,&draw_info->stroke,
967 &exception);
968 break;
969 }
970 if (LocaleCompare(keyword,"strokewidth") == 0)
971 {
cristyf2f27272009-12-17 14:48:46 +0000972 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000973 break;
974 }
975 if (LocaleCompare(keyword,"style") == 0)
976 {
cristy042ee782011-04-22 18:48:30 +0000977 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000978 value);
979 if (option < 0)
980 ThrowMSLException(OptionError,"UnrecognizedStyleType",
981 value);
982 draw_info->style=(StyleType) option;
983 break;
984 }
985 ThrowMSLException(OptionError,"UnrecognizedAttribute",
986 keyword);
987 break;
988 }
989 case 'T':
990 case 't':
991 {
992 if (LocaleCompare(keyword,"text") == 0)
993 {
994 CloneString(&draw_info->text,value);
995 break;
996 }
997 if (LocaleCompare(keyword,"translate") == 0)
998 {
999 flags=ParseGeometry(value,&geometry_info);
1000 if ((flags & SigmaValue) == 0)
1001 geometry_info.sigma=1.0;
1002 affine.tx=geometry_info.rho;
1003 affine.ty=geometry_info.sigma;
1004 break;
1005 }
1006 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1007 keyword);
1008 break;
1009 }
1010 case 'U':
1011 case 'u':
1012 {
1013 if (LocaleCompare(keyword, "undercolor") == 0)
1014 {
1015 (void) QueryColorDatabase(value,&draw_info->undercolor,
1016 &exception);
1017 break;
1018 }
1019 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1020 keyword);
1021 break;
1022 }
1023 case 'W':
1024 case 'w':
1025 {
1026 if (LocaleCompare(keyword,"weight") == 0)
1027 {
cristyf2f27272009-12-17 14:48:46 +00001028 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001029 break;
1030 }
1031 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1032 keyword);
1033 break;
1034 }
1035 case 'X':
1036 case 'x':
1037 {
1038 if (LocaleCompare(keyword,"x") == 0)
1039 {
cristyf2f27272009-12-17 14:48:46 +00001040 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001041 break;
1042 }
1043 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1044 keyword);
1045 break;
1046 }
1047 case 'Y':
1048 case 'y':
1049 {
1050 if (LocaleCompare(keyword,"y") == 0)
1051 {
cristyf2f27272009-12-17 14:48:46 +00001052 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001053 break;
1054 }
1055 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1056 keyword);
1057 break;
1058 }
1059 default:
1060 {
1061 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1062 keyword);
1063 break;
1064 }
1065 }
1066 }
cristyb51dff52011-05-19 16:55:47 +00001067 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00001068 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
1069 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00001070 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00001071 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
1072 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
1073 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
1074 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
1075 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
1076 affine.tx;
1077 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
1078 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00001079 (void) AnnotateImage(msl_info->image[n],draw_info);
1080 draw_info=DestroyDrawInfo(draw_info);
1081 break;
1082 }
cristyb988fe72009-09-16 01:01:10 +00001083 if (LocaleCompare((const char *) tag,"append") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001084 {
1085 Image
1086 *append_image;
1087
1088 MagickBooleanType
1089 stack;
cristyb988fe72009-09-16 01:01:10 +00001090
cristy3ed852e2009-09-05 21:47:34 +00001091 if (msl_info->image[n] == (Image *) NULL)
1092 {
cristyb988fe72009-09-16 01:01:10 +00001093 ThrowMSLException(OptionError,"NoImagesDefined",
1094 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001095 break;
1096 }
1097 stack=MagickFalse;
1098 if (attributes != (const xmlChar **) NULL)
1099 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1100 {
1101 keyword=(const char *) attributes[i++];
1102 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001103 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001104 CloneString(&value,attribute);
1105 switch (*keyword)
1106 {
1107 case 'S':
1108 case 's':
1109 {
1110 if (LocaleCompare(keyword,"stack") == 0)
1111 {
cristy042ee782011-04-22 18:48:30 +00001112 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001113 value);
1114 if (option < 0)
1115 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1116 value);
1117 stack=(MagickBooleanType) option;
1118 break;
1119 }
1120 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1121 keyword);
1122 break;
1123 }
1124 default:
1125 {
1126 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1127 keyword);
1128 break;
1129 }
1130 }
1131 }
1132 append_image=AppendImages(msl_info->image[n],stack,
1133 &msl_info->image[n]->exception);
1134 if (append_image == (Image *) NULL)
1135 break;
1136 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1137 msl_info->image[n]=append_image;
1138 break;
1139 }
1140 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1141 break;
1142 }
1143 case 'B':
1144 case 'b':
1145 {
cristyb988fe72009-09-16 01:01:10 +00001146 if (LocaleCompare((const char *) tag,"blur") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001147 {
1148 Image
1149 *blur_image;
1150
1151 /*
1152 Blur image.
1153 */
1154 if (msl_info->image[n] == (Image *) NULL)
1155 {
cristyb988fe72009-09-16 01:01:10 +00001156 ThrowMSLException(OptionError,"NoImagesDefined",
1157 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001158 break;
1159 }
1160 if (attributes != (const xmlChar **) NULL)
1161 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1162 {
1163 keyword=(const char *) attributes[i++];
1164 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001165 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001166 CloneString(&value,attribute);
1167 switch (*keyword)
1168 {
1169 case 'C':
1170 case 'c':
1171 {
1172 if (LocaleCompare(keyword,"channel") == 0)
1173 {
1174 option=ParseChannelOption(value);
1175 if (option < 0)
1176 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1177 value);
1178 channel=(ChannelType) option;
1179 break;
1180 }
1181 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1182 keyword);
1183 break;
1184 }
1185 case 'G':
1186 case 'g':
1187 {
1188 if (LocaleCompare(keyword,"geometry") == 0)
1189 {
1190 flags=ParseGeometry(value,&geometry_info);
1191 if ((flags & SigmaValue) == 0)
1192 geometry_info.sigma=1.0;
1193 break;
1194 }
1195 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1196 keyword);
1197 break;
1198 }
1199 case 'R':
1200 case 'r':
1201 {
1202 if (LocaleCompare(keyword,"radius") == 0)
1203 {
cristyc1acd842011-05-19 23:05:47 +00001204 geometry_info.rho=InterpretLocaleValue(value,
1205 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001206 break;
1207 }
1208 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1209 keyword);
1210 break;
1211 }
1212 case 'S':
1213 case 's':
1214 {
1215 if (LocaleCompare(keyword,"sigma") == 0)
1216 {
cristyf2f27272009-12-17 14:48:46 +00001217 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001218 break;
1219 }
1220 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1221 keyword);
1222 break;
1223 }
1224 default:
1225 {
1226 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1227 keyword);
1228 break;
1229 }
1230 }
1231 }
1232 blur_image=BlurImageChannel(msl_info->image[n],channel,
1233 geometry_info.rho,geometry_info.sigma,
1234 &msl_info->image[n]->exception);
1235 if (blur_image == (Image *) NULL)
1236 break;
1237 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1238 msl_info->image[n]=blur_image;
1239 break;
1240 }
cristyb988fe72009-09-16 01:01:10 +00001241 if (LocaleCompare((const char *) tag,"border") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001242 {
1243 Image
1244 *border_image;
1245
1246 /*
1247 Border image.
1248 */
1249 if (msl_info->image[n] == (Image *) NULL)
1250 {
cristyb988fe72009-09-16 01:01:10 +00001251 ThrowMSLException(OptionError,"NoImagesDefined",
1252 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001253 break;
1254 }
1255 SetGeometry(msl_info->image[n],&geometry);
1256 if (attributes != (const xmlChar **) NULL)
1257 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1258 {
1259 keyword=(const char *) attributes[i++];
1260 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001261 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001262 CloneString(&value,attribute);
1263 switch (*keyword)
1264 {
1265 case 'C':
1266 case 'c':
1267 {
1268 if (LocaleCompare(keyword,"compose") == 0)
1269 {
cristy042ee782011-04-22 18:48:30 +00001270 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001271 value);
1272 if (option < 0)
1273 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1274 value);
1275 msl_info->image[n]->compose=(CompositeOperator) option;
1276 break;
1277 }
1278 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1279 keyword);
1280 break;
1281 }
1282 case 'F':
1283 case 'f':
1284 {
1285 if (LocaleCompare(keyword, "fill") == 0)
1286 {
1287 (void) QueryColorDatabase(value,
1288 &msl_info->image[n]->border_color,&exception);
1289 break;
1290 }
1291 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1292 keyword);
1293 break;
1294 }
1295 case 'G':
1296 case 'g':
1297 {
1298 if (LocaleCompare(keyword,"geometry") == 0)
1299 {
1300 flags=ParsePageGeometry(msl_info->image[n],value,
1301 &geometry,&exception);
1302 if ((flags & HeightValue) == 0)
1303 geometry.height=geometry.width;
1304 break;
1305 }
1306 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1307 keyword);
1308 break;
1309 }
1310 case 'H':
1311 case 'h':
1312 {
1313 if (LocaleCompare(keyword,"height") == 0)
1314 {
cristyf2f27272009-12-17 14:48:46 +00001315 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001316 break;
1317 }
1318 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1319 keyword);
1320 break;
1321 }
1322 case 'W':
1323 case 'w':
1324 {
1325 if (LocaleCompare(keyword,"width") == 0)
1326 {
cristyf2f27272009-12-17 14:48:46 +00001327 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001328 break;
1329 }
1330 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1331 keyword);
1332 break;
1333 }
1334 default:
1335 {
1336 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1337 keyword);
1338 break;
1339 }
1340 }
1341 }
1342 border_image=BorderImage(msl_info->image[n],&geometry,
1343 &msl_info->image[n]->exception);
1344 if (border_image == (Image *) NULL)
1345 break;
1346 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1347 msl_info->image[n]=border_image;
1348 break;
1349 }
1350 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1351 }
1352 case 'C':
1353 case 'c':
1354 {
cristyb988fe72009-09-16 01:01:10 +00001355 if (LocaleCompare((const char *) tag,"colorize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001356 {
1357 char
1358 opacity[MaxTextExtent];
1359
1360 Image
1361 *colorize_image;
1362
1363 PixelPacket
1364 target;
1365
1366 /*
1367 Add noise image.
1368 */
1369 if (msl_info->image[n] == (Image *) NULL)
1370 {
cristyb988fe72009-09-16 01:01:10 +00001371 ThrowMSLException(OptionError,"NoImagesDefined",
1372 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001373 break;
1374 }
1375 target=msl_info->image[n]->background_color;
1376 (void) CopyMagickString(opacity,"100",MaxTextExtent);
1377 if (attributes != (const xmlChar **) NULL)
1378 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1379 {
1380 keyword=(const char *) attributes[i++];
1381 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001382 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001383 CloneString(&value,attribute);
1384 switch (*keyword)
1385 {
1386 case 'F':
1387 case 'f':
1388 {
1389 if (LocaleCompare(keyword,"fill") == 0)
1390 {
1391 (void) QueryColorDatabase(value,&target,
1392 &msl_info->image[n]->exception);
1393 break;
1394 }
1395 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1396 keyword);
1397 break;
1398 }
1399 case 'O':
1400 case 'o':
1401 {
1402 if (LocaleCompare(keyword,"opacity") == 0)
1403 {
1404 (void) CopyMagickString(opacity,value,MaxTextExtent);
1405 break;
1406 }
1407 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1408 keyword);
1409 break;
1410 }
1411 default:
1412 {
1413 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1414 keyword);
1415 break;
1416 }
1417 }
1418 }
1419 colorize_image=ColorizeImage(msl_info->image[n],opacity,target,
1420 &msl_info->image[n]->exception);
1421 if (colorize_image == (Image *) NULL)
1422 break;
1423 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1424 msl_info->image[n]=colorize_image;
1425 break;
1426 }
cristyb988fe72009-09-16 01:01:10 +00001427 if (LocaleCompare((const char *) tag, "charcoal") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001428 {
1429 double radius = 0.0,
1430 sigma = 1.0;
1431
1432 if (msl_info->image[n] == (Image *) NULL)
1433 {
cristyb988fe72009-09-16 01:01:10 +00001434 ThrowMSLException(OptionError,"NoImagesDefined",
1435 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001436 break;
1437 }
1438 /*
1439 NOTE: charcoal can have no attributes, since we use all the defaults!
1440 */
1441 if (attributes != (const xmlChar **) NULL)
1442 {
1443 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1444 {
1445 keyword=(const char *) attributes[i++];
1446 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001447 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00001448 switch (*keyword)
1449 {
1450 case 'R':
1451 case 'r':
1452 {
1453 if (LocaleCompare(keyword, "radius") == 0)
1454 {
cristyc1acd842011-05-19 23:05:47 +00001455 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001456 break;
1457 }
1458 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1459 break;
1460 }
1461 case 'S':
1462 case 's':
1463 {
1464 if (LocaleCompare(keyword,"sigma") == 0)
1465 {
cristyf2f27272009-12-17 14:48:46 +00001466 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00001467 break;
1468 }
1469 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1470 break;
1471 }
1472 default:
1473 {
1474 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1475 break;
1476 }
1477 }
1478 }
1479 }
1480
1481 /*
1482 charcoal image.
1483 */
1484 {
1485 Image
1486 *newImage;
1487
1488 newImage=CharcoalImage(msl_info->image[n],radius,sigma,
1489 &msl_info->image[n]->exception);
1490 if (newImage == (Image *) NULL)
1491 break;
1492 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1493 msl_info->image[n]=newImage;
1494 break;
1495 }
1496 }
cristyb988fe72009-09-16 01:01:10 +00001497 if (LocaleCompare((const char *) tag,"chop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001498 {
1499 Image
1500 *chop_image;
1501
1502 /*
1503 Chop image.
1504 */
1505 if (msl_info->image[n] == (Image *) NULL)
1506 {
cristyb988fe72009-09-16 01:01:10 +00001507 ThrowMSLException(OptionError,"NoImagesDefined",
1508 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001509 break;
1510 }
1511 SetGeometry(msl_info->image[n],&geometry);
1512 if (attributes != (const xmlChar **) NULL)
1513 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1514 {
1515 keyword=(const char *) attributes[i++];
1516 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001517 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001518 CloneString(&value,attribute);
1519 switch (*keyword)
1520 {
1521 case 'G':
1522 case 'g':
1523 {
1524 if (LocaleCompare(keyword,"geometry") == 0)
1525 {
1526 flags=ParsePageGeometry(msl_info->image[n],value,
1527 &geometry,&exception);
1528 if ((flags & HeightValue) == 0)
1529 geometry.height=geometry.width;
1530 break;
1531 }
1532 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1533 keyword);
1534 break;
1535 }
1536 case 'H':
1537 case 'h':
1538 {
1539 if (LocaleCompare(keyword,"height") == 0)
1540 {
cristyf2f27272009-12-17 14:48:46 +00001541 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001542 break;
1543 }
1544 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1545 keyword);
1546 break;
1547 }
1548 case 'W':
1549 case 'w':
1550 {
1551 if (LocaleCompare(keyword,"width") == 0)
1552 {
cristyf2f27272009-12-17 14:48:46 +00001553 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001554 break;
1555 }
1556 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1557 keyword);
1558 break;
1559 }
1560 case 'X':
1561 case 'x':
1562 {
1563 if (LocaleCompare(keyword,"x") == 0)
1564 {
cristyf2f27272009-12-17 14:48:46 +00001565 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001566 break;
1567 }
1568 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1569 keyword);
1570 break;
1571 }
1572 case 'Y':
1573 case 'y':
1574 {
1575 if (LocaleCompare(keyword,"y") == 0)
1576 {
cristyf2f27272009-12-17 14:48:46 +00001577 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001578 break;
1579 }
1580 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1581 keyword);
1582 break;
1583 }
1584 default:
1585 {
1586 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1587 keyword);
1588 break;
1589 }
1590 }
1591 }
1592 chop_image=ChopImage(msl_info->image[n],&geometry,
1593 &msl_info->image[n]->exception);
1594 if (chop_image == (Image *) NULL)
1595 break;
1596 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1597 msl_info->image[n]=chop_image;
1598 break;
1599 }
cristyb988fe72009-09-16 01:01:10 +00001600 if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001601 {
1602 PaintMethod
1603 paint_method;
1604
cristy4c08aed2011-07-01 19:47:50 +00001605 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00001606 target;
1607
1608 /*
1609 Color floodfill image.
1610 */
1611 if (msl_info->image[n] == (Image *) NULL)
1612 {
cristyb988fe72009-09-16 01:01:10 +00001613 ThrowMSLException(OptionError,"NoImagesDefined",
1614 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001615 break;
1616 }
1617 draw_info=CloneDrawInfo(msl_info->image_info[n],
1618 msl_info->draw_info[n]);
1619 SetGeometry(msl_info->image[n],&geometry);
1620 paint_method=FloodfillMethod;
1621 if (attributes != (const xmlChar **) NULL)
1622 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1623 {
1624 keyword=(const char *) attributes[i++];
1625 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001626 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001627 CloneString(&value,attribute);
1628 switch (*keyword)
1629 {
1630 case 'B':
1631 case 'b':
1632 {
1633 if (LocaleCompare(keyword,"bordercolor") == 0)
1634 {
1635 (void) QueryMagickColor(value,&target,&exception);
1636 paint_method=FillToBorderMethod;
1637 break;
1638 }
1639 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1640 keyword);
1641 break;
1642 }
1643 case 'F':
1644 case 'f':
1645 {
1646 if (LocaleCompare(keyword,"fill") == 0)
1647 {
1648 (void) QueryColorDatabase(value,&draw_info->fill,
1649 &exception);
1650 break;
1651 }
1652 if (LocaleCompare(keyword,"fuzz") == 0)
1653 {
cristyc1acd842011-05-19 23:05:47 +00001654 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
1655 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001656 break;
1657 }
1658 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1659 keyword);
1660 break;
1661 }
1662 case 'G':
1663 case 'g':
1664 {
1665 if (LocaleCompare(keyword,"geometry") == 0)
1666 {
1667 flags=ParsePageGeometry(msl_info->image[n],value,
1668 &geometry,&exception);
1669 if ((flags & HeightValue) == 0)
1670 geometry.height=geometry.width;
1671 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1672 geometry.x,geometry.y,&target,&exception);
1673 break;
1674 }
1675 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1676 keyword);
1677 break;
1678 }
1679 case 'X':
1680 case 'x':
1681 {
1682 if (LocaleCompare(keyword,"x") == 0)
1683 {
cristyf2f27272009-12-17 14:48:46 +00001684 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001685 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1686 geometry.x,geometry.y,&target,&exception);
1687 break;
1688 }
1689 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1690 keyword);
1691 break;
1692 }
1693 case 'Y':
1694 case 'y':
1695 {
1696 if (LocaleCompare(keyword,"y") == 0)
1697 {
cristyf2f27272009-12-17 14:48:46 +00001698 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001699 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1700 geometry.x,geometry.y,&target,&exception);
1701 break;
1702 }
1703 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1704 keyword);
1705 break;
1706 }
1707 default:
1708 {
1709 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1710 keyword);
1711 break;
1712 }
1713 }
1714 }
1715 (void) FloodfillPaintImage(msl_info->image[n],DefaultChannels,
1716 draw_info,&target,geometry.x,geometry.y,
1717 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
1718 draw_info=DestroyDrawInfo(draw_info);
1719 break;
1720 }
cristyb988fe72009-09-16 01:01:10 +00001721 if (LocaleCompare((const char *) tag,"comment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001722 break;
cristyb988fe72009-09-16 01:01:10 +00001723 if (LocaleCompare((const char *) tag,"composite") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001724 {
1725 char
1726 composite_geometry[MaxTextExtent];
1727
1728 CompositeOperator
1729 compose;
1730
1731 Image
1732 *composite_image,
1733 *rotate_image;
1734
1735 PixelPacket
1736 target;
1737
1738 /*
1739 Composite image.
1740 */
1741 if (msl_info->image[n] == (Image *) NULL)
1742 {
cristyb988fe72009-09-16 01:01:10 +00001743 ThrowMSLException(OptionError,"NoImagesDefined",
1744 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001745 break;
1746 }
1747 composite_image=NewImageList();
1748 compose=OverCompositeOp;
1749 if (attributes != (const xmlChar **) NULL)
1750 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1751 {
1752 keyword=(const char *) attributes[i++];
1753 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001754 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001755 CloneString(&value,attribute);
1756 switch (*keyword)
1757 {
1758 case 'C':
1759 case 'c':
1760 {
1761 if (LocaleCompare(keyword,"compose") == 0)
1762 {
cristy042ee782011-04-22 18:48:30 +00001763 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001764 value);
1765 if (option < 0)
1766 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1767 value);
1768 compose=(CompositeOperator) option;
1769 break;
1770 }
1771 break;
1772 }
1773 case 'I':
1774 case 'i':
1775 {
1776 if (LocaleCompare(keyword,"image") == 0)
1777 for (j=0; j < msl_info->n; j++)
1778 {
1779 const char
1780 *attribute;
cristyb988fe72009-09-16 01:01:10 +00001781
cristy3ed852e2009-09-05 21:47:34 +00001782 attribute=GetImageProperty(msl_info->attributes[j],"id");
1783 if ((attribute != (const char *) NULL) &&
1784 (LocaleCompare(attribute,value) == 0))
1785 {
1786 composite_image=CloneImage(msl_info->image[j],0,0,
1787 MagickFalse,&exception);
1788 break;
1789 }
1790 }
1791 break;
1792 }
1793 default:
1794 break;
1795 }
1796 }
1797 if (composite_image == (Image *) NULL)
1798 break;
1799 rotate_image=NewImageList();
1800 SetGeometry(msl_info->image[n],&geometry);
1801 if (attributes != (const xmlChar **) NULL)
1802 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1803 {
1804 keyword=(const char *) attributes[i++];
1805 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001806 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001807 CloneString(&value,attribute);
1808 switch (*keyword)
1809 {
1810 case 'B':
1811 case 'b':
1812 {
1813 if (LocaleCompare(keyword,"blend") == 0)
1814 {
1815 (void) SetImageArtifact(composite_image,
1816 "compose:args",value);
1817 break;
1818 }
1819 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1820 keyword);
1821 break;
1822 }
1823 case 'C':
1824 case 'c':
1825 {
1826 if (LocaleCompare(keyword,"channel") == 0)
1827 {
1828 option=ParseChannelOption(value);
1829 if (option < 0)
1830 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1831 value);
1832 channel=(ChannelType) option;
1833 break;
1834 }
1835 if (LocaleCompare(keyword, "color") == 0)
1836 {
1837 (void) QueryColorDatabase(value,
1838 &composite_image->background_color,&exception);
1839 break;
1840 }
1841 if (LocaleCompare(keyword,"compose") == 0)
1842 break;
1843 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1844 keyword);
1845 break;
1846 }
1847 case 'G':
1848 case 'g':
1849 {
1850 if (LocaleCompare(keyword,"geometry") == 0)
1851 {
1852 flags=ParsePageGeometry(msl_info->image[n],value,
1853 &geometry,&exception);
1854 if ((flags & HeightValue) == 0)
1855 geometry.height=geometry.width;
1856 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
1857 geometry.y,&target,&exception);
1858 break;
1859 }
1860 if (LocaleCompare(keyword,"gravity") == 0)
1861 {
cristy042ee782011-04-22 18:48:30 +00001862 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001863 value);
1864 if (option < 0)
1865 ThrowMSLException(OptionError,"UnrecognizedGravityType",
1866 value);
1867 msl_info->image[n]->gravity=(GravityType) option;
1868 break;
1869 }
1870 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1871 keyword);
1872 break;
1873 }
1874 case 'I':
1875 case 'i':
1876 {
1877 if (LocaleCompare(keyword,"image") == 0)
1878 break;
1879 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1880 keyword);
1881 break;
1882 }
1883 case 'M':
1884 case 'm':
1885 {
1886 if (LocaleCompare(keyword,"mask") == 0)
1887 for (j=0; j < msl_info->n; j++)
1888 {
1889 const char
1890 *attribute;
1891
1892 attribute=GetImageProperty(msl_info->attributes[j],"id");
1893 if ((attribute != (const char *) NULL) &&
1894 (LocaleCompare(value,value) == 0))
1895 {
1896 SetImageType(composite_image,TrueColorMatteType);
1897 (void) CompositeImage(composite_image,
1898 CopyOpacityCompositeOp,msl_info->image[j],0,0);
1899 break;
1900 }
1901 }
1902 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1903 keyword);
1904 break;
1905 }
1906 case 'O':
1907 case 'o':
1908 {
1909 if (LocaleCompare(keyword,"opacity") == 0)
1910 {
cristybb503372010-05-27 20:51:26 +00001911 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001912 opacity,
1913 y;
cristyb988fe72009-09-16 01:01:10 +00001914
cristybb503372010-05-27 20:51:26 +00001915 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001916 x;
cristyb988fe72009-09-16 01:01:10 +00001917
cristy4c08aed2011-07-01 19:47:50 +00001918 register Quantum
cristy3ed852e2009-09-05 21:47:34 +00001919 *q;
cristyb988fe72009-09-16 01:01:10 +00001920
cristy3ed852e2009-09-05 21:47:34 +00001921 CacheView
1922 *composite_view;
1923
cristy4c08aed2011-07-01 19:47:50 +00001924 opacity=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001925 if (compose != DissolveCompositeOp)
1926 {
cristyb988fe72009-09-16 01:01:10 +00001927 (void) SetImageOpacity(composite_image,(Quantum)
1928 opacity);
cristy3ed852e2009-09-05 21:47:34 +00001929 break;
1930 }
1931 (void) SetImageArtifact(msl_info->image[n],
1932 "compose:args",value);
1933 if (composite_image->matte != MagickTrue)
cristy4c08aed2011-07-01 19:47:50 +00001934 (void) SetImageOpacity(composite_image,OpaqueAlpha);
cristy3ed852e2009-09-05 21:47:34 +00001935 composite_view=AcquireCacheView(composite_image);
cristybb503372010-05-27 20:51:26 +00001936 for (y=0; y < (ssize_t) composite_image->rows ; y++)
cristyb988fe72009-09-16 01:01:10 +00001937 {
cristy4c08aed2011-07-01 19:47:50 +00001938 q=GetCacheViewAuthenticPixels(composite_view,0,y,
1939 (ssize_t) composite_image->columns,1,&exception);
cristybb503372010-05-27 20:51:26 +00001940 for (x=0; x < (ssize_t) composite_image->columns; x++)
cristyb988fe72009-09-16 01:01:10 +00001941 {
cristy4c08aed2011-07-01 19:47:50 +00001942 if (GetPixelAlpha(composite_image,q) == OpaqueAlpha)
1943 SetPixelAlpha(composite_image,
1944 ClampToQuantum(opacity),q);
1945 q+=GetPixelChannels(composite_image);
cristy3ed852e2009-09-05 21:47:34 +00001946 }
1947 if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1948 break;
1949 }
1950 composite_view=DestroyCacheView(composite_view);
1951 break;
1952 }
1953 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1954 keyword);
1955 break;
1956 }
1957 case 'R':
1958 case 'r':
1959 {
1960 if (LocaleCompare(keyword,"rotate") == 0)
1961 {
cristyc1acd842011-05-19 23:05:47 +00001962 rotate_image=RotateImage(composite_image,
1963 InterpretLocaleValue(value,(char **) NULL),&exception);
cristy3ed852e2009-09-05 21:47:34 +00001964 break;
1965 }
1966 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1967 keyword);
1968 break;
1969 }
1970 case 'T':
1971 case 't':
1972 {
1973 if (LocaleCompare(keyword,"tile") == 0)
1974 {
1975 MagickBooleanType
1976 tile;
1977
cristy042ee782011-04-22 18:48:30 +00001978 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001979 value);
1980 if (option < 0)
1981 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1982 value);
1983 tile=(MagickBooleanType) option;
cristyda16f162011-02-19 23:52:17 +00001984 (void) tile;
cristy3ed852e2009-09-05 21:47:34 +00001985 if (rotate_image != (Image *) NULL)
1986 (void) SetImageArtifact(rotate_image,
1987 "compose:outside-overlay","false");
1988 else
1989 (void) SetImageArtifact(composite_image,
1990 "compose:outside-overlay","false");
1991 image=msl_info->image[n];
1992 height=composite_image->rows;
1993 width=composite_image->columns;
cristyeaedf062010-05-29 22:36:02 +00001994 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
1995 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
cristy3ed852e2009-09-05 21:47:34 +00001996 {
1997 if (rotate_image != (Image *) NULL)
1998 (void) CompositeImage(image,compose,rotate_image,
1999 x,y);
2000 else
2001 (void) CompositeImage(image,compose,
2002 composite_image,x,y);
2003 }
2004 if (rotate_image != (Image *) NULL)
2005 rotate_image=DestroyImage(rotate_image);
2006 break;
2007 }
2008 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2009 keyword);
2010 break;
2011 }
2012 case 'X':
2013 case 'x':
2014 {
2015 if (LocaleCompare(keyword,"x") == 0)
2016 {
cristyf2f27272009-12-17 14:48:46 +00002017 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002018 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2019 geometry.y,&target,&exception);
2020 break;
2021 }
2022 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2023 keyword);
2024 break;
2025 }
2026 case 'Y':
2027 case 'y':
2028 {
2029 if (LocaleCompare(keyword,"y") == 0)
2030 {
cristyf2f27272009-12-17 14:48:46 +00002031 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002032 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2033 geometry.y,&target,&exception);
2034 break;
2035 }
2036 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2037 keyword);
2038 break;
2039 }
2040 default:
2041 {
2042 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2043 keyword);
2044 break;
2045 }
2046 }
2047 }
2048 image=msl_info->image[n];
cristyb51dff52011-05-19 16:55:47 +00002049 (void) FormatLocaleString(composite_geometry,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002050 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2051 (double) composite_image->rows,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00002052 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002053 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2054 &exception);
2055 if (rotate_image == (Image *) NULL)
cristy5bc7a4e2011-07-06 00:00:40 +00002056 CompositeImage(image,compose,composite_image,geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002057 else
2058 {
2059 /*
2060 Rotate image.
2061 */
cristybb503372010-05-27 20:51:26 +00002062 geometry.x-=(ssize_t) (rotate_image->columns-
cristy3ed852e2009-09-05 21:47:34 +00002063 composite_image->columns)/2;
cristybb503372010-05-27 20:51:26 +00002064 geometry.y-=(ssize_t) (rotate_image->rows-composite_image->rows)/2;
cristy5bc7a4e2011-07-06 00:00:40 +00002065 CompositeImage(image,compose,rotate_image,geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002066 rotate_image=DestroyImage(rotate_image);
2067 }
2068 composite_image=DestroyImage(composite_image);
2069 break;
2070 }
cristyb988fe72009-09-16 01:01:10 +00002071 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002072 {
2073 MagickBooleanType
2074 sharpen;
2075
2076 /*
2077 Contrast image.
2078 */
2079 if (msl_info->image[n] == (Image *) NULL)
2080 {
cristyb988fe72009-09-16 01:01:10 +00002081 ThrowMSLException(OptionError,"NoImagesDefined",
2082 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002083 break;
2084 }
2085 sharpen=MagickFalse;
2086 if (attributes != (const xmlChar **) NULL)
2087 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2088 {
2089 keyword=(const char *) attributes[i++];
2090 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002091 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002092 CloneString(&value,attribute);
2093 switch (*keyword)
2094 {
2095 case 'S':
2096 case 's':
2097 {
2098 if (LocaleCompare(keyword,"sharpen") == 0)
2099 {
cristy042ee782011-04-22 18:48:30 +00002100 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002101 value);
2102 if (option < 0)
2103 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2104 value);
2105 sharpen=(MagickBooleanType) option;
2106 break;
2107 }
2108 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2109 keyword);
2110 break;
2111 }
2112 default:
2113 {
2114 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2115 keyword);
2116 break;
2117 }
2118 }
2119 }
2120 (void) ContrastImage(msl_info->image[n],sharpen);
2121 break;
2122 }
cristyb988fe72009-09-16 01:01:10 +00002123 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002124 {
2125 Image
2126 *crop_image;
2127
2128 /*
2129 Crop image.
2130 */
2131 if (msl_info->image[n] == (Image *) NULL)
2132 {
cristyb988fe72009-09-16 01:01:10 +00002133 ThrowMSLException(OptionError,"NoImagesDefined",
2134 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002135 break;
2136 }
2137 SetGeometry(msl_info->image[n],&geometry);
2138 if (attributes != (const xmlChar **) NULL)
2139 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2140 {
2141 keyword=(const char *) attributes[i++];
2142 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002143 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002144 CloneString(&value,attribute);
2145 switch (*keyword)
2146 {
2147 case 'G':
2148 case 'g':
2149 {
2150 if (LocaleCompare(keyword,"geometry") == 0)
2151 {
2152 flags=ParsePageGeometry(msl_info->image[n],value,
2153 &geometry,&exception);
2154 if ((flags & HeightValue) == 0)
2155 geometry.height=geometry.width;
2156 break;
2157 }
2158 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2159 keyword);
2160 break;
2161 }
2162 case 'H':
2163 case 'h':
2164 {
2165 if (LocaleCompare(keyword,"height") == 0)
2166 {
cristyf2f27272009-12-17 14:48:46 +00002167 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002168 break;
2169 }
2170 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2171 keyword);
2172 break;
2173 }
2174 case 'W':
2175 case 'w':
2176 {
2177 if (LocaleCompare(keyword,"width") == 0)
2178 {
cristyf2f27272009-12-17 14:48:46 +00002179 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002180 break;
2181 }
2182 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2183 keyword);
2184 break;
2185 }
2186 case 'X':
2187 case 'x':
2188 {
2189 if (LocaleCompare(keyword,"x") == 0)
2190 {
cristyf2f27272009-12-17 14:48:46 +00002191 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002192 break;
2193 }
2194 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2195 keyword);
2196 break;
2197 }
2198 case 'Y':
2199 case 'y':
2200 {
2201 if (LocaleCompare(keyword,"y") == 0)
2202 {
cristyf2f27272009-12-17 14:48:46 +00002203 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002204 break;
2205 }
2206 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2207 keyword);
2208 break;
2209 }
2210 default:
2211 {
2212 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2213 keyword);
2214 break;
2215 }
2216 }
2217 }
2218 crop_image=CropImage(msl_info->image[n],&geometry,
2219 &msl_info->image[n]->exception);
2220 if (crop_image == (Image *) NULL)
2221 break;
2222 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2223 msl_info->image[n]=crop_image;
2224 break;
2225 }
cristyb988fe72009-09-16 01:01:10 +00002226 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002227 {
cristybb503372010-05-27 20:51:26 +00002228 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002229 display;
2230
2231 /*
2232 Cycle-colormap image.
2233 */
2234 if (msl_info->image[n] == (Image *) NULL)
2235 {
cristyb988fe72009-09-16 01:01:10 +00002236 ThrowMSLException(OptionError,"NoImagesDefined",
2237 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002238 break;
2239 }
2240 display=0;
2241 if (attributes != (const xmlChar **) NULL)
2242 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2243 {
2244 keyword=(const char *) attributes[i++];
2245 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002246 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002247 CloneString(&value,attribute);
2248 switch (*keyword)
2249 {
2250 case 'D':
2251 case 'd':
2252 {
2253 if (LocaleCompare(keyword,"display") == 0)
2254 {
cristyf2f27272009-12-17 14:48:46 +00002255 display=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002256 break;
2257 }
2258 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2259 keyword);
2260 break;
2261 }
2262 default:
2263 {
2264 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2265 keyword);
2266 break;
2267 }
2268 }
2269 }
2270 (void) CycleColormapImage(msl_info->image[n],display);
2271 break;
2272 }
2273 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2274 }
2275 case 'D':
2276 case 'd':
2277 {
cristyb988fe72009-09-16 01:01:10 +00002278 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002279 {
2280 Image
2281 *despeckle_image;
2282
2283 /*
2284 Despeckle image.
2285 */
2286 if (msl_info->image[n] == (Image *) NULL)
2287 {
cristyb988fe72009-09-16 01:01:10 +00002288 ThrowMSLException(OptionError,"NoImagesDefined",
2289 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002290 break;
2291 }
2292 if (attributes != (const xmlChar **) NULL)
2293 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2294 {
2295 keyword=(const char *) attributes[i++];
2296 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002297 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002298 CloneString(&value,attribute);
2299 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2300 }
2301 despeckle_image=DespeckleImage(msl_info->image[n],
2302 &msl_info->image[n]->exception);
2303 if (despeckle_image == (Image *) NULL)
2304 break;
2305 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2306 msl_info->image[n]=despeckle_image;
2307 break;
2308 }
cristyb988fe72009-09-16 01:01:10 +00002309 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002310 {
2311 if (msl_info->image[n] == (Image *) NULL)
2312 {
cristyb988fe72009-09-16 01:01:10 +00002313 ThrowMSLException(OptionError,"NoImagesDefined",
2314 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002315 break;
2316 }
2317 if (attributes != (const xmlChar **) NULL)
2318 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2319 {
2320 keyword=(const char *) attributes[i++];
2321 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002322 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002323 CloneString(&value,attribute);
2324 switch (*keyword)
2325 {
2326 default:
2327 {
2328 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2329 keyword);
2330 break;
2331 }
2332 }
2333 }
2334 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n]);
2335 break;
2336 }
cristyb988fe72009-09-16 01:01:10 +00002337 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002338 {
2339 char
2340 text[MaxTextExtent];
2341
2342 /*
2343 Annotate image.
2344 */
2345 if (msl_info->image[n] == (Image *) NULL)
2346 {
cristyb988fe72009-09-16 01:01:10 +00002347 ThrowMSLException(OptionError,"NoImagesDefined",
2348 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002349 break;
2350 }
2351 draw_info=CloneDrawInfo(msl_info->image_info[n],
2352 msl_info->draw_info[n]);
2353 angle=0.0;
2354 current=draw_info->affine;
2355 GetAffineMatrix(&affine);
2356 if (attributes != (const xmlChar **) NULL)
2357 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2358 {
2359 keyword=(const char *) attributes[i++];
2360 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002361 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002362 CloneString(&value,attribute);
2363 switch (*keyword)
2364 {
2365 case 'A':
2366 case 'a':
2367 {
2368 if (LocaleCompare(keyword,"affine") == 0)
2369 {
2370 char
2371 *p;
2372
2373 p=value;
cristyc1acd842011-05-19 23:05:47 +00002374 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002375 if (*p ==',')
2376 p++;
cristyc1acd842011-05-19 23:05:47 +00002377 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002378 if (*p ==',')
2379 p++;
cristyc1acd842011-05-19 23:05:47 +00002380 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002381 if (*p ==',')
2382 p++;
cristyc1acd842011-05-19 23:05:47 +00002383 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002384 if (*p ==',')
2385 p++;
cristyc1acd842011-05-19 23:05:47 +00002386 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002387 if (*p ==',')
2388 p++;
cristyc1acd842011-05-19 23:05:47 +00002389 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002390 break;
2391 }
2392 if (LocaleCompare(keyword,"align") == 0)
2393 {
cristy042ee782011-04-22 18:48:30 +00002394 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002395 value);
2396 if (option < 0)
2397 ThrowMSLException(OptionError,"UnrecognizedAlignType",
2398 value);
2399 draw_info->align=(AlignType) option;
2400 break;
2401 }
2402 if (LocaleCompare(keyword,"antialias") == 0)
2403 {
cristy042ee782011-04-22 18:48:30 +00002404 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002405 value);
2406 if (option < 0)
2407 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2408 value);
2409 draw_info->stroke_antialias=(MagickBooleanType) option;
2410 draw_info->text_antialias=(MagickBooleanType) option;
2411 break;
2412 }
2413 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2414 keyword);
2415 break;
2416 }
2417 case 'D':
2418 case 'd':
2419 {
2420 if (LocaleCompare(keyword,"density") == 0)
2421 {
2422 CloneString(&draw_info->density,value);
2423 break;
2424 }
2425 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2426 keyword);
2427 break;
2428 }
2429 case 'E':
2430 case 'e':
2431 {
2432 if (LocaleCompare(keyword,"encoding") == 0)
2433 {
2434 CloneString(&draw_info->encoding,value);
2435 break;
2436 }
2437 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2438 keyword);
2439 break;
2440 }
2441 case 'F':
2442 case 'f':
2443 {
2444 if (LocaleCompare(keyword, "fill") == 0)
2445 {
2446 (void) QueryColorDatabase(value,&draw_info->fill,
2447 &exception);
2448 break;
2449 }
2450 if (LocaleCompare(keyword,"family") == 0)
2451 {
2452 CloneString(&draw_info->family,value);
2453 break;
2454 }
2455 if (LocaleCompare(keyword,"font") == 0)
2456 {
2457 CloneString(&draw_info->font,value);
2458 break;
2459 }
2460 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2461 keyword);
2462 break;
2463 }
2464 case 'G':
2465 case 'g':
2466 {
2467 if (LocaleCompare(keyword,"geometry") == 0)
2468 {
2469 flags=ParsePageGeometry(msl_info->image[n],value,
2470 &geometry,&exception);
2471 if ((flags & HeightValue) == 0)
2472 geometry.height=geometry.width;
2473 break;
2474 }
2475 if (LocaleCompare(keyword,"gravity") == 0)
2476 {
cristy042ee782011-04-22 18:48:30 +00002477 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002478 value);
2479 if (option < 0)
2480 ThrowMSLException(OptionError,"UnrecognizedGravityType",
2481 value);
2482 draw_info->gravity=(GravityType) option;
2483 break;
2484 }
2485 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2486 keyword);
2487 break;
2488 }
2489 case 'P':
2490 case 'p':
2491 {
2492 if (LocaleCompare(keyword,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002493 {
cristy3ed852e2009-09-05 21:47:34 +00002494 CloneString(&draw_info->primitive,value);
2495 break;
2496 }
2497 if (LocaleCompare(keyword,"pointsize") == 0)
2498 {
cristyc1acd842011-05-19 23:05:47 +00002499 draw_info->pointsize=InterpretLocaleValue(value,
2500 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002501 break;
2502 }
2503 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2504 keyword);
2505 break;
2506 }
2507 case 'R':
2508 case 'r':
2509 {
2510 if (LocaleCompare(keyword,"rotate") == 0)
2511 {
cristyc1acd842011-05-19 23:05:47 +00002512 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002513 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2514 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2515 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2516 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2517 break;
2518 }
2519 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2520 keyword);
2521 break;
2522 }
2523 case 'S':
2524 case 's':
2525 {
2526 if (LocaleCompare(keyword,"scale") == 0)
2527 {
2528 flags=ParseGeometry(value,&geometry_info);
2529 if ((flags & SigmaValue) == 0)
2530 geometry_info.sigma=1.0;
2531 affine.sx=geometry_info.rho;
2532 affine.sy=geometry_info.sigma;
2533 break;
2534 }
2535 if (LocaleCompare(keyword,"skewX") == 0)
2536 {
cristyc1acd842011-05-19 23:05:47 +00002537 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002538 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2539 break;
2540 }
2541 if (LocaleCompare(keyword,"skewY") == 0)
2542 {
cristyc1acd842011-05-19 23:05:47 +00002543 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002544 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2545 break;
2546 }
2547 if (LocaleCompare(keyword,"stretch") == 0)
2548 {
cristy042ee782011-04-22 18:48:30 +00002549 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002550 value);
2551 if (option < 0)
2552 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2553 value);
2554 draw_info->stretch=(StretchType) option;
2555 break;
2556 }
2557 if (LocaleCompare(keyword, "stroke") == 0)
2558 {
2559 (void) QueryColorDatabase(value,&draw_info->stroke,
2560 &exception);
2561 break;
2562 }
2563 if (LocaleCompare(keyword,"strokewidth") == 0)
2564 {
cristyf2f27272009-12-17 14:48:46 +00002565 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002566 break;
2567 }
2568 if (LocaleCompare(keyword,"style") == 0)
2569 {
cristy042ee782011-04-22 18:48:30 +00002570 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002571 value);
2572 if (option < 0)
2573 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2574 value);
2575 draw_info->style=(StyleType) option;
2576 break;
2577 }
2578 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2579 keyword);
2580 break;
2581 }
2582 case 'T':
2583 case 't':
2584 {
2585 if (LocaleCompare(keyword,"text") == 0)
2586 {
2587 CloneString(&draw_info->text,value);
2588 break;
2589 }
2590 if (LocaleCompare(keyword,"translate") == 0)
2591 {
2592 flags=ParseGeometry(value,&geometry_info);
2593 if ((flags & SigmaValue) == 0)
2594 geometry_info.sigma=1.0;
2595 affine.tx=geometry_info.rho;
2596 affine.ty=geometry_info.sigma;
2597 break;
2598 }
2599 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2600 keyword);
2601 break;
2602 }
2603 case 'U':
2604 case 'u':
2605 {
2606 if (LocaleCompare(keyword, "undercolor") == 0)
2607 {
2608 (void) QueryColorDatabase(value,&draw_info->undercolor,
2609 &exception);
2610 break;
2611 }
2612 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2613 keyword);
2614 break;
2615 }
2616 case 'W':
2617 case 'w':
2618 {
2619 if (LocaleCompare(keyword,"weight") == 0)
2620 {
cristyf2f27272009-12-17 14:48:46 +00002621 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002622 break;
2623 }
2624 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2625 keyword);
2626 break;
2627 }
2628 case 'X':
2629 case 'x':
2630 {
2631 if (LocaleCompare(keyword,"x") == 0)
2632 {
cristyf2f27272009-12-17 14:48:46 +00002633 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002634 break;
2635 }
2636 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2637 keyword);
2638 break;
2639 }
2640 case 'Y':
2641 case 'y':
2642 {
2643 if (LocaleCompare(keyword,"y") == 0)
2644 {
cristyf2f27272009-12-17 14:48:46 +00002645 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002646 break;
2647 }
2648 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2649 keyword);
2650 break;
2651 }
2652 default:
2653 {
2654 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2655 keyword);
2656 break;
2657 }
2658 }
2659 }
cristyb51dff52011-05-19 16:55:47 +00002660 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002661 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2662 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002663 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002664 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2665 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2666 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2667 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2668 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2669 affine.tx;
2670 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2671 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00002672 (void) DrawImage(msl_info->image[n],draw_info);
2673 draw_info=DestroyDrawInfo(draw_info);
2674 break;
2675 }
2676 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2677 }
2678 case 'E':
2679 case 'e':
2680 {
cristyb988fe72009-09-16 01:01:10 +00002681 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002682 {
2683 Image
2684 *edge_image;
2685
2686 /*
2687 Edge image.
2688 */
2689 if (msl_info->image[n] == (Image *) NULL)
2690 {
cristyb988fe72009-09-16 01:01:10 +00002691 ThrowMSLException(OptionError,"NoImagesDefined",
2692 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002693 break;
2694 }
2695 if (attributes != (const xmlChar **) NULL)
2696 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2697 {
2698 keyword=(const char *) attributes[i++];
2699 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002700 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002701 CloneString(&value,attribute);
2702 switch (*keyword)
2703 {
2704 case 'G':
2705 case 'g':
2706 {
2707 if (LocaleCompare(keyword,"geometry") == 0)
2708 {
2709 flags=ParseGeometry(value,&geometry_info);
2710 if ((flags & SigmaValue) == 0)
2711 geometry_info.sigma=1.0;
2712 break;
2713 }
2714 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2715 keyword);
2716 break;
2717 }
2718 case 'R':
2719 case 'r':
2720 {
2721 if (LocaleCompare(keyword,"radius") == 0)
2722 {
cristyc1acd842011-05-19 23:05:47 +00002723 geometry_info.rho=InterpretLocaleValue(value,
2724 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002725 break;
2726 }
2727 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2728 keyword);
2729 break;
2730 }
2731 default:
2732 {
2733 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2734 keyword);
2735 break;
2736 }
2737 }
2738 }
2739 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
2740 &msl_info->image[n]->exception);
2741 if (edge_image == (Image *) NULL)
2742 break;
2743 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2744 msl_info->image[n]=edge_image;
2745 break;
2746 }
cristyb988fe72009-09-16 01:01:10 +00002747 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002748 {
2749 Image
2750 *emboss_image;
2751
2752 /*
2753 Emboss image.
2754 */
2755 if (msl_info->image[n] == (Image *) NULL)
2756 {
cristyb988fe72009-09-16 01:01:10 +00002757 ThrowMSLException(OptionError,"NoImagesDefined",
2758 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002759 break;
2760 }
2761 if (attributes != (const xmlChar **) NULL)
2762 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2763 {
2764 keyword=(const char *) attributes[i++];
2765 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002766 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002767 CloneString(&value,attribute);
2768 switch (*keyword)
2769 {
2770 case 'G':
2771 case 'g':
2772 {
2773 if (LocaleCompare(keyword,"geometry") == 0)
2774 {
2775 flags=ParseGeometry(value,&geometry_info);
2776 if ((flags & SigmaValue) == 0)
2777 geometry_info.sigma=1.0;
2778 break;
2779 }
2780 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2781 keyword);
2782 break;
2783 }
2784 case 'R':
2785 case 'r':
2786 {
2787 if (LocaleCompare(keyword,"radius") == 0)
2788 {
cristyc1acd842011-05-19 23:05:47 +00002789 geometry_info.rho=InterpretLocaleValue(value,
2790 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002791 break;
2792 }
2793 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2794 keyword);
2795 break;
2796 }
2797 case 'S':
2798 case 's':
2799 {
2800 if (LocaleCompare(keyword,"sigma") == 0)
2801 {
cristyf2f27272009-12-17 14:48:46 +00002802 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002803 break;
2804 }
2805 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2806 keyword);
2807 break;
2808 }
2809 default:
2810 {
2811 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2812 keyword);
2813 break;
2814 }
2815 }
2816 }
2817 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2818 geometry_info.sigma,&msl_info->image[n]->exception);
2819 if (emboss_image == (Image *) NULL)
2820 break;
2821 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2822 msl_info->image[n]=emboss_image;
2823 break;
2824 }
cristyb988fe72009-09-16 01:01:10 +00002825 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002826 {
2827 Image
2828 *enhance_image;
2829
2830 /*
2831 Enhance image.
2832 */
2833 if (msl_info->image[n] == (Image *) NULL)
2834 {
cristyb988fe72009-09-16 01:01:10 +00002835 ThrowMSLException(OptionError,"NoImagesDefined",
2836 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002837 break;
2838 }
2839 if (attributes != (const xmlChar **) NULL)
2840 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2841 {
2842 keyword=(const char *) attributes[i++];
2843 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002844 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002845 CloneString(&value,attribute);
2846 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2847 }
2848 enhance_image=EnhanceImage(msl_info->image[n],
2849 &msl_info->image[n]->exception);
2850 if (enhance_image == (Image *) NULL)
2851 break;
2852 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2853 msl_info->image[n]=enhance_image;
2854 break;
2855 }
cristyb988fe72009-09-16 01:01:10 +00002856 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002857 {
2858 /*
2859 Equalize image.
2860 */
2861 if (msl_info->image[n] == (Image *) NULL)
2862 {
cristyb988fe72009-09-16 01:01:10 +00002863 ThrowMSLException(OptionError,"NoImagesDefined",
2864 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002865 break;
2866 }
2867 if (attributes != (const xmlChar **) NULL)
2868 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2869 {
2870 keyword=(const char *) attributes[i++];
2871 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002872 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002873 CloneString(&value,attribute);
2874 switch (*keyword)
2875 {
2876 default:
2877 {
2878 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2879 keyword);
2880 break;
2881 }
2882 }
2883 }
2884 (void) EqualizeImage(msl_info->image[n]);
2885 break;
2886 }
2887 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2888 }
2889 case 'F':
2890 case 'f':
2891 {
cristyb988fe72009-09-16 01:01:10 +00002892 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002893 {
2894 if (msl_info->image[n] == (Image *) NULL)
2895 {
cristyb988fe72009-09-16 01:01:10 +00002896 ThrowMSLException(OptionError,"NoImagesDefined",
2897 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002898 break;
2899 }
2900
2901 /* no attributes here */
2902
2903 /* process the image */
2904 {
2905 Image
2906 *newImage;
2907
2908 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2909 &msl_info->image[n]->exception);
2910 if (newImage == (Image *) NULL)
2911 break;
2912 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2913 msl_info->image[n]=newImage;
2914 break;
2915 }
2916 }
cristyb988fe72009-09-16 01:01:10 +00002917 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002918 {
2919 Image
2920 *flip_image;
2921
2922 /*
2923 Flip image.
2924 */
2925 if (msl_info->image[n] == (Image *) NULL)
2926 {
cristyb988fe72009-09-16 01:01:10 +00002927 ThrowMSLException(OptionError,"NoImagesDefined",
2928 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002929 break;
2930 }
2931 if (attributes != (const xmlChar **) NULL)
2932 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2933 {
2934 keyword=(const char *) attributes[i++];
2935 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002936 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002937 CloneString(&value,attribute);
2938 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2939 }
2940 flip_image=FlipImage(msl_info->image[n],
2941 &msl_info->image[n]->exception);
2942 if (flip_image == (Image *) NULL)
2943 break;
2944 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2945 msl_info->image[n]=flip_image;
2946 break;
2947 }
cristyb988fe72009-09-16 01:01:10 +00002948 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002949 {
2950 Image
2951 *flop_image;
2952
2953 /*
2954 Flop image.
2955 */
2956 if (msl_info->image[n] == (Image *) NULL)
2957 {
cristyb988fe72009-09-16 01:01:10 +00002958 ThrowMSLException(OptionError,"NoImagesDefined",
2959 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002960 break;
2961 }
2962 if (attributes != (const xmlChar **) NULL)
2963 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2964 {
2965 keyword=(const char *) attributes[i++];
2966 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002967 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002968 CloneString(&value,attribute);
2969 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2970 }
2971 flop_image=FlopImage(msl_info->image[n],
2972 &msl_info->image[n]->exception);
2973 if (flop_image == (Image *) NULL)
2974 break;
2975 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2976 msl_info->image[n]=flop_image;
2977 break;
2978 }
cristyb988fe72009-09-16 01:01:10 +00002979 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002980 {
2981 FrameInfo
2982 frame_info;
2983
2984 Image
2985 *frame_image;
2986
2987 /*
2988 Frame image.
2989 */
2990 if (msl_info->image[n] == (Image *) NULL)
2991 {
cristyb988fe72009-09-16 01:01:10 +00002992 ThrowMSLException(OptionError,"NoImagesDefined",
2993 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002994 break;
2995 }
2996 SetGeometry(msl_info->image[n],&geometry);
2997 if (attributes != (const xmlChar **) NULL)
2998 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2999 {
3000 keyword=(const char *) attributes[i++];
3001 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003002 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003003 CloneString(&value,attribute);
3004 switch (*keyword)
3005 {
3006 case 'C':
3007 case 'c':
3008 {
3009 if (LocaleCompare(keyword,"compose") == 0)
3010 {
cristy042ee782011-04-22 18:48:30 +00003011 option=ParseCommandOption(MagickComposeOptions,
cristy3ed852e2009-09-05 21:47:34 +00003012 MagickFalse,value);
3013 if (option < 0)
3014 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3015 value);
3016 msl_info->image[n]->compose=(CompositeOperator) option;
3017 break;
3018 }
3019 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3020 keyword);
3021 break;
3022 }
3023 case 'F':
3024 case 'f':
3025 {
3026 if (LocaleCompare(keyword, "fill") == 0)
3027 {
3028 (void) QueryColorDatabase(value,
3029 &msl_info->image[n]->matte_color,&exception);
3030 break;
3031 }
3032 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3033 keyword);
3034 break;
3035 }
3036 case 'G':
3037 case 'g':
3038 {
3039 if (LocaleCompare(keyword,"geometry") == 0)
3040 {
3041 flags=ParsePageGeometry(msl_info->image[n],value,
3042 &geometry,&exception);
3043 if ((flags & HeightValue) == 0)
3044 geometry.height=geometry.width;
3045 frame_info.width=geometry.width;
3046 frame_info.height=geometry.height;
3047 frame_info.outer_bevel=geometry.x;
3048 frame_info.inner_bevel=geometry.y;
3049 break;
3050 }
3051 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3052 keyword);
3053 break;
3054 }
3055 case 'H':
3056 case 'h':
3057 {
3058 if (LocaleCompare(keyword,"height") == 0)
3059 {
cristyf2f27272009-12-17 14:48:46 +00003060 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003061 break;
3062 }
3063 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3064 keyword);
3065 break;
3066 }
3067 case 'I':
3068 case 'i':
3069 {
3070 if (LocaleCompare(keyword,"inner") == 0)
3071 {
cristyf2f27272009-12-17 14:48:46 +00003072 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003073 break;
3074 }
3075 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3076 keyword);
3077 break;
3078 }
3079 case 'O':
3080 case 'o':
3081 {
3082 if (LocaleCompare(keyword,"outer") == 0)
3083 {
cristyf2f27272009-12-17 14:48:46 +00003084 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003085 break;
3086 }
3087 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3088 keyword);
3089 break;
3090 }
3091 case 'W':
3092 case 'w':
3093 {
3094 if (LocaleCompare(keyword,"width") == 0)
3095 {
cristyf2f27272009-12-17 14:48:46 +00003096 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003097 break;
3098 }
3099 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3100 keyword);
3101 break;
3102 }
3103 default:
3104 {
3105 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3106 keyword);
3107 break;
3108 }
3109 }
3110 }
cristybb503372010-05-27 20:51:26 +00003111 frame_info.x=(ssize_t) frame_info.width;
3112 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003113 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3114 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3115 frame_image=FrameImage(msl_info->image[n],&frame_info,
3116 &msl_info->image[n]->exception);
3117 if (frame_image == (Image *) NULL)
3118 break;
3119 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3120 msl_info->image[n]=frame_image;
3121 break;
3122 }
3123 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3124 }
3125 case 'G':
3126 case 'g':
3127 {
cristyb988fe72009-09-16 01:01:10 +00003128 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003129 {
3130 char
3131 gamma[MaxTextExtent];
3132
cristy4c08aed2011-07-01 19:47:50 +00003133 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003134 pixel;
3135
3136 /*
3137 Gamma image.
3138 */
3139 if (msl_info->image[n] == (Image *) NULL)
3140 {
cristyb988fe72009-09-16 01:01:10 +00003141 ThrowMSLException(OptionError,"NoImagesDefined",
3142 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003143 break;
3144 }
3145 channel=UndefinedChannel;
3146 pixel.red=0.0;
3147 pixel.green=0.0;
3148 pixel.blue=0.0;
3149 *gamma='\0';
3150 if (attributes != (const xmlChar **) NULL)
3151 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3152 {
3153 keyword=(const char *) attributes[i++];
3154 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003155 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003156 CloneString(&value,attribute);
3157 switch (*keyword)
3158 {
3159 case 'B':
3160 case 'b':
3161 {
3162 if (LocaleCompare(keyword,"blue") == 0)
3163 {
cristyc1acd842011-05-19 23:05:47 +00003164 pixel.blue=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003165 break;
3166 }
3167 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3168 keyword);
3169 break;
3170 }
3171 case 'C':
3172 case 'c':
3173 {
3174 if (LocaleCompare(keyword,"channel") == 0)
3175 {
3176 option=ParseChannelOption(value);
3177 if (option < 0)
3178 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3179 value);
3180 channel=(ChannelType) option;
3181 break;
3182 }
3183 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3184 keyword);
3185 break;
3186 }
3187 case 'G':
3188 case 'g':
3189 {
3190 if (LocaleCompare(keyword,"gamma") == 0)
3191 {
3192 (void) CopyMagickString(gamma,value,MaxTextExtent);
3193 break;
3194 }
3195 if (LocaleCompare(keyword,"green") == 0)
3196 {
cristyc1acd842011-05-19 23:05:47 +00003197 pixel.green=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003198 break;
3199 }
3200 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3201 keyword);
3202 break;
3203 }
3204 case 'R':
3205 case 'r':
3206 {
3207 if (LocaleCompare(keyword,"red") == 0)
3208 {
cristyc1acd842011-05-19 23:05:47 +00003209 pixel.red=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003210 break;
3211 }
3212 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3213 keyword);
3214 break;
3215 }
3216 default:
3217 {
3218 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3219 keyword);
3220 break;
3221 }
3222 }
3223 }
3224 if (*gamma == '\0')
cristyb51dff52011-05-19 16:55:47 +00003225 (void) FormatLocaleString(gamma,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003226 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb988fe72009-09-16 01:01:10 +00003227 switch (channel)
cristy3ed852e2009-09-05 21:47:34 +00003228 {
3229 default:
3230 {
3231 (void) GammaImage(msl_info->image[n],gamma);
3232 break;
3233 }
3234 case RedChannel:
3235 {
3236 (void) GammaImageChannel(msl_info->image[n],RedChannel,pixel.red);
3237 break;
3238 }
3239 case GreenChannel:
3240 {
3241 (void) GammaImageChannel(msl_info->image[n],GreenChannel,
3242 pixel.green);
3243 break;
3244 }
3245 case BlueChannel:
3246 {
3247 (void) GammaImageChannel(msl_info->image[n],BlueChannel,
3248 pixel.blue);
3249 break;
3250 }
3251 }
3252 break;
3253 }
cristyb988fe72009-09-16 01:01:10 +00003254 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003255 {
3256 if (msl_info->image[n] == (Image *) NULL)
3257 {
cristyb988fe72009-09-16 01:01:10 +00003258 ThrowMSLException(OptionError,"NoImagesDefined",
3259 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003260 break;
3261 }
3262 if (attributes == (const xmlChar **) NULL)
3263 break;
3264 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3265 {
3266 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003267 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003268 (void) CopyMagickString(key,value,MaxTextExtent);
3269 switch (*keyword)
3270 {
3271 case 'H':
3272 case 'h':
3273 {
3274 if (LocaleCompare(keyword,"height") == 0)
3275 {
cristyb51dff52011-05-19 16:55:47 +00003276 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003277 (double) msl_info->image[n]->rows);
cristy3ed852e2009-09-05 21:47:34 +00003278 (void) SetImageProperty(msl_info->attributes[n],key,value);
3279 break;
3280 }
3281 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3282 }
3283 case 'W':
3284 case 'w':
3285 {
3286 if (LocaleCompare(keyword,"width") == 0)
3287 {
cristyb51dff52011-05-19 16:55:47 +00003288 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003289 (double) msl_info->image[n]->columns);
cristy3ed852e2009-09-05 21:47:34 +00003290 (void) SetImageProperty(msl_info->attributes[n],key,value);
3291 break;
3292 }
3293 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3294 }
3295 default:
3296 {
3297 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3298 break;
3299 }
3300 }
3301 }
3302 break;
3303 }
cristyb988fe72009-09-16 01:01:10 +00003304 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003305 {
3306 msl_info->number_groups++;
3307 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3308 msl_info->group_info,msl_info->number_groups+1UL,
3309 sizeof(*msl_info->group_info));
3310 break;
3311 }
3312 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3313 }
3314 case 'I':
3315 case 'i':
3316 {
cristyb988fe72009-09-16 01:01:10 +00003317 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003318 {
cristy3ed852e2009-09-05 21:47:34 +00003319 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003320 if (attributes == (const xmlChar **) NULL)
3321 break;
3322 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3323 {
3324 keyword=(const char *) attributes[i++];
3325 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003326 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00003327 switch (*keyword)
3328 {
cristyb988fe72009-09-16 01:01:10 +00003329 case 'C':
3330 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003331 {
cristyb988fe72009-09-16 01:01:10 +00003332 if (LocaleCompare(keyword,"color") == 0)
3333 {
3334 Image
3335 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003336
cristyb988fe72009-09-16 01:01:10 +00003337 (void) CopyMagickString(msl_info->image_info[n]->filename,
3338 "xc:",MaxTextExtent);
3339 (void) ConcatenateMagickString(msl_info->image_info[n]->
3340 filename,value,MaxTextExtent);
3341 next_image=ReadImage(msl_info->image_info[n],&exception);
3342 CatchException(&exception);
3343 if (next_image == (Image *) NULL)
3344 continue;
3345 if (msl_info->image[n] == (Image *) NULL)
3346 msl_info->image[n]=next_image;
3347 else
3348 {
3349 register Image
3350 *p;
cristy3ed852e2009-09-05 21:47:34 +00003351
cristyb988fe72009-09-16 01:01:10 +00003352 /*
3353 Link image into image list.
3354 */
3355 p=msl_info->image[n];
3356 while (p->next != (Image *) NULL)
3357 p=GetNextImageInList(p);
3358 next_image->previous=p;
3359 p->next=next_image;
3360 }
3361 break;
3362 }
cristyb20775d2009-09-16 01:51:41 +00003363 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003364 break;
3365 }
3366 default:
3367 {
cristyb20775d2009-09-16 01:51:41 +00003368 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003369 break;
3370 }
3371 }
3372 }
3373 break;
3374 }
cristyb988fe72009-09-16 01:01:10 +00003375 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003376 {
3377 Image
3378 *implode_image;
3379
3380 /*
3381 Implode image.
3382 */
3383 if (msl_info->image[n] == (Image *) NULL)
3384 {
cristyb988fe72009-09-16 01:01:10 +00003385 ThrowMSLException(OptionError,"NoImagesDefined",
3386 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003387 break;
3388 }
3389 if (attributes != (const xmlChar **) NULL)
3390 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3391 {
3392 keyword=(const char *) attributes[i++];
3393 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003394 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003395 CloneString(&value,attribute);
3396 switch (*keyword)
3397 {
3398 case 'A':
3399 case 'a':
3400 {
3401 if (LocaleCompare(keyword,"amount") == 0)
3402 {
cristyc1acd842011-05-19 23:05:47 +00003403 geometry_info.rho=InterpretLocaleValue(value,
3404 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003405 break;
3406 }
3407 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3408 keyword);
3409 break;
3410 }
3411 case 'G':
3412 case 'g':
3413 {
3414 if (LocaleCompare(keyword,"geometry") == 0)
3415 {
3416 flags=ParseGeometry(value,&geometry_info);
3417 if ((flags & SigmaValue) == 0)
3418 geometry_info.sigma=1.0;
3419 break;
3420 }
3421 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3422 keyword);
3423 break;
3424 }
3425 default:
3426 {
3427 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3428 keyword);
3429 break;
3430 }
3431 }
3432 }
3433 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3434 &msl_info->image[n]->exception);
3435 if (implode_image == (Image *) NULL)
3436 break;
3437 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3438 msl_info->image[n]=implode_image;
3439 break;
3440 }
3441 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3442 }
3443 case 'L':
3444 case 'l':
3445 {
cristyb988fe72009-09-16 01:01:10 +00003446 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003447 break;
cristyb988fe72009-09-16 01:01:10 +00003448 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003449 {
3450 double
3451 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3452
3453 if (msl_info->image[n] == (Image *) NULL)
3454 {
cristyb988fe72009-09-16 01:01:10 +00003455 ThrowMSLException(OptionError,"NoImagesDefined",
3456 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003457 break;
3458 }
3459 if (attributes == (const xmlChar **) NULL)
3460 break;
3461 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3462 {
3463 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003464 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003465 (void) CopyMagickString(key,value,MaxTextExtent);
3466 switch (*keyword)
3467 {
3468 case 'B':
3469 case 'b':
3470 {
3471 if (LocaleCompare(keyword,"black") == 0)
3472 {
cristyc1acd842011-05-19 23:05:47 +00003473 levelBlack = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003474 break;
3475 }
3476 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3477 break;
3478 }
3479 case 'G':
3480 case 'g':
3481 {
3482 if (LocaleCompare(keyword,"gamma") == 0)
3483 {
cristyc1acd842011-05-19 23:05:47 +00003484 levelGamma = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003485 break;
3486 }
3487 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3488 break;
3489 }
3490 case 'W':
3491 case 'w':
3492 {
3493 if (LocaleCompare(keyword,"white") == 0)
3494 {
cristyc1acd842011-05-19 23:05:47 +00003495 levelWhite = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003496 break;
3497 }
3498 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3499 break;
3500 }
3501 default:
3502 {
3503 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3504 break;
3505 }
3506 }
3507 }
3508
3509 /* process image */
3510 {
3511 char level[MaxTextExtent + 1];
cristyb51dff52011-05-19 16:55:47 +00003512 (void) FormatLocaleString(level,MaxTextExtent,"%3.6f/%3.6f/%3.6f/",
cristy3ed852e2009-09-05 21:47:34 +00003513 levelBlack,levelGamma,levelWhite);
3514 LevelImage ( msl_info->image[n], level );
3515 break;
3516 }
3517 }
3518 }
3519 case 'M':
3520 case 'm':
3521 {
cristyb988fe72009-09-16 01:01:10 +00003522 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003523 {
3524 Image
3525 *magnify_image;
3526
3527 /*
3528 Magnify image.
3529 */
3530 if (msl_info->image[n] == (Image *) NULL)
3531 {
cristyb988fe72009-09-16 01:01:10 +00003532 ThrowMSLException(OptionError,"NoImagesDefined",
3533 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003534 break;
3535 }
3536 if (attributes != (const xmlChar **) NULL)
3537 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3538 {
3539 keyword=(const char *) attributes[i++];
3540 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003541 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003542 CloneString(&value,attribute);
3543 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3544 }
3545 magnify_image=MagnifyImage(msl_info->image[n],
3546 &msl_info->image[n]->exception);
3547 if (magnify_image == (Image *) NULL)
3548 break;
3549 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3550 msl_info->image[n]=magnify_image;
3551 break;
3552 }
cristyb988fe72009-09-16 01:01:10 +00003553 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003554 {
3555 Image
3556 *affinity_image;
3557
3558 MagickBooleanType
3559 dither;
3560
3561 QuantizeInfo
3562 *quantize_info;
3563
3564 /*
3565 Map image.
3566 */
3567 if (msl_info->image[n] == (Image *) NULL)
3568 {
cristyb988fe72009-09-16 01:01:10 +00003569 ThrowMSLException(OptionError,"NoImagesDefined",
3570 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003571 break;
3572 }
3573 affinity_image=NewImageList();
3574 dither=MagickFalse;
3575 if (attributes != (const xmlChar **) NULL)
3576 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3577 {
3578 keyword=(const char *) attributes[i++];
3579 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003580 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003581 CloneString(&value,attribute);
3582 switch (*keyword)
3583 {
3584 case 'D':
3585 case 'd':
3586 {
3587 if (LocaleCompare(keyword,"dither") == 0)
3588 {
cristy042ee782011-04-22 18:48:30 +00003589 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003590 value);
3591 if (option < 0)
3592 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3593 value);
3594 dither=(MagickBooleanType) option;
3595 break;
3596 }
3597 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3598 keyword);
3599 break;
3600 }
3601 case 'I':
3602 case 'i':
3603 {
3604 if (LocaleCompare(keyword,"image") == 0)
3605 for (j=0; j < msl_info->n; j++)
3606 {
3607 const char
3608 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003609
cristy3ed852e2009-09-05 21:47:34 +00003610 attribute=GetImageProperty(msl_info->attributes[j],"id");
3611 if ((attribute != (const char *) NULL) &&
3612 (LocaleCompare(attribute,value) == 0))
3613 {
3614 affinity_image=CloneImage(msl_info->image[j],0,0,
3615 MagickFalse,&exception);
3616 break;
3617 }
3618 }
3619 break;
3620 }
3621 default:
3622 {
3623 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3624 keyword);
3625 break;
3626 }
3627 }
3628 }
3629 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3630 quantize_info->dither=dither;
3631 (void) RemapImages(quantize_info,msl_info->image[n],
3632 affinity_image);
3633 quantize_info=DestroyQuantizeInfo(quantize_info);
3634 affinity_image=DestroyImage(affinity_image);
3635 break;
3636 }
cristyb988fe72009-09-16 01:01:10 +00003637 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003638 {
3639 double
3640 opacity;
3641
cristy4c08aed2011-07-01 19:47:50 +00003642 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003643 target;
3644
3645 PaintMethod
3646 paint_method;
3647
3648 /*
3649 Matte floodfill image.
3650 */
3651 opacity=0.0;
3652 if (msl_info->image[n] == (Image *) NULL)
3653 {
cristyb988fe72009-09-16 01:01:10 +00003654 ThrowMSLException(OptionError,"NoImagesDefined",
3655 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003656 break;
3657 }
3658 SetGeometry(msl_info->image[n],&geometry);
3659 paint_method=FloodfillMethod;
3660 if (attributes != (const xmlChar **) NULL)
3661 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3662 {
3663 keyword=(const char *) attributes[i++];
3664 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003665 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003666 CloneString(&value,attribute);
3667 switch (*keyword)
3668 {
3669 case 'B':
3670 case 'b':
3671 {
3672 if (LocaleCompare(keyword,"bordercolor") == 0)
3673 {
3674 (void) QueryMagickColor(value,&target,&exception);
3675 paint_method=FillToBorderMethod;
3676 break;
3677 }
3678 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3679 keyword);
3680 break;
3681 }
3682 case 'F':
3683 case 'f':
3684 {
3685 if (LocaleCompare(keyword,"fuzz") == 0)
3686 {
cristyc1acd842011-05-19 23:05:47 +00003687 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
3688 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003689 break;
3690 }
3691 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3692 keyword);
3693 break;
3694 }
3695 case 'G':
3696 case 'g':
3697 {
3698 if (LocaleCompare(keyword,"geometry") == 0)
3699 {
3700 flags=ParsePageGeometry(msl_info->image[n],value,
3701 &geometry,&exception);
3702 if ((flags & HeightValue) == 0)
3703 geometry.height=geometry.width;
3704 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3705 geometry.x,geometry.y,&target,&exception);
3706 break;
3707 }
3708 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3709 keyword);
3710 break;
3711 }
3712 case 'O':
3713 case 'o':
3714 {
3715 if (LocaleCompare(keyword,"opacity") == 0)
3716 {
cristyc1acd842011-05-19 23:05:47 +00003717 opacity=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003718 break;
3719 }
3720 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3721 keyword);
3722 break;
3723 }
3724 case 'X':
3725 case 'x':
3726 {
3727 if (LocaleCompare(keyword,"x") == 0)
3728 {
cristyf2f27272009-12-17 14:48:46 +00003729 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003730 (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 case 'Y':
3739 case 'y':
3740 {
3741 if (LocaleCompare(keyword,"y") == 0)
3742 {
cristyf2f27272009-12-17 14:48:46 +00003743 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003744 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3745 geometry.x,geometry.y,&target,&exception);
3746 break;
3747 }
3748 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3749 keyword);
3750 break;
3751 }
3752 default:
3753 {
3754 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3755 keyword);
3756 break;
3757 }
3758 }
3759 }
3760 draw_info=CloneDrawInfo(msl_info->image_info[n],
3761 msl_info->draw_info[n]);
cristy4c08aed2011-07-01 19:47:50 +00003762 draw_info->fill.alpha=ClampToQuantum(opacity);
cristy3ed852e2009-09-05 21:47:34 +00003763 (void) FloodfillPaintImage(msl_info->image[n],OpacityChannel,
3764 draw_info,&target,geometry.x,geometry.y,
3765 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
3766 draw_info=DestroyDrawInfo(draw_info);
3767 break;
3768 }
cristyb988fe72009-09-16 01:01:10 +00003769 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003770 {
3771 Image
3772 *median_image;
3773
3774 /*
3775 Median-filter image.
3776 */
3777 if (msl_info->image[n] == (Image *) NULL)
3778 {
cristyb988fe72009-09-16 01:01:10 +00003779 ThrowMSLException(OptionError,"NoImagesDefined",
3780 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003781 break;
3782 }
3783 if (attributes != (const xmlChar **) NULL)
3784 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3785 {
3786 keyword=(const char *) attributes[i++];
3787 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003788 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003789 CloneString(&value,attribute);
3790 switch (*keyword)
3791 {
3792 case 'G':
3793 case 'g':
3794 {
3795 if (LocaleCompare(keyword,"geometry") == 0)
3796 {
3797 flags=ParseGeometry(value,&geometry_info);
3798 if ((flags & SigmaValue) == 0)
3799 geometry_info.sigma=1.0;
3800 break;
3801 }
3802 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3803 keyword);
3804 break;
3805 }
3806 case 'R':
3807 case 'r':
3808 {
3809 if (LocaleCompare(keyword,"radius") == 0)
3810 {
cristyc1acd842011-05-19 23:05:47 +00003811 geometry_info.rho=InterpretLocaleValue(value,
3812 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003813 break;
3814 }
3815 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3816 keyword);
3817 break;
3818 }
3819 default:
3820 {
3821 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3822 keyword);
3823 break;
3824 }
3825 }
3826 }
cristy733678d2011-03-18 21:29:28 +00003827 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003828 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3829 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003830 if (median_image == (Image *) NULL)
3831 break;
3832 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3833 msl_info->image[n]=median_image;
3834 break;
3835 }
cristyb988fe72009-09-16 01:01:10 +00003836 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003837 {
3838 Image
3839 *minify_image;
3840
3841 /*
3842 Minify image.
3843 */
3844 if (msl_info->image[n] == (Image *) NULL)
3845 {
cristyb988fe72009-09-16 01:01:10 +00003846 ThrowMSLException(OptionError,"NoImagesDefined",
3847 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003848 break;
3849 }
3850 if (attributes != (const xmlChar **) NULL)
3851 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3852 {
3853 keyword=(const char *) attributes[i++];
3854 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003855 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003856 CloneString(&value,attribute);
3857 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3858 }
3859 minify_image=MinifyImage(msl_info->image[n],
3860 &msl_info->image[n]->exception);
3861 if (minify_image == (Image *) NULL)
3862 break;
3863 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3864 msl_info->image[n]=minify_image;
3865 break;
3866 }
cristyb988fe72009-09-16 01:01:10 +00003867 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003868 break;
cristyb988fe72009-09-16 01:01:10 +00003869 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003870 {
3871 char
3872 modulate[MaxTextExtent];
3873
3874 /*
3875 Modulate image.
3876 */
3877 if (msl_info->image[n] == (Image *) NULL)
3878 {
cristyb988fe72009-09-16 01:01:10 +00003879 ThrowMSLException(OptionError,"NoImagesDefined",
3880 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003881 break;
3882 }
3883 geometry_info.rho=100.0;
3884 geometry_info.sigma=100.0;
3885 geometry_info.xi=100.0;
3886 if (attributes != (const xmlChar **) NULL)
3887 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3888 {
3889 keyword=(const char *) attributes[i++];
3890 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003891 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003892 CloneString(&value,attribute);
3893 switch (*keyword)
3894 {
3895 case 'B':
3896 case 'b':
3897 {
3898 if (LocaleCompare(keyword,"blackness") == 0)
3899 {
cristyc1acd842011-05-19 23:05:47 +00003900 geometry_info.rho=InterpretLocaleValue(value,
3901 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003902 break;
3903 }
3904 if (LocaleCompare(keyword,"brightness") == 0)
3905 {
cristyc1acd842011-05-19 23:05:47 +00003906 geometry_info.rho=InterpretLocaleValue(value,
3907 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003908 break;
3909 }
3910 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3911 keyword);
3912 break;
3913 }
3914 case 'F':
3915 case 'f':
3916 {
3917 if (LocaleCompare(keyword,"factor") == 0)
3918 {
3919 flags=ParseGeometry(value,&geometry_info);
3920 break;
3921 }
3922 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3923 keyword);
3924 break;
3925 }
3926 case 'H':
3927 case 'h':
3928 {
3929 if (LocaleCompare(keyword,"hue") == 0)
3930 {
cristyc1acd842011-05-19 23:05:47 +00003931 geometry_info.xi=InterpretLocaleValue(value,
3932 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003933 break;
3934 }
3935 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3936 keyword);
3937 break;
3938 }
3939 case 'L':
3940 case 'l':
3941 {
3942 if (LocaleCompare(keyword,"lightness") == 0)
3943 {
cristyc1acd842011-05-19 23:05:47 +00003944 geometry_info.rho=InterpretLocaleValue(value,
3945 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003946 break;
3947 }
3948 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3949 keyword);
3950 break;
3951 }
3952 case 'S':
3953 case 's':
3954 {
3955 if (LocaleCompare(keyword,"saturation") == 0)
3956 {
cristyc1acd842011-05-19 23:05:47 +00003957 geometry_info.sigma=InterpretLocaleValue(value,
3958 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003959 break;
3960 }
3961 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3962 keyword);
3963 break;
3964 }
3965 case 'W':
3966 case 'w':
3967 {
3968 if (LocaleCompare(keyword,"whiteness") == 0)
3969 {
cristyc1acd842011-05-19 23:05:47 +00003970 geometry_info.sigma=InterpretLocaleValue(value,
3971 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003972 break;
3973 }
3974 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3975 keyword);
3976 break;
3977 }
3978 default:
3979 {
3980 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3981 keyword);
3982 break;
3983 }
3984 }
3985 }
cristyb51dff52011-05-19 16:55:47 +00003986 (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003987 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
3988 (void) ModulateImage(msl_info->image[n],modulate);
3989 break;
3990 }
3991 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3992 }
3993 case 'N':
3994 case 'n':
3995 {
cristyb988fe72009-09-16 01:01:10 +00003996 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003997 {
3998 MagickBooleanType
3999 gray;
4000
4001 /*
4002 Negate image.
4003 */
4004 if (msl_info->image[n] == (Image *) NULL)
4005 {
cristyb988fe72009-09-16 01:01:10 +00004006 ThrowMSLException(OptionError,"NoImagesDefined",
4007 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004008 break;
4009 }
4010 gray=MagickFalse;
4011 if (attributes != (const xmlChar **) NULL)
4012 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4013 {
4014 keyword=(const char *) attributes[i++];
4015 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004016 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004017 CloneString(&value,attribute);
4018 switch (*keyword)
4019 {
4020 case 'C':
4021 case 'c':
4022 {
4023 if (LocaleCompare(keyword,"channel") == 0)
4024 {
4025 option=ParseChannelOption(value);
4026 if (option < 0)
4027 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4028 value);
4029 channel=(ChannelType) option;
4030 break;
4031 }
4032 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4033 keyword);
4034 break;
4035 }
4036 case 'G':
4037 case 'g':
4038 {
4039 if (LocaleCompare(keyword,"gray") == 0)
4040 {
cristy042ee782011-04-22 18:48:30 +00004041 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004042 value);
4043 if (option < 0)
4044 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4045 value);
4046 gray=(MagickBooleanType) option;
4047 break;
4048 }
4049 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4050 keyword);
4051 break;
4052 }
4053 default:
4054 {
4055 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4056 keyword);
4057 break;
4058 }
4059 }
4060 }
4061 (void) NegateImageChannel(msl_info->image[n],channel,gray);
4062 break;
4063 }
cristyb988fe72009-09-16 01:01:10 +00004064 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004065 {
4066 /*
4067 Normalize image.
4068 */
4069 if (msl_info->image[n] == (Image *) NULL)
4070 {
cristyb988fe72009-09-16 01:01:10 +00004071 ThrowMSLException(OptionError,"NoImagesDefined",
4072 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004073 break;
4074 }
4075 if (attributes != (const xmlChar **) NULL)
4076 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4077 {
4078 keyword=(const char *) attributes[i++];
4079 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004080 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004081 CloneString(&value,attribute);
4082 switch (*keyword)
4083 {
4084 case 'C':
4085 case 'c':
4086 {
4087 if (LocaleCompare(keyword,"channel") == 0)
4088 {
4089 option=ParseChannelOption(value);
4090 if (option < 0)
4091 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4092 value);
4093 channel=(ChannelType) option;
4094 break;
4095 }
4096 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4097 keyword);
4098 break;
4099 }
4100 default:
4101 {
4102 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4103 keyword);
4104 break;
4105 }
4106 }
4107 }
4108 (void) NormalizeImageChannel(msl_info->image[n],channel);
4109 break;
4110 }
4111 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4112 }
4113 case 'O':
4114 case 'o':
4115 {
cristyb988fe72009-09-16 01:01:10 +00004116 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004117 {
4118 Image
4119 *paint_image;
4120
4121 /*
4122 Oil-paint image.
4123 */
4124 if (msl_info->image[n] == (Image *) NULL)
4125 {
cristyb988fe72009-09-16 01:01:10 +00004126 ThrowMSLException(OptionError,"NoImagesDefined",
4127 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004128 break;
4129 }
4130 if (attributes != (const xmlChar **) NULL)
4131 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4132 {
4133 keyword=(const char *) attributes[i++];
4134 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004135 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004136 CloneString(&value,attribute);
4137 switch (*keyword)
4138 {
4139 case 'G':
4140 case 'g':
4141 {
4142 if (LocaleCompare(keyword,"geometry") == 0)
4143 {
4144 flags=ParseGeometry(value,&geometry_info);
4145 if ((flags & SigmaValue) == 0)
4146 geometry_info.sigma=1.0;
4147 break;
4148 }
4149 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4150 keyword);
4151 break;
4152 }
4153 case 'R':
4154 case 'r':
4155 {
4156 if (LocaleCompare(keyword,"radius") == 0)
4157 {
cristyc1acd842011-05-19 23:05:47 +00004158 geometry_info.rho=InterpretLocaleValue(value,
4159 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004160 break;
4161 }
4162 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4163 keyword);
4164 break;
4165 }
4166 default:
4167 {
4168 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4169 keyword);
4170 break;
4171 }
4172 }
4173 }
4174 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4175 &msl_info->image[n]->exception);
4176 if (paint_image == (Image *) NULL)
4177 break;
4178 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4179 msl_info->image[n]=paint_image;
4180 break;
4181 }
cristyb988fe72009-09-16 01:01:10 +00004182 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004183 {
cristy4c08aed2011-07-01 19:47:50 +00004184 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004185 fill_color,
4186 target;
4187
4188 /*
4189 Opaque image.
4190 */
4191 if (msl_info->image[n] == (Image *) NULL)
4192 {
cristyb988fe72009-09-16 01:01:10 +00004193 ThrowMSLException(OptionError,"NoImagesDefined",
4194 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004195 break;
4196 }
4197 (void) QueryMagickColor("none",&target,&exception);
4198 (void) QueryMagickColor("none",&fill_color,&exception);
4199 if (attributes != (const xmlChar **) NULL)
4200 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4201 {
4202 keyword=(const char *) attributes[i++];
4203 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004204 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004205 CloneString(&value,attribute);
4206 switch (*keyword)
4207 {
4208 case 'C':
4209 case 'c':
4210 {
4211 if (LocaleCompare(keyword,"channel") == 0)
4212 {
4213 option=ParseChannelOption(value);
4214 if (option < 0)
4215 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4216 value);
4217 channel=(ChannelType) option;
4218 break;
4219 }
4220 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4221 keyword);
4222 break;
4223 }
4224 case 'F':
4225 case 'f':
4226 {
4227 if (LocaleCompare(keyword,"fill") == 0)
4228 {
4229 (void) QueryMagickColor(value,&fill_color,&exception);
4230 break;
4231 }
4232 if (LocaleCompare(keyword,"fuzz") == 0)
4233 {
cristyc1acd842011-05-19 23:05:47 +00004234 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
4235 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004236 break;
4237 }
4238 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4239 keyword);
4240 break;
4241 }
4242 default:
4243 {
4244 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4245 keyword);
4246 break;
4247 }
4248 }
4249 }
4250 (void) OpaquePaintImageChannel(msl_info->image[n],channel,
4251 &target,&fill_color,MagickFalse);
4252 break;
4253 }
4254 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4255 }
4256 case 'P':
4257 case 'p':
4258 {
cristyb988fe72009-09-16 01:01:10 +00004259 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004260 {
4261 if (attributes == (const xmlChar **) NULL)
4262 break;
4263 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4264 {
4265 keyword=(const char *) attributes[i++];
4266 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004267 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004268 CloneString(&value,attribute);
4269 switch (*keyword)
4270 {
4271 case 'O':
4272 case 'o':
4273 {
4274 if (LocaleCompare(keyword,"output") == 0)
4275 {
cristyb51dff52011-05-19 16:55:47 +00004276 (void) FormatLocaleFile(stdout,"%s",value);
cristy3ed852e2009-09-05 21:47:34 +00004277 break;
4278 }
4279 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4280 break;
4281 }
4282 default:
4283 {
4284 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4285 break;
4286 }
4287 }
4288 }
4289 break;
4290 }
cristy4fa36e42009-09-18 14:24:06 +00004291 if (LocaleCompare((const char *) tag, "profile") == 0)
4292 {
cristy4fa36e42009-09-18 14:24:06 +00004293 if (msl_info->image[n] == (Image *) NULL)
4294 {
4295 ThrowMSLException(OptionError,"NoImagesDefined",
4296 (const char *) tag);
4297 break;
4298 }
4299 if (attributes == (const xmlChar **) NULL)
4300 break;
4301 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4302 {
4303 const char
4304 *name;
4305
4306 const StringInfo
4307 *profile;
4308
4309 Image
4310 *profile_image;
4311
4312 ImageInfo
4313 *profile_info;
4314
4315 keyword=(const char *) attributes[i++];
4316 attribute=InterpretImageProperties(msl_info->image_info[n],
4317 msl_info->attributes[n],(const char *) attributes[i]);
4318 CloneString(&value,attribute);
4319 if (*keyword == '+')
4320 {
4321 /*
4322 Remove a profile from the image.
4323 */
4324 (void) ProfileImage(msl_info->image[n],keyword,
4325 (const unsigned char *) NULL,0,MagickTrue);
4326 continue;
4327 }
4328 /*
4329 Associate a profile with the image.
4330 */
4331 profile_info=CloneImageInfo(msl_info->image_info[n]);
4332 profile=GetImageProfile(msl_info->image[n],"iptc");
4333 if (profile != (StringInfo *) NULL)
4334 profile_info->profile=(void *) CloneStringInfo(profile);
4335 profile_image=GetImageCache(profile_info,keyword,&exception);
4336 profile_info=DestroyImageInfo(profile_info);
4337 if (profile_image == (Image *) NULL)
4338 {
4339 char
4340 name[MaxTextExtent],
4341 filename[MaxTextExtent];
4342
4343 register char
4344 *p;
4345
4346 StringInfo
4347 *profile;
4348
4349 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4350 (void) CopyMagickString(name,keyword,MaxTextExtent);
4351 for (p=filename; *p != '\0'; p++)
4352 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4353 (IsPathAccessible(keyword) == MagickFalse))
4354 {
4355 register char
4356 *q;
4357
4358 /*
4359 Look for profile name (e.g. name:profile).
4360 */
4361 (void) CopyMagickString(name,filename,(size_t)
4362 (p-filename+1));
4363 for (q=filename; *q != '\0'; q++)
4364 *q=(*++p);
4365 break;
4366 }
4367 profile=FileToStringInfo(filename,~0UL,&exception);
4368 if (profile != (StringInfo *) NULL)
4369 {
4370 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004371 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004372 GetStringInfoLength(profile),MagickFalse);
4373 profile=DestroyStringInfo(profile);
4374 }
4375 continue;
4376 }
4377 ResetImageProfileIterator(profile_image);
4378 name=GetNextImageProfile(profile_image);
4379 while (name != (const char *) NULL)
4380 {
4381 profile=GetImageProfile(profile_image,name);
4382 if (profile != (StringInfo *) NULL)
4383 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004384 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004385 GetStringInfoLength(profile),MagickFalse);
4386 name=GetNextImageProfile(profile_image);
4387 }
4388 profile_image=DestroyImage(profile_image);
4389 }
4390 break;
4391 }
cristy3ed852e2009-09-05 21:47:34 +00004392 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4393 }
4394 case 'Q':
4395 case 'q':
4396 {
cristyb988fe72009-09-16 01:01:10 +00004397 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004398 {
4399 QuantizeInfo
4400 quantize_info;
4401
4402 /*
4403 Quantize image.
4404 */
4405 if (msl_info->image[n] == (Image *) NULL)
4406 {
cristyb988fe72009-09-16 01:01:10 +00004407 ThrowMSLException(OptionError,"NoImagesDefined",
4408 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004409 break;
4410 }
4411 GetQuantizeInfo(&quantize_info);
4412 if (attributes != (const xmlChar **) NULL)
4413 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4414 {
4415 keyword=(const char *) attributes[i++];
4416 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004417 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004418 CloneString(&value,attribute);
4419 switch (*keyword)
4420 {
4421 case 'C':
4422 case 'c':
4423 {
4424 if (LocaleCompare(keyword,"colors") == 0)
4425 {
cristyf2f27272009-12-17 14:48:46 +00004426 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004427 break;
4428 }
4429 if (LocaleCompare(keyword,"colorspace") == 0)
4430 {
cristy042ee782011-04-22 18:48:30 +00004431 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004432 MagickFalse,value);
4433 if (option < 0)
4434 ThrowMSLException(OptionError,
4435 "UnrecognizedColorspaceType",value);
4436 quantize_info.colorspace=(ColorspaceType) option;
4437 break;
4438 }
4439 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4440 keyword);
4441 break;
4442 }
4443 case 'D':
4444 case 'd':
4445 {
4446 if (LocaleCompare(keyword,"dither") == 0)
4447 {
cristy042ee782011-04-22 18:48:30 +00004448 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004449 value);
4450 if (option < 0)
4451 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4452 value);
4453 quantize_info.dither=(MagickBooleanType) option;
4454 break;
4455 }
4456 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4457 keyword);
4458 break;
4459 }
4460 case 'M':
4461 case 'm':
4462 {
4463 if (LocaleCompare(keyword,"measure") == 0)
4464 {
cristy042ee782011-04-22 18:48:30 +00004465 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004466 value);
4467 if (option < 0)
4468 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4469 value);
4470 quantize_info.measure_error=(MagickBooleanType) option;
4471 break;
4472 }
4473 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4474 keyword);
4475 break;
4476 }
4477 case 'T':
4478 case 't':
4479 {
4480 if (LocaleCompare(keyword,"treedepth") == 0)
4481 {
cristyf2f27272009-12-17 14:48:46 +00004482 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004483 break;
4484 }
4485 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4486 keyword);
4487 break;
4488 }
4489 default:
4490 {
4491 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4492 keyword);
4493 break;
4494 }
4495 }
4496 }
4497 (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4498 break;
4499 }
cristyb988fe72009-09-16 01:01:10 +00004500 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004501 {
4502 char
4503 text[MaxTextExtent];
4504
4505 MagickBooleanType
4506 status;
4507
4508 TypeMetric
4509 metrics;
4510
4511 /*
4512 Query font metrics.
4513 */
4514 draw_info=CloneDrawInfo(msl_info->image_info[n],
4515 msl_info->draw_info[n]);
4516 angle=0.0;
4517 current=draw_info->affine;
4518 GetAffineMatrix(&affine);
4519 if (attributes != (const xmlChar **) NULL)
4520 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4521 {
4522 keyword=(const char *) attributes[i++];
4523 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004524 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004525 CloneString(&value,attribute);
4526 switch (*keyword)
4527 {
4528 case 'A':
4529 case 'a':
4530 {
4531 if (LocaleCompare(keyword,"affine") == 0)
4532 {
4533 char
4534 *p;
4535
4536 p=value;
cristyc1acd842011-05-19 23:05:47 +00004537 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004538 if (*p ==',')
4539 p++;
cristyc1acd842011-05-19 23:05:47 +00004540 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004541 if (*p ==',')
4542 p++;
cristyc1acd842011-05-19 23:05:47 +00004543 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004544 if (*p ==',')
4545 p++;
cristyc1acd842011-05-19 23:05:47 +00004546 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004547 if (*p ==',')
4548 p++;
cristyc1acd842011-05-19 23:05:47 +00004549 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004550 if (*p ==',')
4551 p++;
cristyc1acd842011-05-19 23:05:47 +00004552 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004553 break;
4554 }
4555 if (LocaleCompare(keyword,"align") == 0)
4556 {
cristy042ee782011-04-22 18:48:30 +00004557 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004558 value);
4559 if (option < 0)
4560 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4561 value);
4562 draw_info->align=(AlignType) option;
4563 break;
4564 }
4565 if (LocaleCompare(keyword,"antialias") == 0)
4566 {
cristy042ee782011-04-22 18:48:30 +00004567 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004568 value);
4569 if (option < 0)
4570 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4571 value);
4572 draw_info->stroke_antialias=(MagickBooleanType) option;
4573 draw_info->text_antialias=(MagickBooleanType) option;
4574 break;
4575 }
4576 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4577 keyword);
4578 break;
4579 }
4580 case 'D':
4581 case 'd':
4582 {
4583 if (LocaleCompare(keyword,"density") == 0)
4584 {
4585 CloneString(&draw_info->density,value);
4586 break;
4587 }
4588 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4589 keyword);
4590 break;
4591 }
4592 case 'E':
4593 case 'e':
4594 {
4595 if (LocaleCompare(keyword,"encoding") == 0)
4596 {
4597 CloneString(&draw_info->encoding,value);
4598 break;
4599 }
4600 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4601 keyword);
4602 break;
4603 }
4604 case 'F':
4605 case 'f':
4606 {
4607 if (LocaleCompare(keyword, "fill") == 0)
4608 {
4609 (void) QueryColorDatabase(value,&draw_info->fill,
4610 &exception);
4611 break;
4612 }
4613 if (LocaleCompare(keyword,"family") == 0)
4614 {
4615 CloneString(&draw_info->family,value);
4616 break;
4617 }
4618 if (LocaleCompare(keyword,"font") == 0)
4619 {
4620 CloneString(&draw_info->font,value);
4621 break;
4622 }
4623 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4624 keyword);
4625 break;
4626 }
4627 case 'G':
4628 case 'g':
4629 {
4630 if (LocaleCompare(keyword,"geometry") == 0)
4631 {
4632 flags=ParsePageGeometry(msl_info->image[n],value,
4633 &geometry,&exception);
4634 if ((flags & HeightValue) == 0)
4635 geometry.height=geometry.width;
4636 break;
4637 }
4638 if (LocaleCompare(keyword,"gravity") == 0)
4639 {
cristy042ee782011-04-22 18:48:30 +00004640 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004641 value);
4642 if (option < 0)
4643 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4644 value);
4645 draw_info->gravity=(GravityType) option;
4646 break;
4647 }
4648 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4649 keyword);
4650 break;
4651 }
4652 case 'P':
4653 case 'p':
4654 {
4655 if (LocaleCompare(keyword,"pointsize") == 0)
4656 {
cristyc1acd842011-05-19 23:05:47 +00004657 draw_info->pointsize=InterpretLocaleValue(value,
4658 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004659 break;
4660 }
4661 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4662 keyword);
4663 break;
4664 }
4665 case 'R':
4666 case 'r':
4667 {
4668 if (LocaleCompare(keyword,"rotate") == 0)
4669 {
cristyc1acd842011-05-19 23:05:47 +00004670 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004671 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4672 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4673 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4674 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4675 break;
4676 }
4677 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4678 keyword);
4679 break;
4680 }
4681 case 'S':
4682 case 's':
4683 {
4684 if (LocaleCompare(keyword,"scale") == 0)
4685 {
4686 flags=ParseGeometry(value,&geometry_info);
4687 if ((flags & SigmaValue) == 0)
4688 geometry_info.sigma=1.0;
4689 affine.sx=geometry_info.rho;
4690 affine.sy=geometry_info.sigma;
4691 break;
4692 }
4693 if (LocaleCompare(keyword,"skewX") == 0)
4694 {
cristyc1acd842011-05-19 23:05:47 +00004695 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004696 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4697 break;
4698 }
4699 if (LocaleCompare(keyword,"skewY") == 0)
4700 {
cristyc1acd842011-05-19 23:05:47 +00004701 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004702 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4703 break;
4704 }
4705 if (LocaleCompare(keyword,"stretch") == 0)
4706 {
cristy042ee782011-04-22 18:48:30 +00004707 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004708 value);
4709 if (option < 0)
4710 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4711 value);
4712 draw_info->stretch=(StretchType) option;
4713 break;
4714 }
4715 if (LocaleCompare(keyword, "stroke") == 0)
4716 {
4717 (void) QueryColorDatabase(value,&draw_info->stroke,
4718 &exception);
4719 break;
4720 }
4721 if (LocaleCompare(keyword,"strokewidth") == 0)
4722 {
cristyf2f27272009-12-17 14:48:46 +00004723 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004724 break;
4725 }
4726 if (LocaleCompare(keyword,"style") == 0)
4727 {
cristy042ee782011-04-22 18:48:30 +00004728 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004729 value);
4730 if (option < 0)
4731 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4732 value);
4733 draw_info->style=(StyleType) option;
4734 break;
4735 }
4736 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4737 keyword);
4738 break;
4739 }
4740 case 'T':
4741 case 't':
4742 {
4743 if (LocaleCompare(keyword,"text") == 0)
4744 {
4745 CloneString(&draw_info->text,value);
4746 break;
4747 }
4748 if (LocaleCompare(keyword,"translate") == 0)
4749 {
4750 flags=ParseGeometry(value,&geometry_info);
4751 if ((flags & SigmaValue) == 0)
4752 geometry_info.sigma=1.0;
4753 affine.tx=geometry_info.rho;
4754 affine.ty=geometry_info.sigma;
4755 break;
4756 }
4757 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4758 keyword);
4759 break;
4760 }
4761 case 'U':
4762 case 'u':
4763 {
4764 if (LocaleCompare(keyword, "undercolor") == 0)
4765 {
4766 (void) QueryColorDatabase(value,&draw_info->undercolor,
4767 &exception);
4768 break;
4769 }
4770 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4771 keyword);
4772 break;
4773 }
4774 case 'W':
4775 case 'w':
4776 {
4777 if (LocaleCompare(keyword,"weight") == 0)
4778 {
cristyf2f27272009-12-17 14:48:46 +00004779 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004780 break;
4781 }
4782 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4783 keyword);
4784 break;
4785 }
4786 case 'X':
4787 case 'x':
4788 {
4789 if (LocaleCompare(keyword,"x") == 0)
4790 {
cristyf2f27272009-12-17 14:48:46 +00004791 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004792 break;
4793 }
4794 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4795 keyword);
4796 break;
4797 }
4798 case 'Y':
4799 case 'y':
4800 {
4801 if (LocaleCompare(keyword,"y") == 0)
4802 {
cristyf2f27272009-12-17 14:48:46 +00004803 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004804 break;
4805 }
4806 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4807 keyword);
4808 break;
4809 }
4810 default:
4811 {
4812 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4813 keyword);
4814 break;
4815 }
4816 }
4817 }
cristyb51dff52011-05-19 16:55:47 +00004818 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00004819 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4820 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004821 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004822 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4823 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4824 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4825 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4826 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4827 affine.tx;
4828 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4829 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00004830 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4831 if (status != MagickFalse)
4832 {
4833 Image
4834 *image;
4835
4836 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004837 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004838 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004839 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004840 "%g",metrics.pixels_per_em.y);
4841 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004842 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004843 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004844 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004845 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004846 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004847 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004848 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004849 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004850 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004851 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004852 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004853 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004854 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004855 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004856 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004857 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004858 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004859 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004860 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004861 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004862 metrics.origin.y);
4863 }
4864 draw_info=DestroyDrawInfo(draw_info);
4865 break;
4866 }
4867 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4868 }
4869 case 'R':
4870 case 'r':
4871 {
cristyb988fe72009-09-16 01:01:10 +00004872 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004873 {
4874 MagickBooleanType
4875 raise;
4876
4877 /*
4878 Raise image.
4879 */
4880 if (msl_info->image[n] == (Image *) NULL)
4881 {
cristyb988fe72009-09-16 01:01:10 +00004882 ThrowMSLException(OptionError,"NoImagesDefined",
4883 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004884 break;
4885 }
4886 raise=MagickFalse;
4887 SetGeometry(msl_info->image[n],&geometry);
4888 if (attributes != (const xmlChar **) NULL)
4889 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4890 {
4891 keyword=(const char *) attributes[i++];
4892 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004893 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004894 CloneString(&value,attribute);
4895 switch (*keyword)
4896 {
4897 case 'G':
4898 case 'g':
4899 {
4900 if (LocaleCompare(keyword,"geometry") == 0)
4901 {
4902 flags=ParsePageGeometry(msl_info->image[n],value,
4903 &geometry,&exception);
4904 if ((flags & HeightValue) == 0)
4905 geometry.height=geometry.width;
4906 break;
4907 }
4908 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4909 keyword);
4910 break;
4911 }
4912 case 'H':
4913 case 'h':
4914 {
4915 if (LocaleCompare(keyword,"height") == 0)
4916 {
cristyf2f27272009-12-17 14:48:46 +00004917 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004918 break;
4919 }
4920 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4921 keyword);
4922 break;
4923 }
4924 case 'R':
4925 case 'r':
4926 {
4927 if (LocaleCompare(keyword,"raise") == 0)
4928 {
cristy042ee782011-04-22 18:48:30 +00004929 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004930 value);
4931 if (option < 0)
4932 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4933 value);
4934 raise=(MagickBooleanType) option;
4935 break;
4936 }
4937 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4938 keyword);
4939 break;
4940 }
4941 case 'W':
4942 case 'w':
4943 {
4944 if (LocaleCompare(keyword,"width") == 0)
4945 {
cristyf2f27272009-12-17 14:48:46 +00004946 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004947 break;
4948 }
4949 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4950 keyword);
4951 break;
4952 }
4953 default:
4954 {
4955 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4956 keyword);
4957 break;
4958 }
4959 }
4960 }
4961 (void) RaiseImage(msl_info->image[n],&geometry,raise);
4962 break;
4963 }
cristyb988fe72009-09-16 01:01:10 +00004964 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004965 {
4966 if (attributes == (const xmlChar **) NULL)
4967 break;
4968 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4969 {
4970 keyword=(const char *) attributes[i++];
4971 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004972 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00004973 switch (*keyword)
4974 {
4975 case 'F':
4976 case 'f':
4977 {
4978 if (LocaleCompare(keyword,"filename") == 0)
4979 {
4980 Image
4981 *image;
4982
4983 (void) CopyMagickString(msl_info->image_info[n]->filename,
4984 value,MaxTextExtent);
4985 image=ReadImage(msl_info->image_info[n],&exception);
4986 CatchException(&exception);
4987 if (image == (Image *) NULL)
4988 continue;
4989 AppendImageToList(&msl_info->image[n],image);
4990 break;
4991 }
cristy4582cbb2009-09-23 00:35:43 +00004992 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004993 break;
4994 }
4995 default:
4996 {
cristy4582cbb2009-09-23 00:35:43 +00004997 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004998 break;
4999 }
5000 }
5001 }
5002 break;
5003 }
cristyb988fe72009-09-16 01:01:10 +00005004 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005005 {
5006 Image
5007 *paint_image;
5008
5009 /*
5010 Reduce-noise image.
5011 */
5012 if (msl_info->image[n] == (Image *) NULL)
5013 {
cristyb988fe72009-09-16 01:01:10 +00005014 ThrowMSLException(OptionError,"NoImagesDefined",
5015 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005016 break;
5017 }
5018 if (attributes != (const xmlChar **) NULL)
5019 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5020 {
5021 keyword=(const char *) attributes[i++];
5022 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005023 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005024 CloneString(&value,attribute);
5025 switch (*keyword)
5026 {
5027 case 'G':
5028 case 'g':
5029 {
5030 if (LocaleCompare(keyword,"geometry") == 0)
5031 {
5032 flags=ParseGeometry(value,&geometry_info);
5033 if ((flags & SigmaValue) == 0)
5034 geometry_info.sigma=1.0;
5035 break;
5036 }
5037 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5038 keyword);
5039 break;
5040 }
5041 case 'R':
5042 case 'r':
5043 {
5044 if (LocaleCompare(keyword,"radius") == 0)
5045 {
cristyc1acd842011-05-19 23:05:47 +00005046 geometry_info.rho=InterpretLocaleValue(value,
5047 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005048 break;
5049 }
5050 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5051 keyword);
5052 break;
5053 }
5054 default:
5055 {
5056 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5057 keyword);
5058 break;
5059 }
5060 }
5061 }
cristy733678d2011-03-18 21:29:28 +00005062 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005063 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5064 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00005065 if (paint_image == (Image *) NULL)
5066 break;
5067 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5068 msl_info->image[n]=paint_image;
5069 break;
5070 }
cristyb988fe72009-09-16 01:01:10 +00005071 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005072 {
5073 /* init the values */
5074 width=msl_info->image[n]->page.width;
5075 height=msl_info->image[n]->page.height;
5076 x=msl_info->image[n]->page.x;
5077 y=msl_info->image[n]->page.y;
5078
5079 if (msl_info->image[n] == (Image *) NULL)
5080 {
cristyb988fe72009-09-16 01:01:10 +00005081 ThrowMSLException(OptionError,"NoImagesDefined",
5082 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005083 break;
5084 }
5085 if (attributes == (const xmlChar **) NULL)
5086 break;
5087 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5088 {
5089 keyword=(const char *) attributes[i++];
5090 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005091 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005092 switch (*keyword)
5093 {
5094 case 'G':
5095 case 'g':
5096 {
5097 if (LocaleCompare(keyword,"geometry") == 0)
5098 {
5099 int
5100 flags;
5101
5102 RectangleInfo
5103 geometry;
5104
5105 flags=ParseAbsoluteGeometry(value,&geometry);
5106 if ((flags & WidthValue) != 0)
5107 {
5108 if ((flags & HeightValue) == 0)
5109 geometry.height=geometry.width;
5110 width=geometry.width;
5111 height=geometry.height;
5112 }
5113 if ((flags & AspectValue) != 0)
5114 {
5115 if ((flags & XValue) != 0)
5116 x+=geometry.x;
5117 if ((flags & YValue) != 0)
5118 y+=geometry.y;
5119 }
5120 else
5121 {
5122 if ((flags & XValue) != 0)
5123 {
5124 x=geometry.x;
5125 if ((width == 0) && (geometry.x > 0))
5126 width=msl_info->image[n]->columns+geometry.x;
5127 }
5128 if ((flags & YValue) != 0)
5129 {
5130 y=geometry.y;
5131 if ((height == 0) && (geometry.y > 0))
5132 height=msl_info->image[n]->rows+geometry.y;
5133 }
5134 }
5135 break;
5136 }
5137 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5138 break;
5139 }
5140 case 'H':
5141 case 'h':
5142 {
5143 if (LocaleCompare(keyword,"height") == 0)
5144 {
cristyf2f27272009-12-17 14:48:46 +00005145 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005146 break;
5147 }
5148 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5149 break;
5150 }
5151 case 'W':
5152 case 'w':
5153 {
5154 if (LocaleCompare(keyword,"width") == 0)
5155 {
cristyf2f27272009-12-17 14:48:46 +00005156 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005157 break;
5158 }
5159 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5160 break;
5161 }
5162 case 'X':
5163 case 'x':
5164 {
5165 if (LocaleCompare(keyword,"x") == 0)
5166 {
cristyf2f27272009-12-17 14:48:46 +00005167 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005168 break;
5169 }
5170 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5171 break;
5172 }
5173 case 'Y':
5174 case 'y':
5175 {
5176 if (LocaleCompare(keyword,"y") == 0)
5177 {
cristyf2f27272009-12-17 14:48:46 +00005178 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005179 break;
5180 }
5181 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5182 break;
5183 }
5184 default:
5185 {
5186 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5187 break;
5188 }
5189 }
5190 }
5191
cristyb988fe72009-09-16 01:01:10 +00005192 msl_info->image[n]->page.width=width;
5193 msl_info->image[n]->page.height=height;
5194 msl_info->image[n]->page.x=x;
5195 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005196 break;
5197 }
cristyb988fe72009-09-16 01:01:10 +00005198 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005199 {
5200 double
5201 x_resolution,
5202 y_resolution;
5203
5204 if (msl_info->image[n] == (Image *) NULL)
5205 {
cristyb988fe72009-09-16 01:01:10 +00005206 ThrowMSLException(OptionError,"NoImagesDefined",
5207 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005208 break;
5209 }
5210 if (attributes == (const xmlChar **) NULL)
5211 break;
5212 x_resolution=DefaultResolution;
5213 y_resolution=DefaultResolution;
5214 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5215 {
5216 keyword=(const char *) attributes[i++];
5217 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005218 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005219 switch (*keyword)
5220 {
5221 case 'b':
5222 {
5223 if (LocaleCompare(keyword,"blur") == 0)
5224 {
cristyc1acd842011-05-19 23:05:47 +00005225 msl_info->image[n]->blur=InterpretLocaleValue(value,
5226 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005227 break;
5228 }
5229 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5230 break;
5231 }
5232 case 'G':
5233 case 'g':
5234 {
5235 if (LocaleCompare(keyword,"geometry") == 0)
5236 {
cristybb503372010-05-27 20:51:26 +00005237 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005238 flags;
5239
5240 flags=ParseGeometry(value,&geometry_info);
5241 if ((flags & SigmaValue) == 0)
5242 geometry_info.sigma*=geometry_info.rho;
5243 x_resolution=geometry_info.rho;
5244 y_resolution=geometry_info.sigma;
5245 break;
5246 }
5247 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5248 break;
5249 }
5250 case 'X':
5251 case 'x':
5252 {
5253 if (LocaleCompare(keyword,"x-resolution") == 0)
5254 {
cristyc1acd842011-05-19 23:05:47 +00005255 x_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005256 break;
5257 }
5258 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5259 break;
5260 }
5261 case 'Y':
5262 case 'y':
5263 {
5264 if (LocaleCompare(keyword,"y-resolution") == 0)
5265 {
cristyc1acd842011-05-19 23:05:47 +00005266 y_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005267 break;
5268 }
5269 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5270 break;
5271 }
5272 default:
5273 {
5274 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5275 break;
5276 }
5277 }
5278 }
5279 /*
5280 Resample image.
5281 */
5282 {
5283 double
5284 factor;
5285
5286 Image
5287 *resample_image;
5288
5289 factor=1.0;
5290 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5291 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005292 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy3ed852e2009-09-05 21:47:34 +00005293 (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5294 msl_info->image[n]->x_resolution))+0.5);
cristybb503372010-05-27 20:51:26 +00005295 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy3ed852e2009-09-05 21:47:34 +00005296 (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5297 msl_info->image[n]->y_resolution))+0.5);
5298 resample_image=ResizeImage(msl_info->image[n],width,height,
5299 msl_info->image[n]->filter,msl_info->image[n]->blur,
5300 &msl_info->image[n]->exception);
5301 if (resample_image == (Image *) NULL)
5302 break;
5303 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5304 msl_info->image[n]=resample_image;
5305 }
5306 break;
5307 }
cristyb988fe72009-09-16 01:01:10 +00005308 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005309 {
5310 double
5311 blur;
5312
5313 FilterTypes
5314 filter;
5315
5316 Image
5317 *resize_image;
5318
5319 /*
5320 Resize image.
5321 */
5322 if (msl_info->image[n] == (Image *) NULL)
5323 {
cristyb988fe72009-09-16 01:01:10 +00005324 ThrowMSLException(OptionError,"NoImagesDefined",
5325 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005326 break;
5327 }
5328 filter=UndefinedFilter;
5329 blur=1.0;
5330 if (attributes != (const xmlChar **) NULL)
5331 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5332 {
5333 keyword=(const char *) attributes[i++];
5334 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005335 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005336 CloneString(&value,attribute);
5337 switch (*keyword)
5338 {
5339 case 'F':
5340 case 'f':
5341 {
5342 if (LocaleCompare(keyword,"filter") == 0)
5343 {
cristy042ee782011-04-22 18:48:30 +00005344 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005345 value);
5346 if (option < 0)
5347 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5348 value);
5349 filter=(FilterTypes) option;
5350 break;
5351 }
5352 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5353 keyword);
5354 break;
5355 }
5356 case 'G':
5357 case 'g':
5358 {
5359 if (LocaleCompare(keyword,"geometry") == 0)
5360 {
5361 flags=ParseRegionGeometry(msl_info->image[n],value,
5362 &geometry,&exception);
5363 break;
5364 }
5365 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5366 keyword);
5367 break;
5368 }
5369 case 'H':
5370 case 'h':
5371 {
5372 if (LocaleCompare(keyword,"height") == 0)
5373 {
cristye27293e2009-12-18 02:53:20 +00005374 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005375 break;
5376 }
5377 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5378 keyword);
5379 break;
5380 }
5381 case 'S':
5382 case 's':
5383 {
5384 if (LocaleCompare(keyword,"support") == 0)
5385 {
cristyc1acd842011-05-19 23:05:47 +00005386 blur=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005387 break;
5388 }
5389 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5390 keyword);
5391 break;
5392 }
5393 case 'W':
5394 case 'w':
5395 {
5396 if (LocaleCompare(keyword,"width") == 0)
5397 {
cristyf2f27272009-12-17 14:48:46 +00005398 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005399 break;
5400 }
5401 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5402 keyword);
5403 break;
5404 }
5405 default:
5406 {
5407 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5408 keyword);
5409 break;
5410 }
5411 }
5412 }
5413 resize_image=ResizeImage(msl_info->image[n],geometry.width,
5414 geometry.height,filter,blur,&msl_info->image[n]->exception);
5415 if (resize_image == (Image *) NULL)
5416 break;
5417 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5418 msl_info->image[n]=resize_image;
5419 break;
5420 }
cristyb988fe72009-09-16 01:01:10 +00005421 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005422 {
5423 Image
5424 *roll_image;
5425
5426 /*
5427 Roll image.
5428 */
5429 if (msl_info->image[n] == (Image *) NULL)
5430 {
cristyb988fe72009-09-16 01:01:10 +00005431 ThrowMSLException(OptionError,"NoImagesDefined",
5432 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005433 break;
5434 }
5435 SetGeometry(msl_info->image[n],&geometry);
5436 if (attributes != (const xmlChar **) NULL)
5437 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5438 {
5439 keyword=(const char *) attributes[i++];
5440 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005441 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005442 CloneString(&value,attribute);
5443 switch (*keyword)
5444 {
5445 case 'G':
5446 case 'g':
5447 {
5448 if (LocaleCompare(keyword,"geometry") == 0)
5449 {
5450 flags=ParsePageGeometry(msl_info->image[n],value,
5451 &geometry,&exception);
5452 if ((flags & HeightValue) == 0)
5453 geometry.height=geometry.width;
5454 break;
5455 }
5456 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5457 keyword);
5458 break;
5459 }
5460 case 'X':
5461 case 'x':
5462 {
5463 if (LocaleCompare(keyword,"x") == 0)
5464 {
cristyf2f27272009-12-17 14:48:46 +00005465 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005466 break;
5467 }
5468 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5469 keyword);
5470 break;
5471 }
5472 case 'Y':
5473 case 'y':
5474 {
5475 if (LocaleCompare(keyword,"y") == 0)
5476 {
cristyf2f27272009-12-17 14:48:46 +00005477 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005478 break;
5479 }
5480 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5481 keyword);
5482 break;
5483 }
5484 default:
5485 {
5486 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5487 keyword);
5488 break;
5489 }
5490 }
5491 }
5492 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5493 &msl_info->image[n]->exception);
5494 if (roll_image == (Image *) NULL)
5495 break;
5496 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5497 msl_info->image[n]=roll_image;
5498 break;
5499 }
cristyb988fe72009-09-16 01:01:10 +00005500 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005501 {
5502 /* init the values */
5503 width=msl_info->image[n]->columns;
5504 height=msl_info->image[n]->rows;
5505 x = y = 0;
5506
5507 if (msl_info->image[n] == (Image *) NULL)
5508 {
cristyb988fe72009-09-16 01:01:10 +00005509 ThrowMSLException(OptionError,"NoImagesDefined",
5510 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005511 break;
5512 }
5513 if (attributes == (const xmlChar **) NULL)
5514 break;
5515 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5516 {
5517 keyword=(const char *) attributes[i++];
5518 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005519 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005520 switch (*keyword)
5521 {
5522 case 'G':
5523 case 'g':
5524 {
5525 if (LocaleCompare(keyword,"geometry") == 0)
5526 {
5527 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5528 break;
5529 }
5530 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5531 break;
5532 }
5533 case 'X':
5534 case 'x':
5535 {
5536 if (LocaleCompare(keyword,"x") == 0)
5537 {
cristyf2f27272009-12-17 14:48:46 +00005538 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005539 break;
5540 }
5541 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5542 break;
5543 }
5544 case 'Y':
5545 case 'y':
5546 {
5547 if (LocaleCompare(keyword,"y") == 0)
5548 {
cristyf2f27272009-12-17 14:48:46 +00005549 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005550 break;
5551 }
5552 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5553 break;
5554 }
5555 default:
5556 {
5557 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5558 break;
5559 }
5560 }
5561 }
5562
5563 /*
5564 process image.
5565 */
5566 {
5567 Image
5568 *newImage;
5569
5570 newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5571 if (newImage == (Image *) NULL)
5572 break;
5573 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5574 msl_info->image[n]=newImage;
5575 }
5576
5577 break;
5578 }
cristyb988fe72009-09-16 01:01:10 +00005579 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005580 {
5581 Image
5582 *rotate_image;
5583
5584 /*
5585 Rotate image.
5586 */
5587 if (msl_info->image[n] == (Image *) NULL)
5588 {
cristyb988fe72009-09-16 01:01:10 +00005589 ThrowMSLException(OptionError,"NoImagesDefined",
5590 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005591 break;
5592 }
5593 if (attributes != (const xmlChar **) NULL)
5594 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5595 {
5596 keyword=(const char *) attributes[i++];
5597 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005598 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005599 CloneString(&value,attribute);
5600 switch (*keyword)
5601 {
5602 case 'D':
5603 case 'd':
5604 {
5605 if (LocaleCompare(keyword,"degrees") == 0)
5606 {
cristyc1acd842011-05-19 23:05:47 +00005607 geometry_info.rho=InterpretLocaleValue(value,
5608 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005609 break;
5610 }
5611 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5612 keyword);
5613 break;
5614 }
5615 case 'G':
5616 case 'g':
5617 {
5618 if (LocaleCompare(keyword,"geometry") == 0)
5619 {
5620 flags=ParseGeometry(value,&geometry_info);
5621 if ((flags & SigmaValue) == 0)
5622 geometry_info.sigma=1.0;
5623 break;
5624 }
5625 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5626 keyword);
5627 break;
5628 }
5629 default:
5630 {
5631 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5632 keyword);
5633 break;
5634 }
5635 }
5636 }
5637 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5638 &msl_info->image[n]->exception);
5639 if (rotate_image == (Image *) NULL)
5640 break;
5641 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5642 msl_info->image[n]=rotate_image;
5643 break;
5644 }
cristyb988fe72009-09-16 01:01:10 +00005645 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005646 {
5647 /* init the values */
5648 double degrees = 0;
5649
5650 if (msl_info->image[n] == (Image *) NULL)
5651 {
cristyb988fe72009-09-16 01:01:10 +00005652 ThrowMSLException(OptionError,"NoImagesDefined",
5653 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005654 break;
5655 }
5656 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005657 break;
cristy3ed852e2009-09-05 21:47:34 +00005658 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5659 {
5660 keyword=(const char *) attributes[i++];
5661 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005662 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005663 switch (*keyword)
5664 {
5665 case 'D':
5666 case 'd':
5667 {
5668 if (LocaleCompare(keyword,"degrees") == 0)
5669 {
cristyc1acd842011-05-19 23:05:47 +00005670 degrees = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005671 break;
5672 }
5673 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5674 break;
5675 }
5676 default:
5677 {
5678 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5679 break;
5680 }
5681 }
5682 }
5683
5684 /*
5685 process image.
5686 */
5687 {
5688 Image
5689 *newImage;
5690
5691 newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5692 if (newImage == (Image *) NULL)
5693 break;
5694 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5695 msl_info->image[n]=newImage;
5696 }
5697
5698 break;
5699 }
5700 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5701 }
5702 case 'S':
5703 case 's':
5704 {
cristyb988fe72009-09-16 01:01:10 +00005705 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005706 {
5707 Image
5708 *sample_image;
5709
5710 /*
5711 Sample image.
5712 */
5713 if (msl_info->image[n] == (Image *) NULL)
5714 {
cristyb988fe72009-09-16 01:01:10 +00005715 ThrowMSLException(OptionError,"NoImagesDefined",
5716 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005717 break;
5718 }
5719 if (attributes != (const xmlChar **) NULL)
5720 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5721 {
5722 keyword=(const char *) attributes[i++];
5723 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005724 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005725 CloneString(&value,attribute);
5726 switch (*keyword)
5727 {
5728 case 'G':
5729 case 'g':
5730 {
5731 if (LocaleCompare(keyword,"geometry") == 0)
5732 {
5733 flags=ParseRegionGeometry(msl_info->image[n],value,
5734 &geometry,&exception);
5735 break;
5736 }
5737 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5738 keyword);
5739 break;
5740 }
5741 case 'H':
5742 case 'h':
5743 {
5744 if (LocaleCompare(keyword,"height") == 0)
5745 {
cristye27293e2009-12-18 02:53:20 +00005746 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005747 break;
5748 }
5749 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5750 keyword);
5751 break;
5752 }
5753 case 'W':
5754 case 'w':
5755 {
5756 if (LocaleCompare(keyword,"width") == 0)
5757 {
cristyf2f27272009-12-17 14:48:46 +00005758 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005759 break;
5760 }
5761 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5762 keyword);
5763 break;
5764 }
5765 default:
5766 {
5767 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5768 keyword);
5769 break;
5770 }
5771 }
5772 }
5773 sample_image=SampleImage(msl_info->image[n],geometry.width,
5774 geometry.height,&msl_info->image[n]->exception);
5775 if (sample_image == (Image *) NULL)
5776 break;
5777 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5778 msl_info->image[n]=sample_image;
5779 break;
5780 }
cristyb988fe72009-09-16 01:01:10 +00005781 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005782 {
5783 Image
5784 *scale_image;
5785
5786 /*
5787 Scale image.
5788 */
5789 if (msl_info->image[n] == (Image *) NULL)
5790 {
cristyb988fe72009-09-16 01:01:10 +00005791 ThrowMSLException(OptionError,"NoImagesDefined",
5792 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005793 break;
5794 }
5795 if (attributes != (const xmlChar **) NULL)
5796 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5797 {
5798 keyword=(const char *) attributes[i++];
5799 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005800 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005801 CloneString(&value,attribute);
5802 switch (*keyword)
5803 {
5804 case 'G':
5805 case 'g':
5806 {
5807 if (LocaleCompare(keyword,"geometry") == 0)
5808 {
5809 flags=ParseRegionGeometry(msl_info->image[n],value,
5810 &geometry,&exception);
5811 break;
5812 }
5813 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5814 keyword);
5815 break;
5816 }
5817 case 'H':
5818 case 'h':
5819 {
5820 if (LocaleCompare(keyword,"height") == 0)
5821 {
cristye27293e2009-12-18 02:53:20 +00005822 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005823 break;
5824 }
5825 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5826 keyword);
5827 break;
5828 }
5829 case 'W':
5830 case 'w':
5831 {
5832 if (LocaleCompare(keyword,"width") == 0)
5833 {
cristyf2f27272009-12-17 14:48:46 +00005834 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005835 break;
5836 }
5837 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5838 keyword);
5839 break;
5840 }
5841 default:
5842 {
5843 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5844 keyword);
5845 break;
5846 }
5847 }
5848 }
5849 scale_image=ScaleImage(msl_info->image[n],geometry.width,
5850 geometry.height,&msl_info->image[n]->exception);
5851 if (scale_image == (Image *) NULL)
5852 break;
5853 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5854 msl_info->image[n]=scale_image;
5855 break;
5856 }
cristyb988fe72009-09-16 01:01:10 +00005857 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005858 {
5859 ColorspaceType
5860 colorspace;
5861
5862 MagickBooleanType
5863 verbose;
cristyb988fe72009-09-16 01:01:10 +00005864
cristy3ed852e2009-09-05 21:47:34 +00005865 /*
5866 Segment image.
5867 */
5868 if (msl_info->image[n] == (Image *) NULL)
5869 {
cristyb988fe72009-09-16 01:01:10 +00005870 ThrowMSLException(OptionError,"NoImagesDefined",
5871 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005872 break;
5873 }
5874 geometry_info.rho=1.0;
5875 geometry_info.sigma=1.5;
5876 colorspace=RGBColorspace;
5877 verbose=MagickFalse;
5878 if (attributes != (const xmlChar **) NULL)
5879 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5880 {
5881 keyword=(const char *) attributes[i++];
5882 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005883 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005884 CloneString(&value,attribute);
5885 switch (*keyword)
5886 {
5887 case 'C':
5888 case 'c':
5889 {
5890 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5891 {
cristyc1acd842011-05-19 23:05:47 +00005892 geometry_info.rho=InterpretLocaleValue(value,
5893 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005894 break;
5895 }
5896 if (LocaleCompare(keyword,"colorspace") == 0)
5897 {
cristy042ee782011-04-22 18:48:30 +00005898 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005899 MagickFalse,value);
5900 if (option < 0)
5901 ThrowMSLException(OptionError,
5902 "UnrecognizedColorspaceType",value);
5903 colorspace=(ColorspaceType) option;
5904 break;
5905 }
5906 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5907 keyword);
5908 break;
5909 }
5910 case 'G':
5911 case 'g':
5912 {
5913 if (LocaleCompare(keyword,"geometry") == 0)
5914 {
5915 flags=ParseGeometry(value,&geometry_info);
5916 if ((flags & SigmaValue) == 0)
5917 geometry_info.sigma=1.5;
5918 break;
5919 }
5920 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5921 keyword);
5922 break;
5923 }
5924 case 'S':
5925 case 's':
5926 {
5927 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5928 {
cristyc1acd842011-05-19 23:05:47 +00005929 geometry_info.sigma=InterpretLocaleValue(value,
5930 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005931 break;
5932 }
5933 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5934 keyword);
5935 break;
5936 }
5937 default:
5938 {
5939 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5940 keyword);
5941 break;
5942 }
5943 }
5944 }
5945 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5946 geometry_info.rho,geometry_info.sigma);
5947 break;
5948 }
cristyb988fe72009-09-16 01:01:10 +00005949 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005950 {
5951 if (msl_info->image[n] == (Image *) NULL)
5952 {
cristyb988fe72009-09-16 01:01:10 +00005953 ThrowMSLException(OptionError,"NoImagesDefined",
5954 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005955 break;
5956 }
5957
5958 if (attributes == (const xmlChar **) NULL)
5959 break;
5960 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5961 {
5962 keyword=(const char *) attributes[i++];
5963 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005964 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005965 switch (*keyword)
5966 {
cristy3ed852e2009-09-05 21:47:34 +00005967 case 'C':
5968 case 'c':
5969 {
5970 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005971 {
cristy2c8b6312009-09-16 02:37:23 +00005972 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005973 {
cristy2c8b6312009-09-16 02:37:23 +00005974 const char
5975 *property;
5976
5977 property=GetImageProperty(msl_info->attributes[j],"id");
5978 if (LocaleCompare(property,value) == 0)
5979 {
5980 SetImageMask(msl_info->image[n],msl_info->image[j]);
5981 break;
5982 }
cristy3ed852e2009-09-05 21:47:34 +00005983 }
cristy2c8b6312009-09-16 02:37:23 +00005984 break;
cristy3ed852e2009-09-05 21:47:34 +00005985 }
cristy3ed852e2009-09-05 21:47:34 +00005986 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005987 {
cristy2c8b6312009-09-16 02:37:23 +00005988 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005989 {
cristy2c8b6312009-09-16 02:37:23 +00005990 const char
5991 *property;
5992
5993 property=GetImageProperty(msl_info->attributes[j],"id");
5994 if (LocaleCompare(property,value) == 0)
5995 {
5996 SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5997 break;
5998 }
cristy3ed852e2009-09-05 21:47:34 +00005999 }
cristy2c8b6312009-09-16 02:37:23 +00006000 break;
cristy3ed852e2009-09-05 21:47:34 +00006001 }
cristy2c8b6312009-09-16 02:37:23 +00006002 if (LocaleCompare(keyword,"colorspace") == 0)
6003 {
cristybb503372010-05-27 20:51:26 +00006004 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00006005 colorspace;
6006
cristy042ee782011-04-22 18:48:30 +00006007 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00006008 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00006009 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00006010 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00006011 value);
6012 (void) TransformImageColorspace(msl_info->image[n],
6013 (ColorspaceType) colorspace);
6014 break;
6015 }
6016 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006017 break;
6018 }
6019 case 'D':
6020 case 'd':
6021 {
cristy2c8b6312009-09-16 02:37:23 +00006022 if (LocaleCompare(keyword,"density") == 0)
6023 {
6024 flags=ParseGeometry(value,&geometry_info);
6025 msl_info->image[n]->x_resolution=geometry_info.rho;
6026 msl_info->image[n]->y_resolution=geometry_info.sigma;
6027 if ((flags & SigmaValue) == 0)
6028 msl_info->image[n]->y_resolution=
6029 msl_info->image[n]->x_resolution;
6030 break;
6031 }
6032 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006033 break;
6034 }
6035 case 'O':
6036 case 'o':
6037 {
6038 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006039 {
cristy4c08aed2011-07-01 19:47:50 +00006040 ssize_t opac = OpaqueAlpha,
cristybb503372010-05-27 20:51:26 +00006041 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006042
cristy2c8b6312009-09-16 02:37:23 +00006043 if (value[len-1] == '%') {
6044 char tmp[100];
6045 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006046 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006047 opac = (int)(QuantumRange * ((float)opac/100));
6048 } else
cristyf2f27272009-12-17 14:48:46 +00006049 opac = StringToLong( value );
cristy2c8b6312009-09-16 02:37:23 +00006050 (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6051 break;
cristy3ed852e2009-09-05 21:47:34 +00006052 }
cristy2c8b6312009-09-16 02:37:23 +00006053 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006054 break;
6055 }
6056 case 'P':
6057 case 'p':
6058 {
6059 if (LocaleCompare(keyword, "page") == 0)
6060 {
6061 char
6062 page[MaxTextExtent];
6063
6064 const char
6065 *image_option;
6066
6067 MagickStatusType
6068 flags;
6069
6070 RectangleInfo
6071 geometry;
6072
6073 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6074 image_option=GetImageOption(msl_info->image_info[n],"page");
6075 if (image_option != (const char *) NULL)
6076 flags=ParseAbsoluteGeometry(image_option,&geometry);
6077 flags=ParseAbsoluteGeometry(value,&geometry);
cristyb51dff52011-05-19 16:55:47 +00006078 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
cristye8c25f92010-06-03 00:53:06 +00006079 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006080 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristyb51dff52011-05-19 16:55:47 +00006081 (void) FormatLocaleString(page,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00006082 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6083 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006084 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006085 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6086 msl_info->image_info[n]->page=GetPageGeometry(page);
6087 break;
6088 }
cristy2c8b6312009-09-16 02:37:23 +00006089 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006090 break;
6091 }
6092 default:
6093 {
cristy2c8b6312009-09-16 02:37:23 +00006094 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006095 break;
6096 }
6097 }
6098 }
6099 break;
6100 }
cristyb988fe72009-09-16 01:01:10 +00006101 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006102 {
6103 Image
6104 *shade_image;
6105
6106 MagickBooleanType
6107 gray;
6108
6109 /*
6110 Shade image.
6111 */
6112 if (msl_info->image[n] == (Image *) NULL)
6113 {
cristyb988fe72009-09-16 01:01:10 +00006114 ThrowMSLException(OptionError,"NoImagesDefined",
6115 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006116 break;
6117 }
6118 gray=MagickFalse;
6119 if (attributes != (const xmlChar **) NULL)
6120 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6121 {
6122 keyword=(const char *) attributes[i++];
6123 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006124 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006125 CloneString(&value,attribute);
6126 switch (*keyword)
6127 {
6128 case 'A':
6129 case 'a':
6130 {
6131 if (LocaleCompare(keyword,"azimuth") == 0)
6132 {
cristyc1acd842011-05-19 23:05:47 +00006133 geometry_info.rho=InterpretLocaleValue(value,
6134 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006135 break;
6136 }
6137 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6138 keyword);
6139 break;
6140 }
6141 case 'E':
6142 case 'e':
6143 {
6144 if (LocaleCompare(keyword,"elevation") == 0)
6145 {
cristyc1acd842011-05-19 23:05:47 +00006146 geometry_info.sigma=InterpretLocaleValue(value,
6147 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006148 break;
6149 }
6150 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6151 keyword);
6152 break;
6153 }
6154 case 'G':
6155 case 'g':
6156 {
6157 if (LocaleCompare(keyword,"geometry") == 0)
6158 {
6159 flags=ParseGeometry(value,&geometry_info);
6160 if ((flags & SigmaValue) == 0)
6161 geometry_info.sigma=1.0;
6162 break;
6163 }
6164 if (LocaleCompare(keyword,"gray") == 0)
6165 {
cristy042ee782011-04-22 18:48:30 +00006166 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006167 value);
6168 if (option < 0)
6169 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6170 value);
6171 gray=(MagickBooleanType) option;
6172 break;
6173 }
6174 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6175 keyword);
6176 break;
6177 }
6178 default:
6179 {
6180 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6181 keyword);
6182 break;
6183 }
6184 }
6185 }
6186 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6187 geometry_info.sigma,&msl_info->image[n]->exception);
6188 if (shade_image == (Image *) NULL)
6189 break;
6190 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6191 msl_info->image[n]=shade_image;
6192 break;
6193 }
cristyb988fe72009-09-16 01:01:10 +00006194 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006195 {
6196 Image
6197 *shadow_image;
6198
6199 /*
6200 Shear image.
6201 */
6202 if (msl_info->image[n] == (Image *) NULL)
6203 {
cristyb988fe72009-09-16 01:01:10 +00006204 ThrowMSLException(OptionError,"NoImagesDefined",
6205 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006206 break;
6207 }
6208 if (attributes != (const xmlChar **) NULL)
6209 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6210 {
6211 keyword=(const char *) attributes[i++];
6212 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006213 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006214 CloneString(&value,attribute);
6215 switch (*keyword)
6216 {
6217 case 'G':
6218 case 'g':
6219 {
6220 if (LocaleCompare(keyword,"geometry") == 0)
6221 {
6222 flags=ParseGeometry(value,&geometry_info);
6223 if ((flags & SigmaValue) == 0)
6224 geometry_info.sigma=1.0;
6225 break;
6226 }
6227 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6228 keyword);
6229 break;
6230 }
6231 case 'O':
6232 case 'o':
6233 {
6234 if (LocaleCompare(keyword,"opacity") == 0)
6235 {
cristyf2f27272009-12-17 14:48:46 +00006236 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006237 break;
6238 }
6239 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6240 keyword);
6241 break;
6242 }
6243 case 'S':
6244 case 's':
6245 {
6246 if (LocaleCompare(keyword,"sigma") == 0)
6247 {
cristyf2f27272009-12-17 14:48:46 +00006248 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006249 break;
6250 }
6251 break;
6252 }
6253 case 'X':
6254 case 'x':
6255 {
6256 if (LocaleCompare(keyword,"x") == 0)
6257 {
cristyc1acd842011-05-19 23:05:47 +00006258 geometry_info.xi=InterpretLocaleValue(value,
6259 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006260 break;
6261 }
6262 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6263 keyword);
6264 break;
6265 }
6266 case 'Y':
6267 case 'y':
6268 {
6269 if (LocaleCompare(keyword,"y") == 0)
6270 {
cristyf2f27272009-12-17 14:48:46 +00006271 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006272 break;
6273 }
6274 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6275 keyword);
6276 break;
6277 }
6278 default:
6279 {
6280 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6281 keyword);
6282 break;
6283 }
6284 }
6285 }
6286 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristybb503372010-05-27 20:51:26 +00006287 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
cristy0534a6b2010-03-18 01:19:38 +00006288 ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006289 if (shadow_image == (Image *) NULL)
6290 break;
6291 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6292 msl_info->image[n]=shadow_image;
6293 break;
6294 }
cristyb988fe72009-09-16 01:01:10 +00006295 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006296 {
6297 double radius = 0.0,
6298 sigma = 1.0;
6299
6300 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006301 {
6302 ThrowMSLException(OptionError,"NoImagesDefined",
6303 (const char *) tag);
6304 break;
6305 }
cristy3ed852e2009-09-05 21:47:34 +00006306 /*
6307 NOTE: sharpen can have no attributes, since we use all the defaults!
6308 */
6309 if (attributes != (const xmlChar **) NULL)
6310 {
6311 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6312 {
6313 keyword=(const char *) attributes[i++];
6314 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006315 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006316 switch (*keyword)
6317 {
6318 case 'R':
6319 case 'r':
6320 {
6321 if (LocaleCompare(keyword, "radius") == 0)
6322 {
cristyc1acd842011-05-19 23:05:47 +00006323 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006324 break;
6325 }
6326 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6327 break;
6328 }
6329 case 'S':
6330 case 's':
6331 {
6332 if (LocaleCompare(keyword,"sigma") == 0)
6333 {
cristyf2f27272009-12-17 14:48:46 +00006334 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006335 break;
6336 }
6337 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6338 break;
6339 }
6340 default:
6341 {
6342 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6343 break;
6344 }
6345 }
6346 }
6347 }
6348
6349 /*
6350 sharpen image.
6351 */
6352 {
6353 Image
6354 *newImage;
6355
6356 newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6357 if (newImage == (Image *) NULL)
6358 break;
6359 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6360 msl_info->image[n]=newImage;
6361 break;
6362 }
6363 }
cristyb988fe72009-09-16 01:01:10 +00006364 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006365 {
6366 /* init the values */
6367 width = height = 0;
6368 x = y = 0;
6369
6370 if (msl_info->image[n] == (Image *) NULL)
6371 {
cristyb988fe72009-09-16 01:01:10 +00006372 ThrowMSLException(OptionError,"NoImagesDefined",
6373 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006374 break;
6375 }
6376 if (attributes == (const xmlChar **) NULL)
6377 break;
6378 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6379 {
6380 keyword=(const char *) attributes[i++];
6381 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006382 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006383 switch (*keyword)
6384 {
6385 case 'G':
6386 case 'g':
6387 {
6388 if (LocaleCompare(keyword,"geometry") == 0)
6389 {
6390 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6391 break;
6392 }
6393 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6394 break;
6395 }
6396 case 'H':
6397 case 'h':
6398 {
6399 if (LocaleCompare(keyword,"height") == 0)
6400 {
cristyf2f27272009-12-17 14:48:46 +00006401 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006402 break;
6403 }
6404 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6405 break;
6406 }
6407 case 'W':
6408 case 'w':
6409 {
6410 if (LocaleCompare(keyword,"width") == 0)
6411 {
cristyf2f27272009-12-17 14:48:46 +00006412 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006413 break;
6414 }
6415 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6416 break;
6417 }
6418 default:
6419 {
6420 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6421 break;
6422 }
6423 }
6424 }
6425
6426 /*
6427 process image.
6428 */
6429 {
6430 Image
6431 *newImage;
6432 RectangleInfo
6433 rectInfo;
6434
6435 rectInfo.height = height;
6436 rectInfo.width = width;
6437 rectInfo.x = x;
6438 rectInfo.y = y;
6439
6440
6441 newImage=ShaveImage(msl_info->image[n], &rectInfo,
6442 &msl_info->image[n]->exception);
6443 if (newImage == (Image *) NULL)
6444 break;
6445 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6446 msl_info->image[n]=newImage;
6447 }
6448
6449 break;
6450 }
cristyb988fe72009-09-16 01:01:10 +00006451 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006452 {
6453 Image
6454 *shear_image;
6455
6456 /*
6457 Shear image.
6458 */
6459 if (msl_info->image[n] == (Image *) NULL)
6460 {
cristyb988fe72009-09-16 01:01:10 +00006461 ThrowMSLException(OptionError,"NoImagesDefined",
6462 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006463 break;
6464 }
6465 if (attributes != (const xmlChar **) NULL)
6466 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6467 {
6468 keyword=(const char *) attributes[i++];
6469 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006470 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006471 CloneString(&value,attribute);
6472 switch (*keyword)
6473 {
6474 case 'F':
6475 case 'f':
6476 {
6477 if (LocaleCompare(keyword, "fill") == 0)
6478 {
6479 (void) QueryColorDatabase(value,
6480 &msl_info->image[n]->background_color,&exception);
6481 break;
6482 }
6483 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6484 keyword);
6485 break;
6486 }
6487 case 'G':
6488 case 'g':
6489 {
6490 if (LocaleCompare(keyword,"geometry") == 0)
6491 {
6492 flags=ParseGeometry(value,&geometry_info);
6493 if ((flags & SigmaValue) == 0)
6494 geometry_info.sigma=1.0;
6495 break;
6496 }
6497 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6498 keyword);
6499 break;
6500 }
6501 case 'X':
6502 case 'x':
6503 {
6504 if (LocaleCompare(keyword,"x") == 0)
6505 {
cristyc1acd842011-05-19 23:05:47 +00006506 geometry_info.rho=InterpretLocaleValue(value,
6507 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006508 break;
6509 }
6510 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6511 keyword);
6512 break;
6513 }
6514 case 'Y':
6515 case 'y':
6516 {
6517 if (LocaleCompare(keyword,"y") == 0)
6518 {
cristyf2f27272009-12-17 14:48:46 +00006519 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006520 break;
6521 }
6522 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6523 keyword);
6524 break;
6525 }
6526 default:
6527 {
6528 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6529 keyword);
6530 break;
6531 }
6532 }
6533 }
6534 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6535 geometry_info.sigma,&msl_info->image[n]->exception);
6536 if (shear_image == (Image *) NULL)
6537 break;
6538 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6539 msl_info->image[n]=shear_image;
6540 break;
6541 }
cristyb988fe72009-09-16 01:01:10 +00006542 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006543 {
6544 /*
6545 Signature image.
6546 */
6547 if (msl_info->image[n] == (Image *) NULL)
6548 {
cristyb988fe72009-09-16 01:01:10 +00006549 ThrowMSLException(OptionError,"NoImagesDefined",
6550 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006551 break;
6552 }
6553 if (attributes != (const xmlChar **) NULL)
6554 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6555 {
6556 keyword=(const char *) attributes[i++];
6557 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006558 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006559 CloneString(&value,attribute);
6560 switch (*keyword)
6561 {
6562 default:
6563 {
6564 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6565 keyword);
6566 break;
6567 }
6568 }
6569 }
6570 (void) SignatureImage(msl_info->image[n]);
6571 break;
6572 }
cristyb988fe72009-09-16 01:01:10 +00006573 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006574 {
6575 /*
6576 Solarize image.
6577 */
6578 if (msl_info->image[n] == (Image *) NULL)
6579 {
cristyb988fe72009-09-16 01:01:10 +00006580 ThrowMSLException(OptionError,"NoImagesDefined",
6581 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006582 break;
6583 }
6584 geometry_info.rho=QuantumRange/2.0;
6585 if (attributes != (const xmlChar **) NULL)
6586 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6587 {
6588 keyword=(const char *) attributes[i++];
6589 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006590 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006591 CloneString(&value,attribute);
6592 switch (*keyword)
6593 {
6594 case 'G':
6595 case 'g':
6596 {
6597 if (LocaleCompare(keyword,"geometry") == 0)
6598 {
6599 flags=ParseGeometry(value,&geometry_info);
6600 break;
6601 }
6602 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6603 keyword);
6604 break;
6605 }
6606 case 'T':
6607 case 't':
6608 {
6609 if (LocaleCompare(keyword,"threshold") == 0)
6610 {
cristyc1acd842011-05-19 23:05:47 +00006611 geometry_info.rho=InterpretLocaleValue(value,
6612 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006613 break;
6614 }
6615 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6616 keyword);
6617 break;
6618 }
6619 default:
6620 {
6621 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6622 keyword);
6623 break;
6624 }
6625 }
6626 }
6627 (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6628 break;
6629 }
cristyb988fe72009-09-16 01:01:10 +00006630 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006631 {
6632 Image
6633 *spread_image;
6634
6635 /*
6636 Spread image.
6637 */
6638 if (msl_info->image[n] == (Image *) NULL)
6639 {
cristyb988fe72009-09-16 01:01:10 +00006640 ThrowMSLException(OptionError,"NoImagesDefined",
6641 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006642 break;
6643 }
6644 if (attributes != (const xmlChar **) NULL)
6645 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6646 {
6647 keyword=(const char *) attributes[i++];
6648 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006649 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006650 CloneString(&value,attribute);
6651 switch (*keyword)
6652 {
6653 case 'G':
6654 case 'g':
6655 {
6656 if (LocaleCompare(keyword,"geometry") == 0)
6657 {
6658 flags=ParseGeometry(value,&geometry_info);
6659 if ((flags & SigmaValue) == 0)
6660 geometry_info.sigma=1.0;
6661 break;
6662 }
6663 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6664 keyword);
6665 break;
6666 }
6667 case 'R':
6668 case 'r':
6669 {
6670 if (LocaleCompare(keyword,"radius") == 0)
6671 {
cristyc1acd842011-05-19 23:05:47 +00006672 geometry_info.rho=InterpretLocaleValue(value,
6673 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006674 break;
6675 }
6676 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6677 keyword);
6678 break;
6679 }
6680 default:
6681 {
6682 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6683 keyword);
6684 break;
6685 }
6686 }
6687 }
6688 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6689 &msl_info->image[n]->exception);
6690 if (spread_image == (Image *) NULL)
6691 break;
6692 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6693 msl_info->image[n]=spread_image;
6694 break;
6695 }
cristyb988fe72009-09-16 01:01:10 +00006696 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006697 {
6698 Image *
6699 watermark = (Image*)NULL;
6700
6701 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006702 {
6703 ThrowMSLException(OptionError,"NoImagesDefined",
6704 (const char *) tag);
6705 break;
6706 }
cristy3ed852e2009-09-05 21:47:34 +00006707 if (attributes == (const xmlChar **) NULL)
6708 break;
6709 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6710 {
6711 keyword=(const char *) attributes[i++];
6712 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006713 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006714 switch (*keyword)
6715 {
6716 case 'I':
6717 case 'i':
6718 {
6719 if (LocaleCompare(keyword,"image") == 0)
6720 {
6721 for (j=0; j<msl_info->n;j++)
6722 {
6723 const char *
6724 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6725 if (theAttr && LocaleCompare(theAttr, value) == 0)
6726 {
6727 watermark = msl_info->image[j];
6728 break;
6729 }
6730 }
6731 break;
6732 }
6733 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6734 break;
6735 }
6736 default:
6737 {
6738 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6739 break;
6740 }
6741 }
6742 }
6743
6744 /*
6745 process image.
6746 */
6747 if ( watermark != (Image*) NULL )
6748 {
6749 Image
6750 *newImage;
6751
6752 newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6753 if (newImage == (Image *) NULL)
6754 break;
6755 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6756 msl_info->image[n]=newImage;
6757 break;
6758 } else
6759 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6760 }
cristyb988fe72009-09-16 01:01:10 +00006761 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006762 {
6763 Image *
6764 stereoImage = (Image*)NULL;
6765
6766 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006767 {
6768 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6769 break;
6770 }
cristy3ed852e2009-09-05 21:47:34 +00006771 if (attributes == (const xmlChar **) NULL)
6772 break;
6773 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6774 {
6775 keyword=(const char *) attributes[i++];
6776 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006777 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006778 switch (*keyword)
6779 {
6780 case 'I':
6781 case 'i':
6782 {
6783 if (LocaleCompare(keyword,"image") == 0)
6784 {
6785 for (j=0; j<msl_info->n;j++)
6786 {
6787 const char *
6788 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6789 if (theAttr && LocaleCompare(theAttr, value) == 0)
6790 {
6791 stereoImage = msl_info->image[j];
6792 break;
6793 }
6794 }
6795 break;
6796 }
6797 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6798 break;
6799 }
6800 default:
6801 {
6802 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6803 break;
6804 }
6805 }
6806 }
6807
6808 /*
6809 process image.
6810 */
6811 if ( stereoImage != (Image*) NULL )
6812 {
6813 Image
6814 *newImage;
6815
6816 newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6817 if (newImage == (Image *) NULL)
6818 break;
6819 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6820 msl_info->image[n]=newImage;
6821 break;
6822 } else
6823 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6824 }
cristyb988fe72009-09-16 01:01:10 +00006825 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006826 {
6827 Image
6828 *p,
6829 *q,
6830 *swap;
6831
cristybb503372010-05-27 20:51:26 +00006832 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006833 index,
6834 swap_index;
6835
6836 if (msl_info->image[n] == (Image *) NULL)
6837 {
cristyb988fe72009-09-16 01:01:10 +00006838 ThrowMSLException(OptionError,"NoImagesDefined",
6839 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006840 break;
6841 }
6842 index=(-1);
6843 swap_index=(-2);
6844 if (attributes != (const xmlChar **) NULL)
6845 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6846 {
6847 keyword=(const char *) attributes[i++];
6848 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006849 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006850 CloneString(&value,attribute);
6851 switch (*keyword)
6852 {
6853 case 'G':
6854 case 'g':
6855 {
6856 if (LocaleCompare(keyword,"indexes") == 0)
6857 {
6858 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006859 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006860 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006861 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006862 break;
6863 }
6864 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6865 keyword);
6866 break;
6867 }
6868 default:
6869 {
6870 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6871 keyword);
6872 break;
6873 }
6874 }
6875 }
6876 /*
6877 Swap images.
6878 */
6879 p=GetImageFromList(msl_info->image[n],index);
6880 q=GetImageFromList(msl_info->image[n],swap_index);
6881 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6882 {
cristyb988fe72009-09-16 01:01:10 +00006883 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006884 break;
6885 }
6886 swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6887 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6888 ReplaceImageInList(&q,swap);
6889 msl_info->image[n]=GetFirstImageInList(q);
6890 break;
6891 }
cristyb988fe72009-09-16 01:01:10 +00006892 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006893 {
6894 Image
6895 *swirl_image;
6896
6897 /*
6898 Swirl image.
6899 */
6900 if (msl_info->image[n] == (Image *) NULL)
6901 {
cristyb988fe72009-09-16 01:01:10 +00006902 ThrowMSLException(OptionError,"NoImagesDefined",
6903 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006904 break;
6905 }
6906 if (attributes != (const xmlChar **) NULL)
6907 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6908 {
6909 keyword=(const char *) attributes[i++];
6910 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006911 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006912 CloneString(&value,attribute);
6913 switch (*keyword)
6914 {
6915 case 'D':
6916 case 'd':
6917 {
6918 if (LocaleCompare(keyword,"degrees") == 0)
6919 {
cristyc1acd842011-05-19 23:05:47 +00006920 geometry_info.rho=InterpretLocaleValue(value,
6921 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006922 break;
6923 }
6924 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6925 keyword);
6926 break;
6927 }
6928 case 'G':
6929 case 'g':
6930 {
6931 if (LocaleCompare(keyword,"geometry") == 0)
6932 {
6933 flags=ParseGeometry(value,&geometry_info);
6934 if ((flags & SigmaValue) == 0)
6935 geometry_info.sigma=1.0;
6936 break;
6937 }
6938 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6939 keyword);
6940 break;
6941 }
6942 default:
6943 {
6944 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6945 keyword);
6946 break;
6947 }
6948 }
6949 }
6950 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6951 &msl_info->image[n]->exception);
6952 if (swirl_image == (Image *) NULL)
6953 break;
6954 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6955 msl_info->image[n]=swirl_image;
6956 break;
6957 }
cristyb988fe72009-09-16 01:01:10 +00006958 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006959 {
6960 /*
6961 Sync image.
6962 */
6963 if (msl_info->image[n] == (Image *) NULL)
6964 {
cristyb988fe72009-09-16 01:01:10 +00006965 ThrowMSLException(OptionError,"NoImagesDefined",
6966 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006967 break;
6968 }
6969 if (attributes != (const xmlChar **) NULL)
6970 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6971 {
6972 keyword=(const char *) attributes[i++];
6973 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006974 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006975 CloneString(&value,attribute);
6976 switch (*keyword)
6977 {
6978 default:
6979 {
6980 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6981 keyword);
6982 break;
6983 }
6984 }
6985 }
6986 (void) SyncImage(msl_info->image[n]);
6987 break;
6988 }
6989 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6990 }
6991 case 'T':
6992 case 't':
6993 {
cristyb988fe72009-09-16 01:01:10 +00006994 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006995 {
6996 Image
6997 *texture_image;
6998
6999 /*
7000 Texture image.
7001 */
7002 if (msl_info->image[n] == (Image *) NULL)
7003 {
cristyb988fe72009-09-16 01:01:10 +00007004 ThrowMSLException(OptionError,"NoImagesDefined",
7005 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007006 break;
7007 }
7008 texture_image=NewImageList();
7009 if (attributes != (const xmlChar **) NULL)
7010 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7011 {
7012 keyword=(const char *) attributes[i++];
7013 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007014 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00007015 CloneString(&value,attribute);
7016 switch (*keyword)
7017 {
7018 case 'I':
7019 case 'i':
7020 {
7021 if (LocaleCompare(keyword,"image") == 0)
7022 for (j=0; j < msl_info->n; j++)
7023 {
7024 const char
7025 *attribute;
cristyb988fe72009-09-16 01:01:10 +00007026
cristy3ed852e2009-09-05 21:47:34 +00007027 attribute=GetImageProperty(msl_info->attributes[j],"id");
7028 if ((attribute != (const char *) NULL) &&
7029 (LocaleCompare(attribute,value) == 0))
7030 {
7031 texture_image=CloneImage(msl_info->image[j],0,0,
7032 MagickFalse,&exception);
7033 break;
7034 }
7035 }
7036 break;
7037 }
7038 default:
7039 {
7040 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7041 keyword);
7042 break;
7043 }
7044 }
7045 }
7046 (void) TextureImage(msl_info->image[n],texture_image);
7047 texture_image=DestroyImage(texture_image);
7048 break;
7049 }
cristyb988fe72009-09-16 01:01:10 +00007050 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007051 {
7052 /* init the values */
7053 double threshold = 0;
7054
7055 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007056 {
7057 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7058 break;
7059 }
cristy3ed852e2009-09-05 21:47:34 +00007060 if (attributes == (const xmlChar **) NULL)
7061 break;
7062 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7063 {
7064 keyword=(const char *) attributes[i++];
7065 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007066 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007067 switch (*keyword)
7068 {
7069 case 'T':
7070 case 't':
7071 {
7072 if (LocaleCompare(keyword,"threshold") == 0)
7073 {
cristyc1acd842011-05-19 23:05:47 +00007074 threshold = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007075 break;
7076 }
7077 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7078 break;
7079 }
7080 default:
7081 {
7082 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7083 break;
7084 }
7085 }
7086 }
7087
7088 /*
7089 process image.
7090 */
7091 {
7092 BilevelImageChannel(msl_info->image[n],
cristy9a9230e2011-04-26 14:56:14 +00007093 (ChannelType) ((ssize_t) (CompositeChannels &~ (ssize_t) OpacityChannel)),
cristy3ed852e2009-09-05 21:47:34 +00007094 threshold);
7095 break;
7096 }
7097 }
cristyb988fe72009-09-16 01:01:10 +00007098 else if (LocaleCompare((const char *) tag, "transparent") == 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 if (attributes == (const xmlChar **) NULL)
7106 break;
7107 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7108 {
7109 keyword=(const char *) attributes[i++];
7110 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007111 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007112 switch (*keyword)
7113 {
7114 case 'C':
7115 case 'c':
7116 {
7117 if (LocaleCompare(keyword,"color") == 0)
7118 {
cristy4c08aed2011-07-01 19:47:50 +00007119 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00007120 target;
7121
7122 (void) QueryMagickColor(value,&target,&exception);
7123 (void) TransparentPaintImage(msl_info->image[n],&target,
cristy4c08aed2011-07-01 19:47:50 +00007124 TransparentAlpha,MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +00007125 break;
7126 }
7127 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7128 break;
7129 }
7130 default:
7131 {
7132 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7133 break;
7134 }
7135 }
7136 }
7137 break;
7138 }
cristyb988fe72009-09-16 01:01:10 +00007139 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007140 {
7141 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007142 {
7143 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7144 break;
7145 }
cristy3ed852e2009-09-05 21:47:34 +00007146
7147 /* no attributes here */
7148
7149 /* process the image */
7150 {
7151 Image
7152 *newImage;
7153 RectangleInfo
7154 rectInfo;
7155
7156 /* all zeros on a crop == trim edges! */
7157 rectInfo.height = rectInfo.width = 0;
7158 rectInfo.x = rectInfo.y = 0;
7159
7160 newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7161 if (newImage == (Image *) NULL)
7162 break;
7163 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7164 msl_info->image[n]=newImage;
7165 break;
7166 }
7167 }
7168 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7169 }
7170 case 'W':
7171 case 'w':
7172 {
cristyb988fe72009-09-16 01:01:10 +00007173 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007174 {
7175 if (msl_info->image[n] == (Image *) NULL)
7176 {
cristyb988fe72009-09-16 01:01:10 +00007177 ThrowMSLException(OptionError,"NoImagesDefined",
7178 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007179 break;
7180 }
7181 if (attributes == (const xmlChar **) NULL)
7182 break;
7183 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7184 {
7185 keyword=(const char *) attributes[i++];
7186 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007187 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007188 switch (*keyword)
7189 {
7190 case 'F':
7191 case 'f':
7192 {
7193 if (LocaleCompare(keyword,"filename") == 0)
7194 {
7195 (void) CopyMagickString(msl_info->image[n]->filename,value,
7196 MaxTextExtent);
7197 break;
7198 }
cristy4582cbb2009-09-23 00:35:43 +00007199 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007200 }
7201 default:
7202 {
cristy4582cbb2009-09-23 00:35:43 +00007203 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007204 break;
7205 }
7206 }
7207 }
7208
7209 /* process */
7210 {
7211 (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7212 break;
7213 }
7214 }
7215 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7216 }
7217 default:
7218 {
7219 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7220 break;
7221 }
7222 }
7223 if ( value != NULL )
7224 value=DestroyString(value);
7225 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7226}
7227
7228static void MSLEndElement(void *context,const xmlChar *tag)
7229{
cristybb503372010-05-27 20:51:26 +00007230 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007231 n;
7232
7233 MSLInfo
7234 *msl_info;
7235
7236 /*
7237 Called when the end of an element has been detected.
7238 */
7239 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7240 tag);
7241 msl_info=(MSLInfo *) context;
7242 n=msl_info->n;
7243 switch (*tag)
7244 {
7245 case 'C':
7246 case 'c':
7247 {
cristyb988fe72009-09-16 01:01:10 +00007248 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007249 {
7250 (void) DeleteImageProperty(msl_info->image[n],"comment");
7251 if (msl_info->content == (char *) NULL)
7252 break;
7253 StripString(msl_info->content);
7254 (void) SetImageProperty(msl_info->image[n],"comment",
7255 msl_info->content);
7256 break;
7257 }
7258 break;
7259 }
7260 case 'G':
7261 case 'g':
7262 {
cristyb988fe72009-09-16 01:01:10 +00007263 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007264 {
7265 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7266 {
cristybb503372010-05-27 20:51:26 +00007267 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007268 (msl_info->group_info[msl_info->number_groups-1].numImages);
7269 while ( i-- )
7270 {
7271 if (msl_info->image[msl_info->n] != (Image *) NULL)
7272 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7273 msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7274 msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7275 msl_info->n--;
7276 }
7277 }
7278 msl_info->number_groups--;
7279 }
7280 break;
7281 }
7282 case 'I':
7283 case 'i':
7284 {
cristyb988fe72009-09-16 01:01:10 +00007285 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007286 MSLPopImage(msl_info);
7287 break;
7288 }
7289 case 'L':
7290 case 'l':
7291 {
cristyb988fe72009-09-16 01:01:10 +00007292 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007293 {
7294 (void) DeleteImageProperty(msl_info->image[n],"label");
7295 if (msl_info->content == (char *) NULL)
7296 break;
7297 StripString(msl_info->content);
7298 (void) SetImageProperty(msl_info->image[n],"label",
7299 msl_info->content);
7300 break;
7301 }
7302 break;
7303 }
7304 case 'M':
7305 case 'm':
7306 {
cristyb988fe72009-09-16 01:01:10 +00007307 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007308 {
7309 /*
7310 This our base element.
7311 at the moment we don't do anything special
7312 but someday we might!
7313 */
7314 }
7315 break;
7316 }
7317 default:
7318 break;
7319 }
7320 if (msl_info->content != (char *) NULL)
7321 msl_info->content=DestroyString(msl_info->content);
7322}
7323
7324static void MSLCharacters(void *context,const xmlChar *c,int length)
7325{
7326 MSLInfo
7327 *msl_info;
7328
7329 register char
7330 *p;
7331
cristybb503372010-05-27 20:51:26 +00007332 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007333 i;
7334
7335 /*
7336 Receiving some characters from the parser.
7337 */
7338 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7339 " SAX.characters(%s,%d)",c,length);
7340 msl_info=(MSLInfo *) context;
7341 if (msl_info->content != (char *) NULL)
7342 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7343 strlen(msl_info->content)+length+MaxTextExtent,
7344 sizeof(*msl_info->content));
7345 else
7346 {
7347 msl_info->content=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +00007348 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00007349 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7350 sizeof(*msl_info->content));
7351 if (msl_info->content != (char *) NULL)
7352 *msl_info->content='\0';
7353 }
7354 if (msl_info->content == (char *) NULL)
7355 return;
7356 p=msl_info->content+strlen(msl_info->content);
7357 for (i=0; i < length; i++)
7358 *p++=c[i];
7359 *p='\0';
7360}
7361
7362static void MSLReference(void *context,const xmlChar *name)
7363{
7364 MSLInfo
7365 *msl_info;
7366
7367 xmlParserCtxtPtr
7368 parser;
7369
7370 /*
7371 Called when an entity reference is detected.
7372 */
7373 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7374 " SAX.reference(%s)",name);
7375 msl_info=(MSLInfo *) context;
7376 parser=msl_info->parser;
7377 if (*name == '#')
7378 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7379 else
7380 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7381}
7382
7383static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7384{
7385 MSLInfo
7386 *msl_info;
7387
7388 /*
7389 Receiving some ignorable whitespaces from the parser.
7390 */
7391 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7392 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7393 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007394 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007395}
7396
7397static void MSLProcessingInstructions(void *context,const xmlChar *target,
7398 const xmlChar *data)
7399{
7400 MSLInfo
7401 *msl_info;
7402
7403 /*
7404 A processing instruction has been parsed.
7405 */
7406 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7407 " SAX.processingInstruction(%s, %s)",
7408 target,data);
7409 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007410 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007411}
7412
7413static void MSLComment(void *context,const xmlChar *value)
7414{
7415 MSLInfo
7416 *msl_info;
7417
7418 /*
7419 A comment has been parsed.
7420 */
7421 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7422 " SAX.comment(%s)",value);
7423 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007424 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007425}
7426
7427static void MSLWarning(void *context,const char *format,...)
7428{
7429 char
7430 *message,
7431 reason[MaxTextExtent];
7432
7433 MSLInfo
7434 *msl_info;
7435
7436 va_list
7437 operands;
7438
7439 /**
7440 Display and format a warning messages, gives file, line, position and
7441 extra parameters.
7442 */
7443 va_start(operands,format);
7444 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7445 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7446 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007447 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007448#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7449 (void) vsprintf(reason,format,operands);
7450#else
7451 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7452#endif
7453 message=GetExceptionMessage(errno);
7454 ThrowMSLException(CoderError,reason,message);
7455 message=DestroyString(message);
7456 va_end(operands);
7457}
7458
7459static void MSLError(void *context,const char *format,...)
7460{
7461 char
7462 reason[MaxTextExtent];
7463
7464 MSLInfo
7465 *msl_info;
7466
7467 va_list
7468 operands;
7469
7470 /*
7471 Display and format a error formats, gives file, line, position and
7472 extra parameters.
7473 */
7474 va_start(operands,format);
7475 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7476 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7477 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007478 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007479#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7480 (void) vsprintf(reason,format,operands);
7481#else
7482 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7483#endif
7484 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7485 va_end(operands);
7486}
7487
7488static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7489{
7490 MSLInfo
7491 *msl_info;
7492
7493 xmlNodePtr
7494 child;
7495
7496 xmlParserCtxtPtr
7497 parser;
7498
7499 /*
7500 Called when a pcdata block has been parsed.
7501 */
7502 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7503 " SAX.pcdata(%s, %d)",value,length);
7504 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007505 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007506 parser=msl_info->parser;
7507 child=xmlGetLastChild(parser->node);
7508 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7509 {
7510 xmlTextConcat(child,value,length);
7511 return;
7512 }
7513 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7514}
7515
7516static void MSLExternalSubset(void *context,const xmlChar *name,
7517 const xmlChar *external_id,const xmlChar *system_id)
7518{
7519 MSLInfo
7520 *msl_info;
7521
7522 xmlParserCtxt
7523 parser_context;
7524
7525 xmlParserCtxtPtr
7526 parser;
7527
7528 xmlParserInputPtr
7529 input;
7530
7531 /*
7532 Does this document has an external subset?
7533 */
7534 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7535 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007536 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7537 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007538 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007539 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007540 parser=msl_info->parser;
7541 if (((external_id == NULL) && (system_id == NULL)) ||
7542 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7543 (msl_info->document == 0)))
7544 return;
7545 input=MSLResolveEntity(context,external_id,system_id);
7546 if (input == NULL)
7547 return;
7548 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7549 parser_context=(*parser);
7550 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7551 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7552 {
7553 parser->errNo=XML_ERR_NO_MEMORY;
7554 parser->input=parser_context.input;
7555 parser->inputNr=parser_context.inputNr;
7556 parser->inputMax=parser_context.inputMax;
7557 parser->inputTab=parser_context.inputTab;
7558 return;
7559 }
7560 parser->inputNr=0;
7561 parser->inputMax=5;
7562 parser->input=NULL;
7563 xmlPushInput(parser,input);
7564 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7565 if (input->filename == (char *) NULL)
7566 input->filename=(char *) xmlStrdup(system_id);
7567 input->line=1;
7568 input->col=1;
7569 input->base=parser->input->cur;
7570 input->cur=parser->input->cur;
7571 input->free=NULL;
7572 xmlParseExternalSubset(parser,external_id,system_id);
7573 while (parser->inputNr > 1)
7574 (void) xmlPopInput(parser);
7575 xmlFreeInputStream(parser->input);
7576 xmlFree(parser->inputTab);
7577 parser->input=parser_context.input;
7578 parser->inputNr=parser_context.inputNr;
7579 parser->inputMax=parser_context.inputMax;
7580 parser->inputTab=parser_context.inputTab;
7581}
7582
7583#if defined(__cplusplus) || defined(c_plusplus)
7584}
7585#endif
7586
7587static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7588 ExceptionInfo *exception)
7589{
cristy3ed852e2009-09-05 21:47:34 +00007590 char
7591 message[MaxTextExtent];
7592
7593 Image
7594 *msl_image;
7595
7596 int
7597 status;
7598
cristybb503372010-05-27 20:51:26 +00007599 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007600 n;
7601
7602 MSLInfo
7603 msl_info;
7604
cristy5f6f01c2009-11-19 19:36:42 +00007605 xmlSAXHandler
7606 sax_modules;
7607
cristy3ed852e2009-09-05 21:47:34 +00007608 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007609 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007610
7611 /*
7612 Open image file.
7613 */
7614 assert(image_info != (const ImageInfo *) NULL);
7615 assert(image_info->signature == MagickSignature);
7616 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007617 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7618 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007619 assert(image != (Image **) NULL);
7620 msl_image=AcquireImage(image_info);
7621 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7622 if (status == MagickFalse)
7623 {
7624 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7625 msl_image->filename);
7626 msl_image=DestroyImageList(msl_image);
7627 return(MagickFalse);
7628 }
7629 msl_image->columns=1;
7630 msl_image->rows=1;
7631 /*
7632 Parse MSL file.
7633 */
7634 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7635 msl_info.exception=exception;
7636 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7637 sizeof(*msl_info.image_info));
7638 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7639 sizeof(*msl_info.draw_info));
7640 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007641 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007642 msl_info.attributes=(Image **) AcquireMagickMemory(
7643 sizeof(*msl_info.attributes));
7644 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7645 sizeof(*msl_info.group_info));
7646 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7647 (msl_info.image == (Image **) NULL) ||
7648 (msl_info.attributes == (Image **) NULL) ||
7649 (msl_info.group_info == (MSLGroupInfo *) NULL))
7650 ThrowFatalException(ResourceLimitFatalError,
7651 "UnableToInterpretMSLImage");
7652 *msl_info.image_info=CloneImageInfo(image_info);
7653 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7654 *msl_info.attributes=AcquireImage(image_info);
7655 msl_info.group_info[0].numImages=0;
7656 /* the first slot is used to point to the MSL file image */
7657 *msl_info.image=msl_image;
7658 if (*image != (Image *) NULL)
7659 MSLPushImage(&msl_info,*image);
7660 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007661 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7662 sax_modules.internalSubset=MSLInternalSubset;
7663 sax_modules.isStandalone=MSLIsStandalone;
7664 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7665 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7666 sax_modules.resolveEntity=MSLResolveEntity;
7667 sax_modules.getEntity=MSLGetEntity;
7668 sax_modules.entityDecl=MSLEntityDeclaration;
7669 sax_modules.notationDecl=MSLNotationDeclaration;
7670 sax_modules.attributeDecl=MSLAttributeDeclaration;
7671 sax_modules.elementDecl=MSLElementDeclaration;
7672 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7673 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7674 sax_modules.startDocument=MSLStartDocument;
7675 sax_modules.endDocument=MSLEndDocument;
7676 sax_modules.startElement=MSLStartElement;
7677 sax_modules.endElement=MSLEndElement;
7678 sax_modules.reference=MSLReference;
7679 sax_modules.characters=MSLCharacters;
7680 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7681 sax_modules.processingInstruction=MSLProcessingInstructions;
7682 sax_modules.comment=MSLComment;
7683 sax_modules.warning=MSLWarning;
7684 sax_modules.error=MSLError;
7685 sax_modules.fatalError=MSLError;
7686 sax_modules.getParameterEntity=MSLGetParameterEntity;
7687 sax_modules.cdataBlock=MSLCDataBlock;
7688 sax_modules.externalSubset=MSLExternalSubset;
7689 sax_handler=(&sax_modules);
7690 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007691 msl_image->filename);
7692 while (ReadBlobString(msl_image,message) != (char *) NULL)
7693 {
cristybb503372010-05-27 20:51:26 +00007694 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007695 if (n == 0)
7696 continue;
7697 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7698 if (status != 0)
7699 break;
7700 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7701 if (msl_info.exception->severity >= ErrorException)
7702 break;
7703 }
7704 if (msl_info.exception->severity == UndefinedException)
7705 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7706 xmlFreeParserCtxt(msl_info.parser);
7707 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7708 xmlCleanupParser();
7709 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7710 msl_info.group_info);
7711 if (*image == (Image *) NULL)
7712 *image=(*msl_info.image);
cristy5f6f01c2009-11-19 19:36:42 +00007713 if ((*msl_info.image)->exception.severity != UndefinedException)
7714 return(MagickFalse);
7715 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007716}
7717
7718static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7719{
7720 Image
7721 *image;
7722
7723 /*
7724 Open image file.
7725 */
7726 assert(image_info != (const ImageInfo *) NULL);
7727 assert(image_info->signature == MagickSignature);
7728 if (image_info->debug != MagickFalse)
7729 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7730 image_info->filename);
7731 assert(exception != (ExceptionInfo *) NULL);
7732 assert(exception->signature == MagickSignature);
7733 image=(Image *) NULL;
7734 (void) ProcessMSLScript(image_info,&image,exception);
7735 return(GetFirstImageInList(image));
7736}
7737#endif
7738
7739/*
7740%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7741% %
7742% %
7743% %
7744% R e g i s t e r M S L I m a g e %
7745% %
7746% %
7747% %
7748%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7749%
7750% RegisterMSLImage() adds attributes for the MSL image format to
7751% the list of supported formats. The attributes include the image format
7752% tag, a method to read and/or write the format, whether the format
7753% supports the saving of more than one frame to the same file or blob,
7754% whether the format supports native in-memory I/O, and a brief
7755% description of the format.
7756%
7757% The format of the RegisterMSLImage method is:
7758%
cristybb503372010-05-27 20:51:26 +00007759% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007760%
7761*/
cristybb503372010-05-27 20:51:26 +00007762ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007763{
7764 MagickInfo
7765 *entry;
7766
7767 entry=SetMagickInfo("MSL");
7768#if defined(MAGICKCORE_XML_DELEGATE)
7769 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7770 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7771#endif
7772 entry->description=ConstantString("Magick Scripting Language");
7773 entry->module=ConstantString("MSL");
7774 (void) RegisterMagickInfo(entry);
7775 return(MagickImageCoderSignature);
7776}
7777
cristy6b9f7ed2010-04-24 01:08:02 +00007778#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007779/*
7780%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7781% %
7782% %
7783% %
cristyb988fe72009-09-16 01:01:10 +00007784% S e t M S L A t t r i b u t e s %
7785% %
7786% %
7787% %
7788%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7789%
7790% SetMSLAttributes() ...
7791%
7792% The format of the SetMSLAttributes method is:
7793%
7794% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007795% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007796%
7797% A description of each parameter follows:
7798%
7799% o msl_info: the MSL info.
7800%
cristyb20775d2009-09-16 01:51:41 +00007801% o keyword: the keyword.
7802%
7803% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007804%
7805*/
cristyb20775d2009-09-16 01:51:41 +00007806static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7807 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007808{
cristy4582cbb2009-09-23 00:35:43 +00007809 Image
7810 *attributes;
7811
cristyb20775d2009-09-16 01:51:41 +00007812 DrawInfo
7813 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007814
7815 ExceptionInfo
7816 *exception;
7817
cristy4582cbb2009-09-23 00:35:43 +00007818 GeometryInfo
7819 geometry_info;
7820
cristy4fa36e42009-09-18 14:24:06 +00007821 Image
7822 *image;
7823
cristyb20775d2009-09-16 01:51:41 +00007824 ImageInfo
7825 *image_info;
7826
cristy4582cbb2009-09-23 00:35:43 +00007827 int
7828 flags;
7829
cristybb503372010-05-27 20:51:26 +00007830 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007831 n;
7832
cristyb988fe72009-09-16 01:01:10 +00007833 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007834 if (keyword == (const char *) NULL)
7835 return(MagickTrue);
7836 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007837 return(MagickTrue);
7838 exception=msl_info->exception;
7839 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007840 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007841 image_info=msl_info->image_info[n];
7842 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007843 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007844 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007845 {
cristyfb758a52009-09-16 14:36:08 +00007846 case 'A':
7847 case 'a':
7848 {
7849 if (LocaleCompare(keyword,"adjoin") == 0)
7850 {
cristybb503372010-05-27 20:51:26 +00007851 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007852 adjoin;
7853
cristy042ee782011-04-22 18:48:30 +00007854 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007855 if (adjoin < 0)
7856 ThrowMSLException(OptionError,"UnrecognizedType",value);
7857 image_info->adjoin=(MagickBooleanType) adjoin;
7858 break;
7859 }
cristy4fa36e42009-09-18 14:24:06 +00007860 if (LocaleCompare(keyword,"alpha") == 0)
7861 {
cristybb503372010-05-27 20:51:26 +00007862 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007863 alpha;
7864
cristy042ee782011-04-22 18:48:30 +00007865 alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007866 if (alpha < 0)
7867 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007868 if (image != (Image *) NULL)
7869 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha);
7870 break;
7871 }
7872 if (LocaleCompare(keyword,"antialias") == 0)
7873 {
cristybb503372010-05-27 20:51:26 +00007874 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007875 antialias;
7876
cristy042ee782011-04-22 18:48:30 +00007877 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007878 if (antialias < 0)
7879 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7880 image_info->antialias=(MagickBooleanType) antialias;
7881 break;
7882 }
7883 if (LocaleCompare(keyword,"area-limit") == 0)
7884 {
7885 MagickSizeType
7886 limit;
7887
7888 limit=MagickResourceInfinity;
7889 if (LocaleCompare(value,"unlimited") != 0)
cristyf2f27272009-12-17 14:48:46 +00007890 limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007891 (void) SetMagickResourceLimit(AreaResource,limit);
7892 break;
7893 }
7894 if (LocaleCompare(keyword,"attenuate") == 0)
7895 {
7896 (void) SetImageOption(image_info,keyword,value);
7897 break;
7898 }
7899 if (LocaleCompare(keyword,"authenticate") == 0)
7900 {
7901 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007902 break;
7903 }
cristyfb758a52009-09-16 14:36:08 +00007904 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7905 break;
7906 }
cristyb20775d2009-09-16 01:51:41 +00007907 case 'B':
7908 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007909 {
cristyb20775d2009-09-16 01:51:41 +00007910 if (LocaleCompare(keyword,"background") == 0)
7911 {
cristy2c8b6312009-09-16 02:37:23 +00007912 (void) QueryColorDatabase(value,&image_info->background_color,
cristyb20775d2009-09-16 01:51:41 +00007913 exception);
7914 break;
7915 }
cristy4582cbb2009-09-23 00:35:43 +00007916 if (LocaleCompare(keyword,"bias") == 0)
7917 {
7918 if (image == (Image *) NULL)
7919 break;
cristyf2f27272009-12-17 14:48:46 +00007920 image->bias=SiPrefixToDouble(value,QuantumRange);
cristy4582cbb2009-09-23 00:35:43 +00007921 break;
7922 }
7923 if (LocaleCompare(keyword,"blue-primary") == 0)
7924 {
7925 if (image == (Image *) NULL)
7926 break;
7927 flags=ParseGeometry(value,&geometry_info);
7928 image->chromaticity.blue_primary.x=geometry_info.rho;
7929 image->chromaticity.blue_primary.y=geometry_info.sigma;
7930 if ((flags & SigmaValue) == 0)
7931 image->chromaticity.blue_primary.y=
7932 image->chromaticity.blue_primary.x;
7933 break;
7934 }
cristy2c8b6312009-09-16 02:37:23 +00007935 if (LocaleCompare(keyword,"bordercolor") == 0)
7936 {
7937 (void) QueryColorDatabase(value,&image_info->border_color,
7938 exception);
7939 break;
7940 }
7941 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7942 break;
7943 }
7944 case 'D':
7945 case 'd':
7946 {
7947 if (LocaleCompare(keyword,"density") == 0)
7948 {
7949 (void) CloneString(&image_info->density,value);
7950 (void) CloneString(&draw_info->density,value);
7951 break;
7952 }
cristyb20775d2009-09-16 01:51:41 +00007953 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7954 break;
7955 }
7956 case 'F':
7957 case 'f':
7958 {
7959 if (LocaleCompare(keyword,"fill") == 0)
7960 {
cristy2c8b6312009-09-16 02:37:23 +00007961 (void) QueryColorDatabase(value,&draw_info->fill,exception);
cristya30afaf2009-09-22 13:42:12 +00007962 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00007963 break;
7964 }
cristy4582cbb2009-09-23 00:35:43 +00007965 if (LocaleCompare(keyword,"filename") == 0)
7966 {
7967 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7968 break;
7969 }
7970 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7971 break;
7972 }
7973 case 'G':
7974 case 'g':
7975 {
7976 if (LocaleCompare(keyword,"gravity") == 0)
7977 {
cristybb503372010-05-27 20:51:26 +00007978 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007979 gravity;
7980
cristy042ee782011-04-22 18:48:30 +00007981 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007982 if (gravity < 0)
7983 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7984 (void) SetImageOption(image_info,keyword,value);
7985 break;
7986 }
cristyb20775d2009-09-16 01:51:41 +00007987 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7988 break;
7989 }
7990 case 'I':
7991 case 'i':
7992 {
7993 if (LocaleCompare(keyword,"id") == 0)
7994 {
cristy4582cbb2009-09-23 00:35:43 +00007995 (void) SetImageProperty(attributes,keyword,value);
cristy2c8b6312009-09-16 02:37:23 +00007996 break;
7997 }
7998 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7999 break;
8000 }
8001 case 'M':
8002 case 'm':
8003 {
8004 if (LocaleCompare(keyword,"magick") == 0)
8005 {
8006 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
8007 break;
8008 }
cristy2c8b6312009-09-16 02:37:23 +00008009 if (LocaleCompare(keyword,"mattecolor") == 0)
8010 {
8011 (void) QueryColorDatabase(value,&image_info->matte_color,
8012 exception);
cristyb20775d2009-09-16 01:51:41 +00008013 break;
8014 }
8015 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8016 break;
8017 }
8018 case 'P':
8019 case 'p':
8020 {
8021 if (LocaleCompare(keyword,"pointsize") == 0)
8022 {
cristyc1acd842011-05-19 23:05:47 +00008023 image_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8024 draw_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
cristyb20775d2009-09-16 01:51:41 +00008025 break;
8026 }
8027 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8028 break;
8029 }
cristy4582cbb2009-09-23 00:35:43 +00008030 case 'Q':
8031 case 'q':
8032 {
8033 if (LocaleCompare(keyword,"quality") == 0)
8034 {
cristyf2f27272009-12-17 14:48:46 +00008035 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008036 if (image == (Image *) NULL)
8037 break;
cristyf2f27272009-12-17 14:48:46 +00008038 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008039 break;
8040 }
8041 break;
8042 }
cristyb20775d2009-09-16 01:51:41 +00008043 case 'S':
8044 case 's':
8045 {
8046 if (LocaleCompare(keyword,"size") == 0)
8047 {
cristy2c8b6312009-09-16 02:37:23 +00008048 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008049 break;
8050 }
8051 if (LocaleCompare(keyword,"stroke") == 0)
8052 {
cristy2c8b6312009-09-16 02:37:23 +00008053 (void) QueryColorDatabase(value,&draw_info->stroke,exception);
cristya30afaf2009-09-22 13:42:12 +00008054 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008055 break;
8056 }
8057 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8058 break;
8059 }
8060 default:
8061 {
8062 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8063 break;
cristyb988fe72009-09-16 01:01:10 +00008064 }
8065 }
8066 return(MagickTrue);
8067}
cristy6b9f7ed2010-04-24 01:08:02 +00008068#endif
cristyb988fe72009-09-16 01:01:10 +00008069
8070/*
8071%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8072% %
8073% %
8074% %
cristy3ed852e2009-09-05 21:47:34 +00008075% U n r e g i s t e r M S L I m a g e %
8076% %
8077% %
8078% %
8079%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8080%
8081% UnregisterMSLImage() removes format registrations made by the
8082% MSL module from the list of supported formats.
8083%
8084% The format of the UnregisterMSLImage method is:
8085%
8086% UnregisterMSLImage(void)
8087%
8088*/
8089ModuleExport void UnregisterMSLImage(void)
8090{
8091 (void) UnregisterMagickInfo("MSL");
8092}
8093
8094#if defined(MAGICKCORE_XML_DELEGATE)
8095/*
8096%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8097% %
8098% %
8099% %
8100% W r i t e M S L I m a g e %
8101% %
8102% %
8103% %
8104%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8105%
8106% WriteMSLImage() writes an image to a file in MVG image format.
8107%
8108% The format of the WriteMSLImage method is:
8109%
8110% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8111%
8112% A description of each parameter follows.
8113%
8114% o image_info: the image info.
8115%
8116% o image: The image.
8117%
8118*/
8119static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8120{
8121 assert(image_info != (const ImageInfo *) NULL);
8122 assert(image_info->signature == MagickSignature);
8123 assert(image != (Image *) NULL);
8124 assert(image->signature == MagickSignature);
8125 if (image->debug != MagickFalse)
8126 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8127 (void) ReferenceImage(image);
8128 (void) ProcessMSLScript(image_info,&image,&image->exception);
8129 return(MagickTrue);
8130}
8131#endif