blob: 46d8c6b029ab35382ff3f435f7bfa90e4655ec53 [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)
cristyab015852011-07-06 01:03:32 +00002056 CompositeImageChannel(image,channel,compose,composite_image,
2057 geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002058 else
2059 {
2060 /*
2061 Rotate image.
2062 */
cristybb503372010-05-27 20:51:26 +00002063 geometry.x-=(ssize_t) (rotate_image->columns-
cristy3ed852e2009-09-05 21:47:34 +00002064 composite_image->columns)/2;
cristybb503372010-05-27 20:51:26 +00002065 geometry.y-=(ssize_t) (rotate_image->rows-composite_image->rows)/2;
cristyab015852011-07-06 01:03:32 +00002066 CompositeImageChannel(image,channel,compose,rotate_image,
2067 geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002068 rotate_image=DestroyImage(rotate_image);
2069 }
2070 composite_image=DestroyImage(composite_image);
2071 break;
2072 }
cristyb988fe72009-09-16 01:01:10 +00002073 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002074 {
2075 MagickBooleanType
2076 sharpen;
2077
2078 /*
2079 Contrast image.
2080 */
2081 if (msl_info->image[n] == (Image *) NULL)
2082 {
cristyb988fe72009-09-16 01:01:10 +00002083 ThrowMSLException(OptionError,"NoImagesDefined",
2084 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002085 break;
2086 }
2087 sharpen=MagickFalse;
2088 if (attributes != (const xmlChar **) NULL)
2089 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2090 {
2091 keyword=(const char *) attributes[i++];
2092 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002093 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002094 CloneString(&value,attribute);
2095 switch (*keyword)
2096 {
2097 case 'S':
2098 case 's':
2099 {
2100 if (LocaleCompare(keyword,"sharpen") == 0)
2101 {
cristy042ee782011-04-22 18:48:30 +00002102 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002103 value);
2104 if (option < 0)
2105 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2106 value);
2107 sharpen=(MagickBooleanType) option;
2108 break;
2109 }
2110 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2111 keyword);
2112 break;
2113 }
2114 default:
2115 {
2116 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2117 keyword);
2118 break;
2119 }
2120 }
2121 }
2122 (void) ContrastImage(msl_info->image[n],sharpen);
2123 break;
2124 }
cristyb988fe72009-09-16 01:01:10 +00002125 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002126 {
2127 Image
2128 *crop_image;
2129
2130 /*
2131 Crop image.
2132 */
2133 if (msl_info->image[n] == (Image *) NULL)
2134 {
cristyb988fe72009-09-16 01:01:10 +00002135 ThrowMSLException(OptionError,"NoImagesDefined",
2136 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002137 break;
2138 }
2139 SetGeometry(msl_info->image[n],&geometry);
2140 if (attributes != (const xmlChar **) NULL)
2141 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2142 {
2143 keyword=(const char *) attributes[i++];
2144 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002145 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002146 CloneString(&value,attribute);
2147 switch (*keyword)
2148 {
2149 case 'G':
2150 case 'g':
2151 {
2152 if (LocaleCompare(keyword,"geometry") == 0)
2153 {
2154 flags=ParsePageGeometry(msl_info->image[n],value,
2155 &geometry,&exception);
2156 if ((flags & HeightValue) == 0)
2157 geometry.height=geometry.width;
2158 break;
2159 }
2160 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2161 keyword);
2162 break;
2163 }
2164 case 'H':
2165 case 'h':
2166 {
2167 if (LocaleCompare(keyword,"height") == 0)
2168 {
cristyf2f27272009-12-17 14:48:46 +00002169 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002170 break;
2171 }
2172 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2173 keyword);
2174 break;
2175 }
2176 case 'W':
2177 case 'w':
2178 {
2179 if (LocaleCompare(keyword,"width") == 0)
2180 {
cristyf2f27272009-12-17 14:48:46 +00002181 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002182 break;
2183 }
2184 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2185 keyword);
2186 break;
2187 }
2188 case 'X':
2189 case 'x':
2190 {
2191 if (LocaleCompare(keyword,"x") == 0)
2192 {
cristyf2f27272009-12-17 14:48:46 +00002193 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002194 break;
2195 }
2196 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2197 keyword);
2198 break;
2199 }
2200 case 'Y':
2201 case 'y':
2202 {
2203 if (LocaleCompare(keyword,"y") == 0)
2204 {
cristyf2f27272009-12-17 14:48:46 +00002205 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002206 break;
2207 }
2208 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2209 keyword);
2210 break;
2211 }
2212 default:
2213 {
2214 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2215 keyword);
2216 break;
2217 }
2218 }
2219 }
2220 crop_image=CropImage(msl_info->image[n],&geometry,
2221 &msl_info->image[n]->exception);
2222 if (crop_image == (Image *) NULL)
2223 break;
2224 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2225 msl_info->image[n]=crop_image;
2226 break;
2227 }
cristyb988fe72009-09-16 01:01:10 +00002228 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002229 {
cristybb503372010-05-27 20:51:26 +00002230 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002231 display;
2232
2233 /*
2234 Cycle-colormap image.
2235 */
2236 if (msl_info->image[n] == (Image *) NULL)
2237 {
cristyb988fe72009-09-16 01:01:10 +00002238 ThrowMSLException(OptionError,"NoImagesDefined",
2239 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002240 break;
2241 }
2242 display=0;
2243 if (attributes != (const xmlChar **) NULL)
2244 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2245 {
2246 keyword=(const char *) attributes[i++];
2247 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002248 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002249 CloneString(&value,attribute);
2250 switch (*keyword)
2251 {
2252 case 'D':
2253 case 'd':
2254 {
2255 if (LocaleCompare(keyword,"display") == 0)
2256 {
cristyf2f27272009-12-17 14:48:46 +00002257 display=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002258 break;
2259 }
2260 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2261 keyword);
2262 break;
2263 }
2264 default:
2265 {
2266 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2267 keyword);
2268 break;
2269 }
2270 }
2271 }
2272 (void) CycleColormapImage(msl_info->image[n],display);
2273 break;
2274 }
2275 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2276 }
2277 case 'D':
2278 case 'd':
2279 {
cristyb988fe72009-09-16 01:01:10 +00002280 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002281 {
2282 Image
2283 *despeckle_image;
2284
2285 /*
2286 Despeckle image.
2287 */
2288 if (msl_info->image[n] == (Image *) NULL)
2289 {
cristyb988fe72009-09-16 01:01:10 +00002290 ThrowMSLException(OptionError,"NoImagesDefined",
2291 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002292 break;
2293 }
2294 if (attributes != (const xmlChar **) NULL)
2295 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2296 {
2297 keyword=(const char *) attributes[i++];
2298 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002299 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002300 CloneString(&value,attribute);
2301 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2302 }
2303 despeckle_image=DespeckleImage(msl_info->image[n],
2304 &msl_info->image[n]->exception);
2305 if (despeckle_image == (Image *) NULL)
2306 break;
2307 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2308 msl_info->image[n]=despeckle_image;
2309 break;
2310 }
cristyb988fe72009-09-16 01:01:10 +00002311 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002312 {
2313 if (msl_info->image[n] == (Image *) NULL)
2314 {
cristyb988fe72009-09-16 01:01:10 +00002315 ThrowMSLException(OptionError,"NoImagesDefined",
2316 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002317 break;
2318 }
2319 if (attributes != (const xmlChar **) NULL)
2320 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2321 {
2322 keyword=(const char *) attributes[i++];
2323 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002324 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002325 CloneString(&value,attribute);
2326 switch (*keyword)
2327 {
2328 default:
2329 {
2330 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2331 keyword);
2332 break;
2333 }
2334 }
2335 }
2336 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n]);
2337 break;
2338 }
cristyb988fe72009-09-16 01:01:10 +00002339 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002340 {
2341 char
2342 text[MaxTextExtent];
2343
2344 /*
2345 Annotate image.
2346 */
2347 if (msl_info->image[n] == (Image *) NULL)
2348 {
cristyb988fe72009-09-16 01:01:10 +00002349 ThrowMSLException(OptionError,"NoImagesDefined",
2350 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002351 break;
2352 }
2353 draw_info=CloneDrawInfo(msl_info->image_info[n],
2354 msl_info->draw_info[n]);
2355 angle=0.0;
2356 current=draw_info->affine;
2357 GetAffineMatrix(&affine);
2358 if (attributes != (const xmlChar **) NULL)
2359 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2360 {
2361 keyword=(const char *) attributes[i++];
2362 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002363 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002364 CloneString(&value,attribute);
2365 switch (*keyword)
2366 {
2367 case 'A':
2368 case 'a':
2369 {
2370 if (LocaleCompare(keyword,"affine") == 0)
2371 {
2372 char
2373 *p;
2374
2375 p=value;
cristyc1acd842011-05-19 23:05:47 +00002376 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002377 if (*p ==',')
2378 p++;
cristyc1acd842011-05-19 23:05:47 +00002379 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002380 if (*p ==',')
2381 p++;
cristyc1acd842011-05-19 23:05:47 +00002382 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002383 if (*p ==',')
2384 p++;
cristyc1acd842011-05-19 23:05:47 +00002385 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002386 if (*p ==',')
2387 p++;
cristyc1acd842011-05-19 23:05:47 +00002388 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002389 if (*p ==',')
2390 p++;
cristyc1acd842011-05-19 23:05:47 +00002391 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002392 break;
2393 }
2394 if (LocaleCompare(keyword,"align") == 0)
2395 {
cristy042ee782011-04-22 18:48:30 +00002396 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002397 value);
2398 if (option < 0)
2399 ThrowMSLException(OptionError,"UnrecognizedAlignType",
2400 value);
2401 draw_info->align=(AlignType) option;
2402 break;
2403 }
2404 if (LocaleCompare(keyword,"antialias") == 0)
2405 {
cristy042ee782011-04-22 18:48:30 +00002406 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002407 value);
2408 if (option < 0)
2409 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2410 value);
2411 draw_info->stroke_antialias=(MagickBooleanType) option;
2412 draw_info->text_antialias=(MagickBooleanType) option;
2413 break;
2414 }
2415 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2416 keyword);
2417 break;
2418 }
2419 case 'D':
2420 case 'd':
2421 {
2422 if (LocaleCompare(keyword,"density") == 0)
2423 {
2424 CloneString(&draw_info->density,value);
2425 break;
2426 }
2427 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2428 keyword);
2429 break;
2430 }
2431 case 'E':
2432 case 'e':
2433 {
2434 if (LocaleCompare(keyword,"encoding") == 0)
2435 {
2436 CloneString(&draw_info->encoding,value);
2437 break;
2438 }
2439 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2440 keyword);
2441 break;
2442 }
2443 case 'F':
2444 case 'f':
2445 {
2446 if (LocaleCompare(keyword, "fill") == 0)
2447 {
2448 (void) QueryColorDatabase(value,&draw_info->fill,
2449 &exception);
2450 break;
2451 }
2452 if (LocaleCompare(keyword,"family") == 0)
2453 {
2454 CloneString(&draw_info->family,value);
2455 break;
2456 }
2457 if (LocaleCompare(keyword,"font") == 0)
2458 {
2459 CloneString(&draw_info->font,value);
2460 break;
2461 }
2462 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2463 keyword);
2464 break;
2465 }
2466 case 'G':
2467 case 'g':
2468 {
2469 if (LocaleCompare(keyword,"geometry") == 0)
2470 {
2471 flags=ParsePageGeometry(msl_info->image[n],value,
2472 &geometry,&exception);
2473 if ((flags & HeightValue) == 0)
2474 geometry.height=geometry.width;
2475 break;
2476 }
2477 if (LocaleCompare(keyword,"gravity") == 0)
2478 {
cristy042ee782011-04-22 18:48:30 +00002479 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002480 value);
2481 if (option < 0)
2482 ThrowMSLException(OptionError,"UnrecognizedGravityType",
2483 value);
2484 draw_info->gravity=(GravityType) option;
2485 break;
2486 }
2487 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2488 keyword);
2489 break;
2490 }
2491 case 'P':
2492 case 'p':
2493 {
2494 if (LocaleCompare(keyword,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002495 {
cristy3ed852e2009-09-05 21:47:34 +00002496 CloneString(&draw_info->primitive,value);
2497 break;
2498 }
2499 if (LocaleCompare(keyword,"pointsize") == 0)
2500 {
cristyc1acd842011-05-19 23:05:47 +00002501 draw_info->pointsize=InterpretLocaleValue(value,
2502 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002503 break;
2504 }
2505 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2506 keyword);
2507 break;
2508 }
2509 case 'R':
2510 case 'r':
2511 {
2512 if (LocaleCompare(keyword,"rotate") == 0)
2513 {
cristyc1acd842011-05-19 23:05:47 +00002514 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002515 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2516 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2517 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2518 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2519 break;
2520 }
2521 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2522 keyword);
2523 break;
2524 }
2525 case 'S':
2526 case 's':
2527 {
2528 if (LocaleCompare(keyword,"scale") == 0)
2529 {
2530 flags=ParseGeometry(value,&geometry_info);
2531 if ((flags & SigmaValue) == 0)
2532 geometry_info.sigma=1.0;
2533 affine.sx=geometry_info.rho;
2534 affine.sy=geometry_info.sigma;
2535 break;
2536 }
2537 if (LocaleCompare(keyword,"skewX") == 0)
2538 {
cristyc1acd842011-05-19 23:05:47 +00002539 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002540 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2541 break;
2542 }
2543 if (LocaleCompare(keyword,"skewY") == 0)
2544 {
cristyc1acd842011-05-19 23:05:47 +00002545 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002546 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2547 break;
2548 }
2549 if (LocaleCompare(keyword,"stretch") == 0)
2550 {
cristy042ee782011-04-22 18:48:30 +00002551 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002552 value);
2553 if (option < 0)
2554 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2555 value);
2556 draw_info->stretch=(StretchType) option;
2557 break;
2558 }
2559 if (LocaleCompare(keyword, "stroke") == 0)
2560 {
2561 (void) QueryColorDatabase(value,&draw_info->stroke,
2562 &exception);
2563 break;
2564 }
2565 if (LocaleCompare(keyword,"strokewidth") == 0)
2566 {
cristyf2f27272009-12-17 14:48:46 +00002567 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002568 break;
2569 }
2570 if (LocaleCompare(keyword,"style") == 0)
2571 {
cristy042ee782011-04-22 18:48:30 +00002572 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002573 value);
2574 if (option < 0)
2575 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2576 value);
2577 draw_info->style=(StyleType) option;
2578 break;
2579 }
2580 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2581 keyword);
2582 break;
2583 }
2584 case 'T':
2585 case 't':
2586 {
2587 if (LocaleCompare(keyword,"text") == 0)
2588 {
2589 CloneString(&draw_info->text,value);
2590 break;
2591 }
2592 if (LocaleCompare(keyword,"translate") == 0)
2593 {
2594 flags=ParseGeometry(value,&geometry_info);
2595 if ((flags & SigmaValue) == 0)
2596 geometry_info.sigma=1.0;
2597 affine.tx=geometry_info.rho;
2598 affine.ty=geometry_info.sigma;
2599 break;
2600 }
2601 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2602 keyword);
2603 break;
2604 }
2605 case 'U':
2606 case 'u':
2607 {
2608 if (LocaleCompare(keyword, "undercolor") == 0)
2609 {
2610 (void) QueryColorDatabase(value,&draw_info->undercolor,
2611 &exception);
2612 break;
2613 }
2614 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2615 keyword);
2616 break;
2617 }
2618 case 'W':
2619 case 'w':
2620 {
2621 if (LocaleCompare(keyword,"weight") == 0)
2622 {
cristyf2f27272009-12-17 14:48:46 +00002623 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002624 break;
2625 }
2626 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2627 keyword);
2628 break;
2629 }
2630 case 'X':
2631 case 'x':
2632 {
2633 if (LocaleCompare(keyword,"x") == 0)
2634 {
cristyf2f27272009-12-17 14:48:46 +00002635 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002636 break;
2637 }
2638 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2639 keyword);
2640 break;
2641 }
2642 case 'Y':
2643 case 'y':
2644 {
2645 if (LocaleCompare(keyword,"y") == 0)
2646 {
cristyf2f27272009-12-17 14:48:46 +00002647 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002648 break;
2649 }
2650 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2651 keyword);
2652 break;
2653 }
2654 default:
2655 {
2656 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2657 keyword);
2658 break;
2659 }
2660 }
2661 }
cristyb51dff52011-05-19 16:55:47 +00002662 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002663 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2664 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002665 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002666 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2667 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2668 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2669 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2670 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2671 affine.tx;
2672 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2673 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00002674 (void) DrawImage(msl_info->image[n],draw_info);
2675 draw_info=DestroyDrawInfo(draw_info);
2676 break;
2677 }
2678 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2679 }
2680 case 'E':
2681 case 'e':
2682 {
cristyb988fe72009-09-16 01:01:10 +00002683 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002684 {
2685 Image
2686 *edge_image;
2687
2688 /*
2689 Edge image.
2690 */
2691 if (msl_info->image[n] == (Image *) NULL)
2692 {
cristyb988fe72009-09-16 01:01:10 +00002693 ThrowMSLException(OptionError,"NoImagesDefined",
2694 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002695 break;
2696 }
2697 if (attributes != (const xmlChar **) NULL)
2698 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2699 {
2700 keyword=(const char *) attributes[i++];
2701 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002702 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002703 CloneString(&value,attribute);
2704 switch (*keyword)
2705 {
2706 case 'G':
2707 case 'g':
2708 {
2709 if (LocaleCompare(keyword,"geometry") == 0)
2710 {
2711 flags=ParseGeometry(value,&geometry_info);
2712 if ((flags & SigmaValue) == 0)
2713 geometry_info.sigma=1.0;
2714 break;
2715 }
2716 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2717 keyword);
2718 break;
2719 }
2720 case 'R':
2721 case 'r':
2722 {
2723 if (LocaleCompare(keyword,"radius") == 0)
2724 {
cristyc1acd842011-05-19 23:05:47 +00002725 geometry_info.rho=InterpretLocaleValue(value,
2726 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002727 break;
2728 }
2729 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2730 keyword);
2731 break;
2732 }
2733 default:
2734 {
2735 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2736 keyword);
2737 break;
2738 }
2739 }
2740 }
2741 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
2742 &msl_info->image[n]->exception);
2743 if (edge_image == (Image *) NULL)
2744 break;
2745 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2746 msl_info->image[n]=edge_image;
2747 break;
2748 }
cristyb988fe72009-09-16 01:01:10 +00002749 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002750 {
2751 Image
2752 *emboss_image;
2753
2754 /*
2755 Emboss image.
2756 */
2757 if (msl_info->image[n] == (Image *) NULL)
2758 {
cristyb988fe72009-09-16 01:01:10 +00002759 ThrowMSLException(OptionError,"NoImagesDefined",
2760 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002761 break;
2762 }
2763 if (attributes != (const xmlChar **) NULL)
2764 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2765 {
2766 keyword=(const char *) attributes[i++];
2767 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002768 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002769 CloneString(&value,attribute);
2770 switch (*keyword)
2771 {
2772 case 'G':
2773 case 'g':
2774 {
2775 if (LocaleCompare(keyword,"geometry") == 0)
2776 {
2777 flags=ParseGeometry(value,&geometry_info);
2778 if ((flags & SigmaValue) == 0)
2779 geometry_info.sigma=1.0;
2780 break;
2781 }
2782 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2783 keyword);
2784 break;
2785 }
2786 case 'R':
2787 case 'r':
2788 {
2789 if (LocaleCompare(keyword,"radius") == 0)
2790 {
cristyc1acd842011-05-19 23:05:47 +00002791 geometry_info.rho=InterpretLocaleValue(value,
2792 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002793 break;
2794 }
2795 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2796 keyword);
2797 break;
2798 }
2799 case 'S':
2800 case 's':
2801 {
2802 if (LocaleCompare(keyword,"sigma") == 0)
2803 {
cristyf2f27272009-12-17 14:48:46 +00002804 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002805 break;
2806 }
2807 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2808 keyword);
2809 break;
2810 }
2811 default:
2812 {
2813 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2814 keyword);
2815 break;
2816 }
2817 }
2818 }
2819 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2820 geometry_info.sigma,&msl_info->image[n]->exception);
2821 if (emboss_image == (Image *) NULL)
2822 break;
2823 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2824 msl_info->image[n]=emboss_image;
2825 break;
2826 }
cristyb988fe72009-09-16 01:01:10 +00002827 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002828 {
2829 Image
2830 *enhance_image;
2831
2832 /*
2833 Enhance image.
2834 */
2835 if (msl_info->image[n] == (Image *) NULL)
2836 {
cristyb988fe72009-09-16 01:01:10 +00002837 ThrowMSLException(OptionError,"NoImagesDefined",
2838 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002839 break;
2840 }
2841 if (attributes != (const xmlChar **) NULL)
2842 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2843 {
2844 keyword=(const char *) attributes[i++];
2845 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002846 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002847 CloneString(&value,attribute);
2848 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2849 }
2850 enhance_image=EnhanceImage(msl_info->image[n],
2851 &msl_info->image[n]->exception);
2852 if (enhance_image == (Image *) NULL)
2853 break;
2854 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2855 msl_info->image[n]=enhance_image;
2856 break;
2857 }
cristyb988fe72009-09-16 01:01:10 +00002858 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002859 {
2860 /*
2861 Equalize image.
2862 */
2863 if (msl_info->image[n] == (Image *) NULL)
2864 {
cristyb988fe72009-09-16 01:01:10 +00002865 ThrowMSLException(OptionError,"NoImagesDefined",
2866 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002867 break;
2868 }
2869 if (attributes != (const xmlChar **) NULL)
2870 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2871 {
2872 keyword=(const char *) attributes[i++];
2873 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002874 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002875 CloneString(&value,attribute);
2876 switch (*keyword)
2877 {
2878 default:
2879 {
2880 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2881 keyword);
2882 break;
2883 }
2884 }
2885 }
2886 (void) EqualizeImage(msl_info->image[n]);
2887 break;
2888 }
2889 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2890 }
2891 case 'F':
2892 case 'f':
2893 {
cristyb988fe72009-09-16 01:01:10 +00002894 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002895 {
2896 if (msl_info->image[n] == (Image *) NULL)
2897 {
cristyb988fe72009-09-16 01:01:10 +00002898 ThrowMSLException(OptionError,"NoImagesDefined",
2899 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002900 break;
2901 }
2902
2903 /* no attributes here */
2904
2905 /* process the image */
2906 {
2907 Image
2908 *newImage;
2909
2910 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2911 &msl_info->image[n]->exception);
2912 if (newImage == (Image *) NULL)
2913 break;
2914 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2915 msl_info->image[n]=newImage;
2916 break;
2917 }
2918 }
cristyb988fe72009-09-16 01:01:10 +00002919 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002920 {
2921 Image
2922 *flip_image;
2923
2924 /*
2925 Flip image.
2926 */
2927 if (msl_info->image[n] == (Image *) NULL)
2928 {
cristyb988fe72009-09-16 01:01:10 +00002929 ThrowMSLException(OptionError,"NoImagesDefined",
2930 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002931 break;
2932 }
2933 if (attributes != (const xmlChar **) NULL)
2934 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2935 {
2936 keyword=(const char *) attributes[i++];
2937 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002938 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002939 CloneString(&value,attribute);
2940 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2941 }
2942 flip_image=FlipImage(msl_info->image[n],
2943 &msl_info->image[n]->exception);
2944 if (flip_image == (Image *) NULL)
2945 break;
2946 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2947 msl_info->image[n]=flip_image;
2948 break;
2949 }
cristyb988fe72009-09-16 01:01:10 +00002950 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002951 {
2952 Image
2953 *flop_image;
2954
2955 /*
2956 Flop image.
2957 */
2958 if (msl_info->image[n] == (Image *) NULL)
2959 {
cristyb988fe72009-09-16 01:01:10 +00002960 ThrowMSLException(OptionError,"NoImagesDefined",
2961 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002962 break;
2963 }
2964 if (attributes != (const xmlChar **) NULL)
2965 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2966 {
2967 keyword=(const char *) attributes[i++];
2968 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002969 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002970 CloneString(&value,attribute);
2971 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2972 }
2973 flop_image=FlopImage(msl_info->image[n],
2974 &msl_info->image[n]->exception);
2975 if (flop_image == (Image *) NULL)
2976 break;
2977 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2978 msl_info->image[n]=flop_image;
2979 break;
2980 }
cristyb988fe72009-09-16 01:01:10 +00002981 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002982 {
2983 FrameInfo
2984 frame_info;
2985
2986 Image
2987 *frame_image;
2988
2989 /*
2990 Frame image.
2991 */
2992 if (msl_info->image[n] == (Image *) NULL)
2993 {
cristyb988fe72009-09-16 01:01:10 +00002994 ThrowMSLException(OptionError,"NoImagesDefined",
2995 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002996 break;
2997 }
2998 SetGeometry(msl_info->image[n],&geometry);
2999 if (attributes != (const xmlChar **) NULL)
3000 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3001 {
3002 keyword=(const char *) attributes[i++];
3003 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003004 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003005 CloneString(&value,attribute);
3006 switch (*keyword)
3007 {
3008 case 'C':
3009 case 'c':
3010 {
3011 if (LocaleCompare(keyword,"compose") == 0)
3012 {
cristy042ee782011-04-22 18:48:30 +00003013 option=ParseCommandOption(MagickComposeOptions,
cristy3ed852e2009-09-05 21:47:34 +00003014 MagickFalse,value);
3015 if (option < 0)
3016 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3017 value);
3018 msl_info->image[n]->compose=(CompositeOperator) option;
3019 break;
3020 }
3021 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3022 keyword);
3023 break;
3024 }
3025 case 'F':
3026 case 'f':
3027 {
3028 if (LocaleCompare(keyword, "fill") == 0)
3029 {
3030 (void) QueryColorDatabase(value,
3031 &msl_info->image[n]->matte_color,&exception);
3032 break;
3033 }
3034 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3035 keyword);
3036 break;
3037 }
3038 case 'G':
3039 case 'g':
3040 {
3041 if (LocaleCompare(keyword,"geometry") == 0)
3042 {
3043 flags=ParsePageGeometry(msl_info->image[n],value,
3044 &geometry,&exception);
3045 if ((flags & HeightValue) == 0)
3046 geometry.height=geometry.width;
3047 frame_info.width=geometry.width;
3048 frame_info.height=geometry.height;
3049 frame_info.outer_bevel=geometry.x;
3050 frame_info.inner_bevel=geometry.y;
3051 break;
3052 }
3053 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3054 keyword);
3055 break;
3056 }
3057 case 'H':
3058 case 'h':
3059 {
3060 if (LocaleCompare(keyword,"height") == 0)
3061 {
cristyf2f27272009-12-17 14:48:46 +00003062 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003063 break;
3064 }
3065 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3066 keyword);
3067 break;
3068 }
3069 case 'I':
3070 case 'i':
3071 {
3072 if (LocaleCompare(keyword,"inner") == 0)
3073 {
cristyf2f27272009-12-17 14:48:46 +00003074 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003075 break;
3076 }
3077 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3078 keyword);
3079 break;
3080 }
3081 case 'O':
3082 case 'o':
3083 {
3084 if (LocaleCompare(keyword,"outer") == 0)
3085 {
cristyf2f27272009-12-17 14:48:46 +00003086 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003087 break;
3088 }
3089 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3090 keyword);
3091 break;
3092 }
3093 case 'W':
3094 case 'w':
3095 {
3096 if (LocaleCompare(keyword,"width") == 0)
3097 {
cristyf2f27272009-12-17 14:48:46 +00003098 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003099 break;
3100 }
3101 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3102 keyword);
3103 break;
3104 }
3105 default:
3106 {
3107 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3108 keyword);
3109 break;
3110 }
3111 }
3112 }
cristybb503372010-05-27 20:51:26 +00003113 frame_info.x=(ssize_t) frame_info.width;
3114 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003115 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3116 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3117 frame_image=FrameImage(msl_info->image[n],&frame_info,
3118 &msl_info->image[n]->exception);
3119 if (frame_image == (Image *) NULL)
3120 break;
3121 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3122 msl_info->image[n]=frame_image;
3123 break;
3124 }
3125 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3126 }
3127 case 'G':
3128 case 'g':
3129 {
cristyb988fe72009-09-16 01:01:10 +00003130 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003131 {
3132 char
3133 gamma[MaxTextExtent];
3134
cristy4c08aed2011-07-01 19:47:50 +00003135 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003136 pixel;
3137
3138 /*
3139 Gamma image.
3140 */
3141 if (msl_info->image[n] == (Image *) NULL)
3142 {
cristyb988fe72009-09-16 01:01:10 +00003143 ThrowMSLException(OptionError,"NoImagesDefined",
3144 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003145 break;
3146 }
3147 channel=UndefinedChannel;
3148 pixel.red=0.0;
3149 pixel.green=0.0;
3150 pixel.blue=0.0;
3151 *gamma='\0';
3152 if (attributes != (const xmlChar **) NULL)
3153 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3154 {
3155 keyword=(const char *) attributes[i++];
3156 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003157 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003158 CloneString(&value,attribute);
3159 switch (*keyword)
3160 {
3161 case 'B':
3162 case 'b':
3163 {
3164 if (LocaleCompare(keyword,"blue") == 0)
3165 {
cristyc1acd842011-05-19 23:05:47 +00003166 pixel.blue=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003167 break;
3168 }
3169 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3170 keyword);
3171 break;
3172 }
3173 case 'C':
3174 case 'c':
3175 {
3176 if (LocaleCompare(keyword,"channel") == 0)
3177 {
3178 option=ParseChannelOption(value);
3179 if (option < 0)
3180 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3181 value);
3182 channel=(ChannelType) option;
3183 break;
3184 }
3185 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3186 keyword);
3187 break;
3188 }
3189 case 'G':
3190 case 'g':
3191 {
3192 if (LocaleCompare(keyword,"gamma") == 0)
3193 {
3194 (void) CopyMagickString(gamma,value,MaxTextExtent);
3195 break;
3196 }
3197 if (LocaleCompare(keyword,"green") == 0)
3198 {
cristyc1acd842011-05-19 23:05:47 +00003199 pixel.green=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003200 break;
3201 }
3202 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3203 keyword);
3204 break;
3205 }
3206 case 'R':
3207 case 'r':
3208 {
3209 if (LocaleCompare(keyword,"red") == 0)
3210 {
cristyc1acd842011-05-19 23:05:47 +00003211 pixel.red=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003212 break;
3213 }
3214 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3215 keyword);
3216 break;
3217 }
3218 default:
3219 {
3220 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3221 keyword);
3222 break;
3223 }
3224 }
3225 }
3226 if (*gamma == '\0')
cristyb51dff52011-05-19 16:55:47 +00003227 (void) FormatLocaleString(gamma,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003228 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb988fe72009-09-16 01:01:10 +00003229 switch (channel)
cristy3ed852e2009-09-05 21:47:34 +00003230 {
3231 default:
3232 {
3233 (void) GammaImage(msl_info->image[n],gamma);
3234 break;
3235 }
3236 case RedChannel:
3237 {
3238 (void) GammaImageChannel(msl_info->image[n],RedChannel,pixel.red);
3239 break;
3240 }
3241 case GreenChannel:
3242 {
3243 (void) GammaImageChannel(msl_info->image[n],GreenChannel,
3244 pixel.green);
3245 break;
3246 }
3247 case BlueChannel:
3248 {
3249 (void) GammaImageChannel(msl_info->image[n],BlueChannel,
3250 pixel.blue);
3251 break;
3252 }
3253 }
3254 break;
3255 }
cristyb988fe72009-09-16 01:01:10 +00003256 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003257 {
3258 if (msl_info->image[n] == (Image *) NULL)
3259 {
cristyb988fe72009-09-16 01:01:10 +00003260 ThrowMSLException(OptionError,"NoImagesDefined",
3261 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003262 break;
3263 }
3264 if (attributes == (const xmlChar **) NULL)
3265 break;
3266 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3267 {
3268 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003269 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003270 (void) CopyMagickString(key,value,MaxTextExtent);
3271 switch (*keyword)
3272 {
3273 case 'H':
3274 case 'h':
3275 {
3276 if (LocaleCompare(keyword,"height") == 0)
3277 {
cristyb51dff52011-05-19 16:55:47 +00003278 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003279 (double) msl_info->image[n]->rows);
cristy3ed852e2009-09-05 21:47:34 +00003280 (void) SetImageProperty(msl_info->attributes[n],key,value);
3281 break;
3282 }
3283 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3284 }
3285 case 'W':
3286 case 'w':
3287 {
3288 if (LocaleCompare(keyword,"width") == 0)
3289 {
cristyb51dff52011-05-19 16:55:47 +00003290 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003291 (double) msl_info->image[n]->columns);
cristy3ed852e2009-09-05 21:47:34 +00003292 (void) SetImageProperty(msl_info->attributes[n],key,value);
3293 break;
3294 }
3295 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3296 }
3297 default:
3298 {
3299 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3300 break;
3301 }
3302 }
3303 }
3304 break;
3305 }
cristyb988fe72009-09-16 01:01:10 +00003306 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003307 {
3308 msl_info->number_groups++;
3309 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3310 msl_info->group_info,msl_info->number_groups+1UL,
3311 sizeof(*msl_info->group_info));
3312 break;
3313 }
3314 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3315 }
3316 case 'I':
3317 case 'i':
3318 {
cristyb988fe72009-09-16 01:01:10 +00003319 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003320 {
cristy3ed852e2009-09-05 21:47:34 +00003321 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003322 if (attributes == (const xmlChar **) NULL)
3323 break;
3324 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3325 {
3326 keyword=(const char *) attributes[i++];
3327 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003328 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00003329 switch (*keyword)
3330 {
cristyb988fe72009-09-16 01:01:10 +00003331 case 'C':
3332 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003333 {
cristyb988fe72009-09-16 01:01:10 +00003334 if (LocaleCompare(keyword,"color") == 0)
3335 {
3336 Image
3337 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003338
cristyb988fe72009-09-16 01:01:10 +00003339 (void) CopyMagickString(msl_info->image_info[n]->filename,
3340 "xc:",MaxTextExtent);
3341 (void) ConcatenateMagickString(msl_info->image_info[n]->
3342 filename,value,MaxTextExtent);
3343 next_image=ReadImage(msl_info->image_info[n],&exception);
3344 CatchException(&exception);
3345 if (next_image == (Image *) NULL)
3346 continue;
3347 if (msl_info->image[n] == (Image *) NULL)
3348 msl_info->image[n]=next_image;
3349 else
3350 {
3351 register Image
3352 *p;
cristy3ed852e2009-09-05 21:47:34 +00003353
cristyb988fe72009-09-16 01:01:10 +00003354 /*
3355 Link image into image list.
3356 */
3357 p=msl_info->image[n];
3358 while (p->next != (Image *) NULL)
3359 p=GetNextImageInList(p);
3360 next_image->previous=p;
3361 p->next=next_image;
3362 }
3363 break;
3364 }
cristyb20775d2009-09-16 01:51:41 +00003365 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003366 break;
3367 }
3368 default:
3369 {
cristyb20775d2009-09-16 01:51:41 +00003370 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003371 break;
3372 }
3373 }
3374 }
3375 break;
3376 }
cristyb988fe72009-09-16 01:01:10 +00003377 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003378 {
3379 Image
3380 *implode_image;
3381
3382 /*
3383 Implode image.
3384 */
3385 if (msl_info->image[n] == (Image *) NULL)
3386 {
cristyb988fe72009-09-16 01:01:10 +00003387 ThrowMSLException(OptionError,"NoImagesDefined",
3388 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003389 break;
3390 }
3391 if (attributes != (const xmlChar **) NULL)
3392 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3393 {
3394 keyword=(const char *) attributes[i++];
3395 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003396 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003397 CloneString(&value,attribute);
3398 switch (*keyword)
3399 {
3400 case 'A':
3401 case 'a':
3402 {
3403 if (LocaleCompare(keyword,"amount") == 0)
3404 {
cristyc1acd842011-05-19 23:05:47 +00003405 geometry_info.rho=InterpretLocaleValue(value,
3406 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003407 break;
3408 }
3409 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3410 keyword);
3411 break;
3412 }
3413 case 'G':
3414 case 'g':
3415 {
3416 if (LocaleCompare(keyword,"geometry") == 0)
3417 {
3418 flags=ParseGeometry(value,&geometry_info);
3419 if ((flags & SigmaValue) == 0)
3420 geometry_info.sigma=1.0;
3421 break;
3422 }
3423 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3424 keyword);
3425 break;
3426 }
3427 default:
3428 {
3429 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3430 keyword);
3431 break;
3432 }
3433 }
3434 }
3435 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3436 &msl_info->image[n]->exception);
3437 if (implode_image == (Image *) NULL)
3438 break;
3439 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3440 msl_info->image[n]=implode_image;
3441 break;
3442 }
3443 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3444 }
3445 case 'L':
3446 case 'l':
3447 {
cristyb988fe72009-09-16 01:01:10 +00003448 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003449 break;
cristyb988fe72009-09-16 01:01:10 +00003450 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003451 {
3452 double
3453 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3454
3455 if (msl_info->image[n] == (Image *) NULL)
3456 {
cristyb988fe72009-09-16 01:01:10 +00003457 ThrowMSLException(OptionError,"NoImagesDefined",
3458 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003459 break;
3460 }
3461 if (attributes == (const xmlChar **) NULL)
3462 break;
3463 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3464 {
3465 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003466 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003467 (void) CopyMagickString(key,value,MaxTextExtent);
3468 switch (*keyword)
3469 {
3470 case 'B':
3471 case 'b':
3472 {
3473 if (LocaleCompare(keyword,"black") == 0)
3474 {
cristyc1acd842011-05-19 23:05:47 +00003475 levelBlack = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003476 break;
3477 }
3478 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3479 break;
3480 }
3481 case 'G':
3482 case 'g':
3483 {
3484 if (LocaleCompare(keyword,"gamma") == 0)
3485 {
cristyc1acd842011-05-19 23:05:47 +00003486 levelGamma = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003487 break;
3488 }
3489 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3490 break;
3491 }
3492 case 'W':
3493 case 'w':
3494 {
3495 if (LocaleCompare(keyword,"white") == 0)
3496 {
cristyc1acd842011-05-19 23:05:47 +00003497 levelWhite = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003498 break;
3499 }
3500 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3501 break;
3502 }
3503 default:
3504 {
3505 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3506 break;
3507 }
3508 }
3509 }
3510
3511 /* process image */
3512 {
3513 char level[MaxTextExtent + 1];
cristyb51dff52011-05-19 16:55:47 +00003514 (void) FormatLocaleString(level,MaxTextExtent,"%3.6f/%3.6f/%3.6f/",
cristy3ed852e2009-09-05 21:47:34 +00003515 levelBlack,levelGamma,levelWhite);
3516 LevelImage ( msl_info->image[n], level );
3517 break;
3518 }
3519 }
3520 }
3521 case 'M':
3522 case 'm':
3523 {
cristyb988fe72009-09-16 01:01:10 +00003524 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003525 {
3526 Image
3527 *magnify_image;
3528
3529 /*
3530 Magnify image.
3531 */
3532 if (msl_info->image[n] == (Image *) NULL)
3533 {
cristyb988fe72009-09-16 01:01:10 +00003534 ThrowMSLException(OptionError,"NoImagesDefined",
3535 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003536 break;
3537 }
3538 if (attributes != (const xmlChar **) NULL)
3539 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3540 {
3541 keyword=(const char *) attributes[i++];
3542 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003543 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003544 CloneString(&value,attribute);
3545 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3546 }
3547 magnify_image=MagnifyImage(msl_info->image[n],
3548 &msl_info->image[n]->exception);
3549 if (magnify_image == (Image *) NULL)
3550 break;
3551 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3552 msl_info->image[n]=magnify_image;
3553 break;
3554 }
cristyb988fe72009-09-16 01:01:10 +00003555 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003556 {
3557 Image
3558 *affinity_image;
3559
3560 MagickBooleanType
3561 dither;
3562
3563 QuantizeInfo
3564 *quantize_info;
3565
3566 /*
3567 Map image.
3568 */
3569 if (msl_info->image[n] == (Image *) NULL)
3570 {
cristyb988fe72009-09-16 01:01:10 +00003571 ThrowMSLException(OptionError,"NoImagesDefined",
3572 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003573 break;
3574 }
3575 affinity_image=NewImageList();
3576 dither=MagickFalse;
3577 if (attributes != (const xmlChar **) NULL)
3578 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3579 {
3580 keyword=(const char *) attributes[i++];
3581 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003582 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003583 CloneString(&value,attribute);
3584 switch (*keyword)
3585 {
3586 case 'D':
3587 case 'd':
3588 {
3589 if (LocaleCompare(keyword,"dither") == 0)
3590 {
cristy042ee782011-04-22 18:48:30 +00003591 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003592 value);
3593 if (option < 0)
3594 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3595 value);
3596 dither=(MagickBooleanType) option;
3597 break;
3598 }
3599 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3600 keyword);
3601 break;
3602 }
3603 case 'I':
3604 case 'i':
3605 {
3606 if (LocaleCompare(keyword,"image") == 0)
3607 for (j=0; j < msl_info->n; j++)
3608 {
3609 const char
3610 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003611
cristy3ed852e2009-09-05 21:47:34 +00003612 attribute=GetImageProperty(msl_info->attributes[j],"id");
3613 if ((attribute != (const char *) NULL) &&
3614 (LocaleCompare(attribute,value) == 0))
3615 {
3616 affinity_image=CloneImage(msl_info->image[j],0,0,
3617 MagickFalse,&exception);
3618 break;
3619 }
3620 }
3621 break;
3622 }
3623 default:
3624 {
3625 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3626 keyword);
3627 break;
3628 }
3629 }
3630 }
3631 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3632 quantize_info->dither=dither;
3633 (void) RemapImages(quantize_info,msl_info->image[n],
3634 affinity_image);
3635 quantize_info=DestroyQuantizeInfo(quantize_info);
3636 affinity_image=DestroyImage(affinity_image);
3637 break;
3638 }
cristyb988fe72009-09-16 01:01:10 +00003639 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003640 {
3641 double
3642 opacity;
3643
cristy4c08aed2011-07-01 19:47:50 +00003644 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003645 target;
3646
3647 PaintMethod
3648 paint_method;
3649
3650 /*
3651 Matte floodfill image.
3652 */
3653 opacity=0.0;
3654 if (msl_info->image[n] == (Image *) NULL)
3655 {
cristyb988fe72009-09-16 01:01:10 +00003656 ThrowMSLException(OptionError,"NoImagesDefined",
3657 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003658 break;
3659 }
3660 SetGeometry(msl_info->image[n],&geometry);
3661 paint_method=FloodfillMethod;
3662 if (attributes != (const xmlChar **) NULL)
3663 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3664 {
3665 keyword=(const char *) attributes[i++];
3666 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003667 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003668 CloneString(&value,attribute);
3669 switch (*keyword)
3670 {
3671 case 'B':
3672 case 'b':
3673 {
3674 if (LocaleCompare(keyword,"bordercolor") == 0)
3675 {
3676 (void) QueryMagickColor(value,&target,&exception);
3677 paint_method=FillToBorderMethod;
3678 break;
3679 }
3680 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3681 keyword);
3682 break;
3683 }
3684 case 'F':
3685 case 'f':
3686 {
3687 if (LocaleCompare(keyword,"fuzz") == 0)
3688 {
cristyc1acd842011-05-19 23:05:47 +00003689 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
3690 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003691 break;
3692 }
3693 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3694 keyword);
3695 break;
3696 }
3697 case 'G':
3698 case 'g':
3699 {
3700 if (LocaleCompare(keyword,"geometry") == 0)
3701 {
3702 flags=ParsePageGeometry(msl_info->image[n],value,
3703 &geometry,&exception);
3704 if ((flags & HeightValue) == 0)
3705 geometry.height=geometry.width;
3706 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3707 geometry.x,geometry.y,&target,&exception);
3708 break;
3709 }
3710 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3711 keyword);
3712 break;
3713 }
3714 case 'O':
3715 case 'o':
3716 {
3717 if (LocaleCompare(keyword,"opacity") == 0)
3718 {
cristyc1acd842011-05-19 23:05:47 +00003719 opacity=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003720 break;
3721 }
3722 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3723 keyword);
3724 break;
3725 }
3726 case 'X':
3727 case 'x':
3728 {
3729 if (LocaleCompare(keyword,"x") == 0)
3730 {
cristyf2f27272009-12-17 14:48:46 +00003731 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003732 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3733 geometry.x,geometry.y,&target,&exception);
3734 break;
3735 }
3736 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3737 keyword);
3738 break;
3739 }
3740 case 'Y':
3741 case 'y':
3742 {
3743 if (LocaleCompare(keyword,"y") == 0)
3744 {
cristyf2f27272009-12-17 14:48:46 +00003745 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003746 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3747 geometry.x,geometry.y,&target,&exception);
3748 break;
3749 }
3750 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3751 keyword);
3752 break;
3753 }
3754 default:
3755 {
3756 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3757 keyword);
3758 break;
3759 }
3760 }
3761 }
3762 draw_info=CloneDrawInfo(msl_info->image_info[n],
3763 msl_info->draw_info[n]);
cristy4c08aed2011-07-01 19:47:50 +00003764 draw_info->fill.alpha=ClampToQuantum(opacity);
cristy3ed852e2009-09-05 21:47:34 +00003765 (void) FloodfillPaintImage(msl_info->image[n],OpacityChannel,
3766 draw_info,&target,geometry.x,geometry.y,
3767 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
3768 draw_info=DestroyDrawInfo(draw_info);
3769 break;
3770 }
cristyb988fe72009-09-16 01:01:10 +00003771 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003772 {
3773 Image
3774 *median_image;
3775
3776 /*
3777 Median-filter image.
3778 */
3779 if (msl_info->image[n] == (Image *) NULL)
3780 {
cristyb988fe72009-09-16 01:01:10 +00003781 ThrowMSLException(OptionError,"NoImagesDefined",
3782 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003783 break;
3784 }
3785 if (attributes != (const xmlChar **) NULL)
3786 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3787 {
3788 keyword=(const char *) attributes[i++];
3789 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003790 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003791 CloneString(&value,attribute);
3792 switch (*keyword)
3793 {
3794 case 'G':
3795 case 'g':
3796 {
3797 if (LocaleCompare(keyword,"geometry") == 0)
3798 {
3799 flags=ParseGeometry(value,&geometry_info);
3800 if ((flags & SigmaValue) == 0)
3801 geometry_info.sigma=1.0;
3802 break;
3803 }
3804 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3805 keyword);
3806 break;
3807 }
3808 case 'R':
3809 case 'r':
3810 {
3811 if (LocaleCompare(keyword,"radius") == 0)
3812 {
cristyc1acd842011-05-19 23:05:47 +00003813 geometry_info.rho=InterpretLocaleValue(value,
3814 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003815 break;
3816 }
3817 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3818 keyword);
3819 break;
3820 }
3821 default:
3822 {
3823 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3824 keyword);
3825 break;
3826 }
3827 }
3828 }
cristy733678d2011-03-18 21:29:28 +00003829 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003830 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3831 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003832 if (median_image == (Image *) NULL)
3833 break;
3834 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3835 msl_info->image[n]=median_image;
3836 break;
3837 }
cristyb988fe72009-09-16 01:01:10 +00003838 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003839 {
3840 Image
3841 *minify_image;
3842
3843 /*
3844 Minify image.
3845 */
3846 if (msl_info->image[n] == (Image *) NULL)
3847 {
cristyb988fe72009-09-16 01:01:10 +00003848 ThrowMSLException(OptionError,"NoImagesDefined",
3849 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003850 break;
3851 }
3852 if (attributes != (const xmlChar **) NULL)
3853 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3854 {
3855 keyword=(const char *) attributes[i++];
3856 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003857 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003858 CloneString(&value,attribute);
3859 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3860 }
3861 minify_image=MinifyImage(msl_info->image[n],
3862 &msl_info->image[n]->exception);
3863 if (minify_image == (Image *) NULL)
3864 break;
3865 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3866 msl_info->image[n]=minify_image;
3867 break;
3868 }
cristyb988fe72009-09-16 01:01:10 +00003869 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003870 break;
cristyb988fe72009-09-16 01:01:10 +00003871 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003872 {
3873 char
3874 modulate[MaxTextExtent];
3875
3876 /*
3877 Modulate image.
3878 */
3879 if (msl_info->image[n] == (Image *) NULL)
3880 {
cristyb988fe72009-09-16 01:01:10 +00003881 ThrowMSLException(OptionError,"NoImagesDefined",
3882 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003883 break;
3884 }
3885 geometry_info.rho=100.0;
3886 geometry_info.sigma=100.0;
3887 geometry_info.xi=100.0;
3888 if (attributes != (const xmlChar **) NULL)
3889 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3890 {
3891 keyword=(const char *) attributes[i++];
3892 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003893 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003894 CloneString(&value,attribute);
3895 switch (*keyword)
3896 {
3897 case 'B':
3898 case 'b':
3899 {
3900 if (LocaleCompare(keyword,"blackness") == 0)
3901 {
cristyc1acd842011-05-19 23:05:47 +00003902 geometry_info.rho=InterpretLocaleValue(value,
3903 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003904 break;
3905 }
3906 if (LocaleCompare(keyword,"brightness") == 0)
3907 {
cristyc1acd842011-05-19 23:05:47 +00003908 geometry_info.rho=InterpretLocaleValue(value,
3909 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003910 break;
3911 }
3912 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3913 keyword);
3914 break;
3915 }
3916 case 'F':
3917 case 'f':
3918 {
3919 if (LocaleCompare(keyword,"factor") == 0)
3920 {
3921 flags=ParseGeometry(value,&geometry_info);
3922 break;
3923 }
3924 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3925 keyword);
3926 break;
3927 }
3928 case 'H':
3929 case 'h':
3930 {
3931 if (LocaleCompare(keyword,"hue") == 0)
3932 {
cristyc1acd842011-05-19 23:05:47 +00003933 geometry_info.xi=InterpretLocaleValue(value,
3934 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003935 break;
3936 }
3937 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3938 keyword);
3939 break;
3940 }
3941 case 'L':
3942 case 'l':
3943 {
3944 if (LocaleCompare(keyword,"lightness") == 0)
3945 {
cristyc1acd842011-05-19 23:05:47 +00003946 geometry_info.rho=InterpretLocaleValue(value,
3947 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003948 break;
3949 }
3950 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3951 keyword);
3952 break;
3953 }
3954 case 'S':
3955 case 's':
3956 {
3957 if (LocaleCompare(keyword,"saturation") == 0)
3958 {
cristyc1acd842011-05-19 23:05:47 +00003959 geometry_info.sigma=InterpretLocaleValue(value,
3960 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003961 break;
3962 }
3963 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3964 keyword);
3965 break;
3966 }
3967 case 'W':
3968 case 'w':
3969 {
3970 if (LocaleCompare(keyword,"whiteness") == 0)
3971 {
cristyc1acd842011-05-19 23:05:47 +00003972 geometry_info.sigma=InterpretLocaleValue(value,
3973 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003974 break;
3975 }
3976 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3977 keyword);
3978 break;
3979 }
3980 default:
3981 {
3982 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3983 keyword);
3984 break;
3985 }
3986 }
3987 }
cristyb51dff52011-05-19 16:55:47 +00003988 (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003989 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
3990 (void) ModulateImage(msl_info->image[n],modulate);
3991 break;
3992 }
3993 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3994 }
3995 case 'N':
3996 case 'n':
3997 {
cristyb988fe72009-09-16 01:01:10 +00003998 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003999 {
4000 MagickBooleanType
4001 gray;
4002
4003 /*
4004 Negate image.
4005 */
4006 if (msl_info->image[n] == (Image *) NULL)
4007 {
cristyb988fe72009-09-16 01:01:10 +00004008 ThrowMSLException(OptionError,"NoImagesDefined",
4009 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004010 break;
4011 }
4012 gray=MagickFalse;
4013 if (attributes != (const xmlChar **) NULL)
4014 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4015 {
4016 keyword=(const char *) attributes[i++];
4017 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004018 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004019 CloneString(&value,attribute);
4020 switch (*keyword)
4021 {
4022 case 'C':
4023 case 'c':
4024 {
4025 if (LocaleCompare(keyword,"channel") == 0)
4026 {
4027 option=ParseChannelOption(value);
4028 if (option < 0)
4029 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4030 value);
4031 channel=(ChannelType) option;
4032 break;
4033 }
4034 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4035 keyword);
4036 break;
4037 }
4038 case 'G':
4039 case 'g':
4040 {
4041 if (LocaleCompare(keyword,"gray") == 0)
4042 {
cristy042ee782011-04-22 18:48:30 +00004043 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004044 value);
4045 if (option < 0)
4046 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4047 value);
4048 gray=(MagickBooleanType) option;
4049 break;
4050 }
4051 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4052 keyword);
4053 break;
4054 }
4055 default:
4056 {
4057 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4058 keyword);
4059 break;
4060 }
4061 }
4062 }
4063 (void) NegateImageChannel(msl_info->image[n],channel,gray);
4064 break;
4065 }
cristyb988fe72009-09-16 01:01:10 +00004066 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004067 {
4068 /*
4069 Normalize image.
4070 */
4071 if (msl_info->image[n] == (Image *) NULL)
4072 {
cristyb988fe72009-09-16 01:01:10 +00004073 ThrowMSLException(OptionError,"NoImagesDefined",
4074 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004075 break;
4076 }
4077 if (attributes != (const xmlChar **) NULL)
4078 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4079 {
4080 keyword=(const char *) attributes[i++];
4081 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004082 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004083 CloneString(&value,attribute);
4084 switch (*keyword)
4085 {
4086 case 'C':
4087 case 'c':
4088 {
4089 if (LocaleCompare(keyword,"channel") == 0)
4090 {
4091 option=ParseChannelOption(value);
4092 if (option < 0)
4093 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4094 value);
4095 channel=(ChannelType) option;
4096 break;
4097 }
4098 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4099 keyword);
4100 break;
4101 }
4102 default:
4103 {
4104 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4105 keyword);
4106 break;
4107 }
4108 }
4109 }
4110 (void) NormalizeImageChannel(msl_info->image[n],channel);
4111 break;
4112 }
4113 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4114 }
4115 case 'O':
4116 case 'o':
4117 {
cristyb988fe72009-09-16 01:01:10 +00004118 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004119 {
4120 Image
4121 *paint_image;
4122
4123 /*
4124 Oil-paint image.
4125 */
4126 if (msl_info->image[n] == (Image *) NULL)
4127 {
cristyb988fe72009-09-16 01:01:10 +00004128 ThrowMSLException(OptionError,"NoImagesDefined",
4129 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004130 break;
4131 }
4132 if (attributes != (const xmlChar **) NULL)
4133 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4134 {
4135 keyword=(const char *) attributes[i++];
4136 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004137 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004138 CloneString(&value,attribute);
4139 switch (*keyword)
4140 {
4141 case 'G':
4142 case 'g':
4143 {
4144 if (LocaleCompare(keyword,"geometry") == 0)
4145 {
4146 flags=ParseGeometry(value,&geometry_info);
4147 if ((flags & SigmaValue) == 0)
4148 geometry_info.sigma=1.0;
4149 break;
4150 }
4151 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4152 keyword);
4153 break;
4154 }
4155 case 'R':
4156 case 'r':
4157 {
4158 if (LocaleCompare(keyword,"radius") == 0)
4159 {
cristyc1acd842011-05-19 23:05:47 +00004160 geometry_info.rho=InterpretLocaleValue(value,
4161 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004162 break;
4163 }
4164 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4165 keyword);
4166 break;
4167 }
4168 default:
4169 {
4170 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4171 keyword);
4172 break;
4173 }
4174 }
4175 }
4176 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4177 &msl_info->image[n]->exception);
4178 if (paint_image == (Image *) NULL)
4179 break;
4180 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4181 msl_info->image[n]=paint_image;
4182 break;
4183 }
cristyb988fe72009-09-16 01:01:10 +00004184 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004185 {
cristy4c08aed2011-07-01 19:47:50 +00004186 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004187 fill_color,
4188 target;
4189
4190 /*
4191 Opaque image.
4192 */
4193 if (msl_info->image[n] == (Image *) NULL)
4194 {
cristyb988fe72009-09-16 01:01:10 +00004195 ThrowMSLException(OptionError,"NoImagesDefined",
4196 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004197 break;
4198 }
4199 (void) QueryMagickColor("none",&target,&exception);
4200 (void) QueryMagickColor("none",&fill_color,&exception);
4201 if (attributes != (const xmlChar **) NULL)
4202 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4203 {
4204 keyword=(const char *) attributes[i++];
4205 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004206 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004207 CloneString(&value,attribute);
4208 switch (*keyword)
4209 {
4210 case 'C':
4211 case 'c':
4212 {
4213 if (LocaleCompare(keyword,"channel") == 0)
4214 {
4215 option=ParseChannelOption(value);
4216 if (option < 0)
4217 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4218 value);
4219 channel=(ChannelType) option;
4220 break;
4221 }
4222 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4223 keyword);
4224 break;
4225 }
4226 case 'F':
4227 case 'f':
4228 {
4229 if (LocaleCompare(keyword,"fill") == 0)
4230 {
4231 (void) QueryMagickColor(value,&fill_color,&exception);
4232 break;
4233 }
4234 if (LocaleCompare(keyword,"fuzz") == 0)
4235 {
cristyc1acd842011-05-19 23:05:47 +00004236 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
4237 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004238 break;
4239 }
4240 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4241 keyword);
4242 break;
4243 }
4244 default:
4245 {
4246 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4247 keyword);
4248 break;
4249 }
4250 }
4251 }
4252 (void) OpaquePaintImageChannel(msl_info->image[n],channel,
4253 &target,&fill_color,MagickFalse);
4254 break;
4255 }
4256 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4257 }
4258 case 'P':
4259 case 'p':
4260 {
cristyb988fe72009-09-16 01:01:10 +00004261 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004262 {
4263 if (attributes == (const xmlChar **) NULL)
4264 break;
4265 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4266 {
4267 keyword=(const char *) attributes[i++];
4268 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004269 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004270 CloneString(&value,attribute);
4271 switch (*keyword)
4272 {
4273 case 'O':
4274 case 'o':
4275 {
4276 if (LocaleCompare(keyword,"output") == 0)
4277 {
cristyb51dff52011-05-19 16:55:47 +00004278 (void) FormatLocaleFile(stdout,"%s",value);
cristy3ed852e2009-09-05 21:47:34 +00004279 break;
4280 }
4281 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4282 break;
4283 }
4284 default:
4285 {
4286 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4287 break;
4288 }
4289 }
4290 }
4291 break;
4292 }
cristy4fa36e42009-09-18 14:24:06 +00004293 if (LocaleCompare((const char *) tag, "profile") == 0)
4294 {
cristy4fa36e42009-09-18 14:24:06 +00004295 if (msl_info->image[n] == (Image *) NULL)
4296 {
4297 ThrowMSLException(OptionError,"NoImagesDefined",
4298 (const char *) tag);
4299 break;
4300 }
4301 if (attributes == (const xmlChar **) NULL)
4302 break;
4303 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4304 {
4305 const char
4306 *name;
4307
4308 const StringInfo
4309 *profile;
4310
4311 Image
4312 *profile_image;
4313
4314 ImageInfo
4315 *profile_info;
4316
4317 keyword=(const char *) attributes[i++];
4318 attribute=InterpretImageProperties(msl_info->image_info[n],
4319 msl_info->attributes[n],(const char *) attributes[i]);
4320 CloneString(&value,attribute);
4321 if (*keyword == '+')
4322 {
4323 /*
4324 Remove a profile from the image.
4325 */
4326 (void) ProfileImage(msl_info->image[n],keyword,
4327 (const unsigned char *) NULL,0,MagickTrue);
4328 continue;
4329 }
4330 /*
4331 Associate a profile with the image.
4332 */
4333 profile_info=CloneImageInfo(msl_info->image_info[n]);
4334 profile=GetImageProfile(msl_info->image[n],"iptc");
4335 if (profile != (StringInfo *) NULL)
4336 profile_info->profile=(void *) CloneStringInfo(profile);
4337 profile_image=GetImageCache(profile_info,keyword,&exception);
4338 profile_info=DestroyImageInfo(profile_info);
4339 if (profile_image == (Image *) NULL)
4340 {
4341 char
4342 name[MaxTextExtent],
4343 filename[MaxTextExtent];
4344
4345 register char
4346 *p;
4347
4348 StringInfo
4349 *profile;
4350
4351 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4352 (void) CopyMagickString(name,keyword,MaxTextExtent);
4353 for (p=filename; *p != '\0'; p++)
4354 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4355 (IsPathAccessible(keyword) == MagickFalse))
4356 {
4357 register char
4358 *q;
4359
4360 /*
4361 Look for profile name (e.g. name:profile).
4362 */
4363 (void) CopyMagickString(name,filename,(size_t)
4364 (p-filename+1));
4365 for (q=filename; *q != '\0'; q++)
4366 *q=(*++p);
4367 break;
4368 }
4369 profile=FileToStringInfo(filename,~0UL,&exception);
4370 if (profile != (StringInfo *) NULL)
4371 {
4372 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004373 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004374 GetStringInfoLength(profile),MagickFalse);
4375 profile=DestroyStringInfo(profile);
4376 }
4377 continue;
4378 }
4379 ResetImageProfileIterator(profile_image);
4380 name=GetNextImageProfile(profile_image);
4381 while (name != (const char *) NULL)
4382 {
4383 profile=GetImageProfile(profile_image,name);
4384 if (profile != (StringInfo *) NULL)
4385 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004386 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004387 GetStringInfoLength(profile),MagickFalse);
4388 name=GetNextImageProfile(profile_image);
4389 }
4390 profile_image=DestroyImage(profile_image);
4391 }
4392 break;
4393 }
cristy3ed852e2009-09-05 21:47:34 +00004394 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4395 }
4396 case 'Q':
4397 case 'q':
4398 {
cristyb988fe72009-09-16 01:01:10 +00004399 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004400 {
4401 QuantizeInfo
4402 quantize_info;
4403
4404 /*
4405 Quantize image.
4406 */
4407 if (msl_info->image[n] == (Image *) NULL)
4408 {
cristyb988fe72009-09-16 01:01:10 +00004409 ThrowMSLException(OptionError,"NoImagesDefined",
4410 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004411 break;
4412 }
4413 GetQuantizeInfo(&quantize_info);
4414 if (attributes != (const xmlChar **) NULL)
4415 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4416 {
4417 keyword=(const char *) attributes[i++];
4418 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004419 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004420 CloneString(&value,attribute);
4421 switch (*keyword)
4422 {
4423 case 'C':
4424 case 'c':
4425 {
4426 if (LocaleCompare(keyword,"colors") == 0)
4427 {
cristyf2f27272009-12-17 14:48:46 +00004428 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004429 break;
4430 }
4431 if (LocaleCompare(keyword,"colorspace") == 0)
4432 {
cristy042ee782011-04-22 18:48:30 +00004433 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004434 MagickFalse,value);
4435 if (option < 0)
4436 ThrowMSLException(OptionError,
4437 "UnrecognizedColorspaceType",value);
4438 quantize_info.colorspace=(ColorspaceType) option;
4439 break;
4440 }
4441 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4442 keyword);
4443 break;
4444 }
4445 case 'D':
4446 case 'd':
4447 {
4448 if (LocaleCompare(keyword,"dither") == 0)
4449 {
cristy042ee782011-04-22 18:48:30 +00004450 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004451 value);
4452 if (option < 0)
4453 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4454 value);
4455 quantize_info.dither=(MagickBooleanType) option;
4456 break;
4457 }
4458 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4459 keyword);
4460 break;
4461 }
4462 case 'M':
4463 case 'm':
4464 {
4465 if (LocaleCompare(keyword,"measure") == 0)
4466 {
cristy042ee782011-04-22 18:48:30 +00004467 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004468 value);
4469 if (option < 0)
4470 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4471 value);
4472 quantize_info.measure_error=(MagickBooleanType) option;
4473 break;
4474 }
4475 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4476 keyword);
4477 break;
4478 }
4479 case 'T':
4480 case 't':
4481 {
4482 if (LocaleCompare(keyword,"treedepth") == 0)
4483 {
cristyf2f27272009-12-17 14:48:46 +00004484 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004485 break;
4486 }
4487 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4488 keyword);
4489 break;
4490 }
4491 default:
4492 {
4493 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4494 keyword);
4495 break;
4496 }
4497 }
4498 }
4499 (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4500 break;
4501 }
cristyb988fe72009-09-16 01:01:10 +00004502 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004503 {
4504 char
4505 text[MaxTextExtent];
4506
4507 MagickBooleanType
4508 status;
4509
4510 TypeMetric
4511 metrics;
4512
4513 /*
4514 Query font metrics.
4515 */
4516 draw_info=CloneDrawInfo(msl_info->image_info[n],
4517 msl_info->draw_info[n]);
4518 angle=0.0;
4519 current=draw_info->affine;
4520 GetAffineMatrix(&affine);
4521 if (attributes != (const xmlChar **) NULL)
4522 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4523 {
4524 keyword=(const char *) attributes[i++];
4525 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004526 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004527 CloneString(&value,attribute);
4528 switch (*keyword)
4529 {
4530 case 'A':
4531 case 'a':
4532 {
4533 if (LocaleCompare(keyword,"affine") == 0)
4534 {
4535 char
4536 *p;
4537
4538 p=value;
cristyc1acd842011-05-19 23:05:47 +00004539 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004540 if (*p ==',')
4541 p++;
cristyc1acd842011-05-19 23:05:47 +00004542 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004543 if (*p ==',')
4544 p++;
cristyc1acd842011-05-19 23:05:47 +00004545 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004546 if (*p ==',')
4547 p++;
cristyc1acd842011-05-19 23:05:47 +00004548 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004549 if (*p ==',')
4550 p++;
cristyc1acd842011-05-19 23:05:47 +00004551 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004552 if (*p ==',')
4553 p++;
cristyc1acd842011-05-19 23:05:47 +00004554 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004555 break;
4556 }
4557 if (LocaleCompare(keyword,"align") == 0)
4558 {
cristy042ee782011-04-22 18:48:30 +00004559 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004560 value);
4561 if (option < 0)
4562 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4563 value);
4564 draw_info->align=(AlignType) option;
4565 break;
4566 }
4567 if (LocaleCompare(keyword,"antialias") == 0)
4568 {
cristy042ee782011-04-22 18:48:30 +00004569 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004570 value);
4571 if (option < 0)
4572 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4573 value);
4574 draw_info->stroke_antialias=(MagickBooleanType) option;
4575 draw_info->text_antialias=(MagickBooleanType) option;
4576 break;
4577 }
4578 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4579 keyword);
4580 break;
4581 }
4582 case 'D':
4583 case 'd':
4584 {
4585 if (LocaleCompare(keyword,"density") == 0)
4586 {
4587 CloneString(&draw_info->density,value);
4588 break;
4589 }
4590 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4591 keyword);
4592 break;
4593 }
4594 case 'E':
4595 case 'e':
4596 {
4597 if (LocaleCompare(keyword,"encoding") == 0)
4598 {
4599 CloneString(&draw_info->encoding,value);
4600 break;
4601 }
4602 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4603 keyword);
4604 break;
4605 }
4606 case 'F':
4607 case 'f':
4608 {
4609 if (LocaleCompare(keyword, "fill") == 0)
4610 {
4611 (void) QueryColorDatabase(value,&draw_info->fill,
4612 &exception);
4613 break;
4614 }
4615 if (LocaleCompare(keyword,"family") == 0)
4616 {
4617 CloneString(&draw_info->family,value);
4618 break;
4619 }
4620 if (LocaleCompare(keyword,"font") == 0)
4621 {
4622 CloneString(&draw_info->font,value);
4623 break;
4624 }
4625 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4626 keyword);
4627 break;
4628 }
4629 case 'G':
4630 case 'g':
4631 {
4632 if (LocaleCompare(keyword,"geometry") == 0)
4633 {
4634 flags=ParsePageGeometry(msl_info->image[n],value,
4635 &geometry,&exception);
4636 if ((flags & HeightValue) == 0)
4637 geometry.height=geometry.width;
4638 break;
4639 }
4640 if (LocaleCompare(keyword,"gravity") == 0)
4641 {
cristy042ee782011-04-22 18:48:30 +00004642 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004643 value);
4644 if (option < 0)
4645 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4646 value);
4647 draw_info->gravity=(GravityType) option;
4648 break;
4649 }
4650 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4651 keyword);
4652 break;
4653 }
4654 case 'P':
4655 case 'p':
4656 {
4657 if (LocaleCompare(keyword,"pointsize") == 0)
4658 {
cristyc1acd842011-05-19 23:05:47 +00004659 draw_info->pointsize=InterpretLocaleValue(value,
4660 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004661 break;
4662 }
4663 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4664 keyword);
4665 break;
4666 }
4667 case 'R':
4668 case 'r':
4669 {
4670 if (LocaleCompare(keyword,"rotate") == 0)
4671 {
cristyc1acd842011-05-19 23:05:47 +00004672 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004673 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4674 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4675 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4676 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4677 break;
4678 }
4679 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4680 keyword);
4681 break;
4682 }
4683 case 'S':
4684 case 's':
4685 {
4686 if (LocaleCompare(keyword,"scale") == 0)
4687 {
4688 flags=ParseGeometry(value,&geometry_info);
4689 if ((flags & SigmaValue) == 0)
4690 geometry_info.sigma=1.0;
4691 affine.sx=geometry_info.rho;
4692 affine.sy=geometry_info.sigma;
4693 break;
4694 }
4695 if (LocaleCompare(keyword,"skewX") == 0)
4696 {
cristyc1acd842011-05-19 23:05:47 +00004697 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004698 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4699 break;
4700 }
4701 if (LocaleCompare(keyword,"skewY") == 0)
4702 {
cristyc1acd842011-05-19 23:05:47 +00004703 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004704 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4705 break;
4706 }
4707 if (LocaleCompare(keyword,"stretch") == 0)
4708 {
cristy042ee782011-04-22 18:48:30 +00004709 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004710 value);
4711 if (option < 0)
4712 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4713 value);
4714 draw_info->stretch=(StretchType) option;
4715 break;
4716 }
4717 if (LocaleCompare(keyword, "stroke") == 0)
4718 {
4719 (void) QueryColorDatabase(value,&draw_info->stroke,
4720 &exception);
4721 break;
4722 }
4723 if (LocaleCompare(keyword,"strokewidth") == 0)
4724 {
cristyf2f27272009-12-17 14:48:46 +00004725 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004726 break;
4727 }
4728 if (LocaleCompare(keyword,"style") == 0)
4729 {
cristy042ee782011-04-22 18:48:30 +00004730 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004731 value);
4732 if (option < 0)
4733 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4734 value);
4735 draw_info->style=(StyleType) option;
4736 break;
4737 }
4738 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4739 keyword);
4740 break;
4741 }
4742 case 'T':
4743 case 't':
4744 {
4745 if (LocaleCompare(keyword,"text") == 0)
4746 {
4747 CloneString(&draw_info->text,value);
4748 break;
4749 }
4750 if (LocaleCompare(keyword,"translate") == 0)
4751 {
4752 flags=ParseGeometry(value,&geometry_info);
4753 if ((flags & SigmaValue) == 0)
4754 geometry_info.sigma=1.0;
4755 affine.tx=geometry_info.rho;
4756 affine.ty=geometry_info.sigma;
4757 break;
4758 }
4759 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4760 keyword);
4761 break;
4762 }
4763 case 'U':
4764 case 'u':
4765 {
4766 if (LocaleCompare(keyword, "undercolor") == 0)
4767 {
4768 (void) QueryColorDatabase(value,&draw_info->undercolor,
4769 &exception);
4770 break;
4771 }
4772 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4773 keyword);
4774 break;
4775 }
4776 case 'W':
4777 case 'w':
4778 {
4779 if (LocaleCompare(keyword,"weight") == 0)
4780 {
cristyf2f27272009-12-17 14:48:46 +00004781 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004782 break;
4783 }
4784 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4785 keyword);
4786 break;
4787 }
4788 case 'X':
4789 case 'x':
4790 {
4791 if (LocaleCompare(keyword,"x") == 0)
4792 {
cristyf2f27272009-12-17 14:48:46 +00004793 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004794 break;
4795 }
4796 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4797 keyword);
4798 break;
4799 }
4800 case 'Y':
4801 case 'y':
4802 {
4803 if (LocaleCompare(keyword,"y") == 0)
4804 {
cristyf2f27272009-12-17 14:48:46 +00004805 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004806 break;
4807 }
4808 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4809 keyword);
4810 break;
4811 }
4812 default:
4813 {
4814 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4815 keyword);
4816 break;
4817 }
4818 }
4819 }
cristyb51dff52011-05-19 16:55:47 +00004820 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00004821 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4822 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004823 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004824 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4825 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4826 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4827 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4828 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4829 affine.tx;
4830 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4831 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00004832 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4833 if (status != MagickFalse)
4834 {
4835 Image
4836 *image;
4837
4838 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004839 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004840 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004841 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004842 "%g",metrics.pixels_per_em.y);
4843 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004844 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004845 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004846 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004847 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004848 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004849 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004850 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004851 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004852 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004853 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004854 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004855 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004856 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004857 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004858 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004859 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004860 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004861 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004862 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004863 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004864 metrics.origin.y);
4865 }
4866 draw_info=DestroyDrawInfo(draw_info);
4867 break;
4868 }
4869 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4870 }
4871 case 'R':
4872 case 'r':
4873 {
cristyb988fe72009-09-16 01:01:10 +00004874 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004875 {
4876 MagickBooleanType
4877 raise;
4878
4879 /*
4880 Raise image.
4881 */
4882 if (msl_info->image[n] == (Image *) NULL)
4883 {
cristyb988fe72009-09-16 01:01:10 +00004884 ThrowMSLException(OptionError,"NoImagesDefined",
4885 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004886 break;
4887 }
4888 raise=MagickFalse;
4889 SetGeometry(msl_info->image[n],&geometry);
4890 if (attributes != (const xmlChar **) NULL)
4891 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4892 {
4893 keyword=(const char *) attributes[i++];
4894 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004895 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004896 CloneString(&value,attribute);
4897 switch (*keyword)
4898 {
4899 case 'G':
4900 case 'g':
4901 {
4902 if (LocaleCompare(keyword,"geometry") == 0)
4903 {
4904 flags=ParsePageGeometry(msl_info->image[n],value,
4905 &geometry,&exception);
4906 if ((flags & HeightValue) == 0)
4907 geometry.height=geometry.width;
4908 break;
4909 }
4910 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4911 keyword);
4912 break;
4913 }
4914 case 'H':
4915 case 'h':
4916 {
4917 if (LocaleCompare(keyword,"height") == 0)
4918 {
cristyf2f27272009-12-17 14:48:46 +00004919 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004920 break;
4921 }
4922 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4923 keyword);
4924 break;
4925 }
4926 case 'R':
4927 case 'r':
4928 {
4929 if (LocaleCompare(keyword,"raise") == 0)
4930 {
cristy042ee782011-04-22 18:48:30 +00004931 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004932 value);
4933 if (option < 0)
4934 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4935 value);
4936 raise=(MagickBooleanType) option;
4937 break;
4938 }
4939 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4940 keyword);
4941 break;
4942 }
4943 case 'W':
4944 case 'w':
4945 {
4946 if (LocaleCompare(keyword,"width") == 0)
4947 {
cristyf2f27272009-12-17 14:48:46 +00004948 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004949 break;
4950 }
4951 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4952 keyword);
4953 break;
4954 }
4955 default:
4956 {
4957 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4958 keyword);
4959 break;
4960 }
4961 }
4962 }
4963 (void) RaiseImage(msl_info->image[n],&geometry,raise);
4964 break;
4965 }
cristyb988fe72009-09-16 01:01:10 +00004966 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004967 {
4968 if (attributes == (const xmlChar **) NULL)
4969 break;
4970 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4971 {
4972 keyword=(const char *) attributes[i++];
4973 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004974 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00004975 switch (*keyword)
4976 {
4977 case 'F':
4978 case 'f':
4979 {
4980 if (LocaleCompare(keyword,"filename") == 0)
4981 {
4982 Image
4983 *image;
4984
4985 (void) CopyMagickString(msl_info->image_info[n]->filename,
4986 value,MaxTextExtent);
4987 image=ReadImage(msl_info->image_info[n],&exception);
4988 CatchException(&exception);
4989 if (image == (Image *) NULL)
4990 continue;
4991 AppendImageToList(&msl_info->image[n],image);
4992 break;
4993 }
cristy4582cbb2009-09-23 00:35:43 +00004994 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004995 break;
4996 }
4997 default:
4998 {
cristy4582cbb2009-09-23 00:35:43 +00004999 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005000 break;
5001 }
5002 }
5003 }
5004 break;
5005 }
cristyb988fe72009-09-16 01:01:10 +00005006 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005007 {
5008 Image
5009 *paint_image;
5010
5011 /*
5012 Reduce-noise image.
5013 */
5014 if (msl_info->image[n] == (Image *) NULL)
5015 {
cristyb988fe72009-09-16 01:01:10 +00005016 ThrowMSLException(OptionError,"NoImagesDefined",
5017 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005018 break;
5019 }
5020 if (attributes != (const xmlChar **) NULL)
5021 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5022 {
5023 keyword=(const char *) attributes[i++];
5024 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005025 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005026 CloneString(&value,attribute);
5027 switch (*keyword)
5028 {
5029 case 'G':
5030 case 'g':
5031 {
5032 if (LocaleCompare(keyword,"geometry") == 0)
5033 {
5034 flags=ParseGeometry(value,&geometry_info);
5035 if ((flags & SigmaValue) == 0)
5036 geometry_info.sigma=1.0;
5037 break;
5038 }
5039 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5040 keyword);
5041 break;
5042 }
5043 case 'R':
5044 case 'r':
5045 {
5046 if (LocaleCompare(keyword,"radius") == 0)
5047 {
cristyc1acd842011-05-19 23:05:47 +00005048 geometry_info.rho=InterpretLocaleValue(value,
5049 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005050 break;
5051 }
5052 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5053 keyword);
5054 break;
5055 }
5056 default:
5057 {
5058 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5059 keyword);
5060 break;
5061 }
5062 }
5063 }
cristy733678d2011-03-18 21:29:28 +00005064 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005065 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5066 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00005067 if (paint_image == (Image *) NULL)
5068 break;
5069 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5070 msl_info->image[n]=paint_image;
5071 break;
5072 }
cristyb988fe72009-09-16 01:01:10 +00005073 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005074 {
5075 /* init the values */
5076 width=msl_info->image[n]->page.width;
5077 height=msl_info->image[n]->page.height;
5078 x=msl_info->image[n]->page.x;
5079 y=msl_info->image[n]->page.y;
5080
5081 if (msl_info->image[n] == (Image *) NULL)
5082 {
cristyb988fe72009-09-16 01:01:10 +00005083 ThrowMSLException(OptionError,"NoImagesDefined",
5084 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005085 break;
5086 }
5087 if (attributes == (const xmlChar **) NULL)
5088 break;
5089 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5090 {
5091 keyword=(const char *) attributes[i++];
5092 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005093 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005094 switch (*keyword)
5095 {
5096 case 'G':
5097 case 'g':
5098 {
5099 if (LocaleCompare(keyword,"geometry") == 0)
5100 {
5101 int
5102 flags;
5103
5104 RectangleInfo
5105 geometry;
5106
5107 flags=ParseAbsoluteGeometry(value,&geometry);
5108 if ((flags & WidthValue) != 0)
5109 {
5110 if ((flags & HeightValue) == 0)
5111 geometry.height=geometry.width;
5112 width=geometry.width;
5113 height=geometry.height;
5114 }
5115 if ((flags & AspectValue) != 0)
5116 {
5117 if ((flags & XValue) != 0)
5118 x+=geometry.x;
5119 if ((flags & YValue) != 0)
5120 y+=geometry.y;
5121 }
5122 else
5123 {
5124 if ((flags & XValue) != 0)
5125 {
5126 x=geometry.x;
5127 if ((width == 0) && (geometry.x > 0))
5128 width=msl_info->image[n]->columns+geometry.x;
5129 }
5130 if ((flags & YValue) != 0)
5131 {
5132 y=geometry.y;
5133 if ((height == 0) && (geometry.y > 0))
5134 height=msl_info->image[n]->rows+geometry.y;
5135 }
5136 }
5137 break;
5138 }
5139 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5140 break;
5141 }
5142 case 'H':
5143 case 'h':
5144 {
5145 if (LocaleCompare(keyword,"height") == 0)
5146 {
cristyf2f27272009-12-17 14:48:46 +00005147 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005148 break;
5149 }
5150 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5151 break;
5152 }
5153 case 'W':
5154 case 'w':
5155 {
5156 if (LocaleCompare(keyword,"width") == 0)
5157 {
cristyf2f27272009-12-17 14:48:46 +00005158 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005159 break;
5160 }
5161 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5162 break;
5163 }
5164 case 'X':
5165 case 'x':
5166 {
5167 if (LocaleCompare(keyword,"x") == 0)
5168 {
cristyf2f27272009-12-17 14:48:46 +00005169 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005170 break;
5171 }
5172 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5173 break;
5174 }
5175 case 'Y':
5176 case 'y':
5177 {
5178 if (LocaleCompare(keyword,"y") == 0)
5179 {
cristyf2f27272009-12-17 14:48:46 +00005180 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005181 break;
5182 }
5183 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5184 break;
5185 }
5186 default:
5187 {
5188 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5189 break;
5190 }
5191 }
5192 }
5193
cristyb988fe72009-09-16 01:01:10 +00005194 msl_info->image[n]->page.width=width;
5195 msl_info->image[n]->page.height=height;
5196 msl_info->image[n]->page.x=x;
5197 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005198 break;
5199 }
cristyb988fe72009-09-16 01:01:10 +00005200 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005201 {
5202 double
5203 x_resolution,
5204 y_resolution;
5205
5206 if (msl_info->image[n] == (Image *) NULL)
5207 {
cristyb988fe72009-09-16 01:01:10 +00005208 ThrowMSLException(OptionError,"NoImagesDefined",
5209 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005210 break;
5211 }
5212 if (attributes == (const xmlChar **) NULL)
5213 break;
5214 x_resolution=DefaultResolution;
5215 y_resolution=DefaultResolution;
5216 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5217 {
5218 keyword=(const char *) attributes[i++];
5219 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005220 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005221 switch (*keyword)
5222 {
5223 case 'b':
5224 {
5225 if (LocaleCompare(keyword,"blur") == 0)
5226 {
cristyc1acd842011-05-19 23:05:47 +00005227 msl_info->image[n]->blur=InterpretLocaleValue(value,
5228 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005229 break;
5230 }
5231 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5232 break;
5233 }
5234 case 'G':
5235 case 'g':
5236 {
5237 if (LocaleCompare(keyword,"geometry") == 0)
5238 {
cristybb503372010-05-27 20:51:26 +00005239 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005240 flags;
5241
5242 flags=ParseGeometry(value,&geometry_info);
5243 if ((flags & SigmaValue) == 0)
5244 geometry_info.sigma*=geometry_info.rho;
5245 x_resolution=geometry_info.rho;
5246 y_resolution=geometry_info.sigma;
5247 break;
5248 }
5249 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5250 break;
5251 }
5252 case 'X':
5253 case 'x':
5254 {
5255 if (LocaleCompare(keyword,"x-resolution") == 0)
5256 {
cristyc1acd842011-05-19 23:05:47 +00005257 x_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005258 break;
5259 }
5260 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5261 break;
5262 }
5263 case 'Y':
5264 case 'y':
5265 {
5266 if (LocaleCompare(keyword,"y-resolution") == 0)
5267 {
cristyc1acd842011-05-19 23:05:47 +00005268 y_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005269 break;
5270 }
5271 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5272 break;
5273 }
5274 default:
5275 {
5276 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5277 break;
5278 }
5279 }
5280 }
5281 /*
5282 Resample image.
5283 */
5284 {
5285 double
5286 factor;
5287
5288 Image
5289 *resample_image;
5290
5291 factor=1.0;
5292 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5293 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005294 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy3ed852e2009-09-05 21:47:34 +00005295 (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5296 msl_info->image[n]->x_resolution))+0.5);
cristybb503372010-05-27 20:51:26 +00005297 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy3ed852e2009-09-05 21:47:34 +00005298 (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5299 msl_info->image[n]->y_resolution))+0.5);
5300 resample_image=ResizeImage(msl_info->image[n],width,height,
5301 msl_info->image[n]->filter,msl_info->image[n]->blur,
5302 &msl_info->image[n]->exception);
5303 if (resample_image == (Image *) NULL)
5304 break;
5305 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5306 msl_info->image[n]=resample_image;
5307 }
5308 break;
5309 }
cristyb988fe72009-09-16 01:01:10 +00005310 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005311 {
5312 double
5313 blur;
5314
5315 FilterTypes
5316 filter;
5317
5318 Image
5319 *resize_image;
5320
5321 /*
5322 Resize image.
5323 */
5324 if (msl_info->image[n] == (Image *) NULL)
5325 {
cristyb988fe72009-09-16 01:01:10 +00005326 ThrowMSLException(OptionError,"NoImagesDefined",
5327 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005328 break;
5329 }
5330 filter=UndefinedFilter;
5331 blur=1.0;
5332 if (attributes != (const xmlChar **) NULL)
5333 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5334 {
5335 keyword=(const char *) attributes[i++];
5336 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005337 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005338 CloneString(&value,attribute);
5339 switch (*keyword)
5340 {
5341 case 'F':
5342 case 'f':
5343 {
5344 if (LocaleCompare(keyword,"filter") == 0)
5345 {
cristy042ee782011-04-22 18:48:30 +00005346 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005347 value);
5348 if (option < 0)
5349 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5350 value);
5351 filter=(FilterTypes) option;
5352 break;
5353 }
5354 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5355 keyword);
5356 break;
5357 }
5358 case 'G':
5359 case 'g':
5360 {
5361 if (LocaleCompare(keyword,"geometry") == 0)
5362 {
5363 flags=ParseRegionGeometry(msl_info->image[n],value,
5364 &geometry,&exception);
5365 break;
5366 }
5367 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5368 keyword);
5369 break;
5370 }
5371 case 'H':
5372 case 'h':
5373 {
5374 if (LocaleCompare(keyword,"height") == 0)
5375 {
cristye27293e2009-12-18 02:53:20 +00005376 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005377 break;
5378 }
5379 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5380 keyword);
5381 break;
5382 }
5383 case 'S':
5384 case 's':
5385 {
5386 if (LocaleCompare(keyword,"support") == 0)
5387 {
cristyc1acd842011-05-19 23:05:47 +00005388 blur=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005389 break;
5390 }
5391 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5392 keyword);
5393 break;
5394 }
5395 case 'W':
5396 case 'w':
5397 {
5398 if (LocaleCompare(keyword,"width") == 0)
5399 {
cristyf2f27272009-12-17 14:48:46 +00005400 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005401 break;
5402 }
5403 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5404 keyword);
5405 break;
5406 }
5407 default:
5408 {
5409 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5410 keyword);
5411 break;
5412 }
5413 }
5414 }
5415 resize_image=ResizeImage(msl_info->image[n],geometry.width,
5416 geometry.height,filter,blur,&msl_info->image[n]->exception);
5417 if (resize_image == (Image *) NULL)
5418 break;
5419 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5420 msl_info->image[n]=resize_image;
5421 break;
5422 }
cristyb988fe72009-09-16 01:01:10 +00005423 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005424 {
5425 Image
5426 *roll_image;
5427
5428 /*
5429 Roll image.
5430 */
5431 if (msl_info->image[n] == (Image *) NULL)
5432 {
cristyb988fe72009-09-16 01:01:10 +00005433 ThrowMSLException(OptionError,"NoImagesDefined",
5434 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005435 break;
5436 }
5437 SetGeometry(msl_info->image[n],&geometry);
5438 if (attributes != (const xmlChar **) NULL)
5439 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5440 {
5441 keyword=(const char *) attributes[i++];
5442 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005443 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005444 CloneString(&value,attribute);
5445 switch (*keyword)
5446 {
5447 case 'G':
5448 case 'g':
5449 {
5450 if (LocaleCompare(keyword,"geometry") == 0)
5451 {
5452 flags=ParsePageGeometry(msl_info->image[n],value,
5453 &geometry,&exception);
5454 if ((flags & HeightValue) == 0)
5455 geometry.height=geometry.width;
5456 break;
5457 }
5458 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5459 keyword);
5460 break;
5461 }
5462 case 'X':
5463 case 'x':
5464 {
5465 if (LocaleCompare(keyword,"x") == 0)
5466 {
cristyf2f27272009-12-17 14:48:46 +00005467 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005468 break;
5469 }
5470 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5471 keyword);
5472 break;
5473 }
5474 case 'Y':
5475 case 'y':
5476 {
5477 if (LocaleCompare(keyword,"y") == 0)
5478 {
cristyf2f27272009-12-17 14:48:46 +00005479 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005480 break;
5481 }
5482 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5483 keyword);
5484 break;
5485 }
5486 default:
5487 {
5488 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5489 keyword);
5490 break;
5491 }
5492 }
5493 }
5494 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5495 &msl_info->image[n]->exception);
5496 if (roll_image == (Image *) NULL)
5497 break;
5498 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5499 msl_info->image[n]=roll_image;
5500 break;
5501 }
cristyb988fe72009-09-16 01:01:10 +00005502 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005503 {
5504 /* init the values */
5505 width=msl_info->image[n]->columns;
5506 height=msl_info->image[n]->rows;
5507 x = y = 0;
5508
5509 if (msl_info->image[n] == (Image *) NULL)
5510 {
cristyb988fe72009-09-16 01:01:10 +00005511 ThrowMSLException(OptionError,"NoImagesDefined",
5512 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005513 break;
5514 }
5515 if (attributes == (const xmlChar **) NULL)
5516 break;
5517 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5518 {
5519 keyword=(const char *) attributes[i++];
5520 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005521 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005522 switch (*keyword)
5523 {
5524 case 'G':
5525 case 'g':
5526 {
5527 if (LocaleCompare(keyword,"geometry") == 0)
5528 {
5529 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5530 break;
5531 }
5532 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5533 break;
5534 }
5535 case 'X':
5536 case 'x':
5537 {
5538 if (LocaleCompare(keyword,"x") == 0)
5539 {
cristyf2f27272009-12-17 14:48:46 +00005540 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005541 break;
5542 }
5543 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5544 break;
5545 }
5546 case 'Y':
5547 case 'y':
5548 {
5549 if (LocaleCompare(keyword,"y") == 0)
5550 {
cristyf2f27272009-12-17 14:48:46 +00005551 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005552 break;
5553 }
5554 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5555 break;
5556 }
5557 default:
5558 {
5559 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5560 break;
5561 }
5562 }
5563 }
5564
5565 /*
5566 process image.
5567 */
5568 {
5569 Image
5570 *newImage;
5571
5572 newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5573 if (newImage == (Image *) NULL)
5574 break;
5575 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5576 msl_info->image[n]=newImage;
5577 }
5578
5579 break;
5580 }
cristyb988fe72009-09-16 01:01:10 +00005581 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005582 {
5583 Image
5584 *rotate_image;
5585
5586 /*
5587 Rotate image.
5588 */
5589 if (msl_info->image[n] == (Image *) NULL)
5590 {
cristyb988fe72009-09-16 01:01:10 +00005591 ThrowMSLException(OptionError,"NoImagesDefined",
5592 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005593 break;
5594 }
5595 if (attributes != (const xmlChar **) NULL)
5596 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5597 {
5598 keyword=(const char *) attributes[i++];
5599 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005600 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005601 CloneString(&value,attribute);
5602 switch (*keyword)
5603 {
5604 case 'D':
5605 case 'd':
5606 {
5607 if (LocaleCompare(keyword,"degrees") == 0)
5608 {
cristyc1acd842011-05-19 23:05:47 +00005609 geometry_info.rho=InterpretLocaleValue(value,
5610 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005611 break;
5612 }
5613 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5614 keyword);
5615 break;
5616 }
5617 case 'G':
5618 case 'g':
5619 {
5620 if (LocaleCompare(keyword,"geometry") == 0)
5621 {
5622 flags=ParseGeometry(value,&geometry_info);
5623 if ((flags & SigmaValue) == 0)
5624 geometry_info.sigma=1.0;
5625 break;
5626 }
5627 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5628 keyword);
5629 break;
5630 }
5631 default:
5632 {
5633 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5634 keyword);
5635 break;
5636 }
5637 }
5638 }
5639 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5640 &msl_info->image[n]->exception);
5641 if (rotate_image == (Image *) NULL)
5642 break;
5643 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5644 msl_info->image[n]=rotate_image;
5645 break;
5646 }
cristyb988fe72009-09-16 01:01:10 +00005647 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005648 {
5649 /* init the values */
5650 double degrees = 0;
5651
5652 if (msl_info->image[n] == (Image *) NULL)
5653 {
cristyb988fe72009-09-16 01:01:10 +00005654 ThrowMSLException(OptionError,"NoImagesDefined",
5655 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005656 break;
5657 }
5658 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005659 break;
cristy3ed852e2009-09-05 21:47:34 +00005660 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5661 {
5662 keyword=(const char *) attributes[i++];
5663 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005664 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005665 switch (*keyword)
5666 {
5667 case 'D':
5668 case 'd':
5669 {
5670 if (LocaleCompare(keyword,"degrees") == 0)
5671 {
cristyc1acd842011-05-19 23:05:47 +00005672 degrees = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005673 break;
5674 }
5675 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5676 break;
5677 }
5678 default:
5679 {
5680 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5681 break;
5682 }
5683 }
5684 }
5685
5686 /*
5687 process image.
5688 */
5689 {
5690 Image
5691 *newImage;
5692
5693 newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5694 if (newImage == (Image *) NULL)
5695 break;
5696 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5697 msl_info->image[n]=newImage;
5698 }
5699
5700 break;
5701 }
5702 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5703 }
5704 case 'S':
5705 case 's':
5706 {
cristyb988fe72009-09-16 01:01:10 +00005707 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005708 {
5709 Image
5710 *sample_image;
5711
5712 /*
5713 Sample image.
5714 */
5715 if (msl_info->image[n] == (Image *) NULL)
5716 {
cristyb988fe72009-09-16 01:01:10 +00005717 ThrowMSLException(OptionError,"NoImagesDefined",
5718 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005719 break;
5720 }
5721 if (attributes != (const xmlChar **) NULL)
5722 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5723 {
5724 keyword=(const char *) attributes[i++];
5725 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005726 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005727 CloneString(&value,attribute);
5728 switch (*keyword)
5729 {
5730 case 'G':
5731 case 'g':
5732 {
5733 if (LocaleCompare(keyword,"geometry") == 0)
5734 {
5735 flags=ParseRegionGeometry(msl_info->image[n],value,
5736 &geometry,&exception);
5737 break;
5738 }
5739 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5740 keyword);
5741 break;
5742 }
5743 case 'H':
5744 case 'h':
5745 {
5746 if (LocaleCompare(keyword,"height") == 0)
5747 {
cristye27293e2009-12-18 02:53:20 +00005748 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005749 break;
5750 }
5751 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5752 keyword);
5753 break;
5754 }
5755 case 'W':
5756 case 'w':
5757 {
5758 if (LocaleCompare(keyword,"width") == 0)
5759 {
cristyf2f27272009-12-17 14:48:46 +00005760 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005761 break;
5762 }
5763 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5764 keyword);
5765 break;
5766 }
5767 default:
5768 {
5769 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5770 keyword);
5771 break;
5772 }
5773 }
5774 }
5775 sample_image=SampleImage(msl_info->image[n],geometry.width,
5776 geometry.height,&msl_info->image[n]->exception);
5777 if (sample_image == (Image *) NULL)
5778 break;
5779 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5780 msl_info->image[n]=sample_image;
5781 break;
5782 }
cristyb988fe72009-09-16 01:01:10 +00005783 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005784 {
5785 Image
5786 *scale_image;
5787
5788 /*
5789 Scale image.
5790 */
5791 if (msl_info->image[n] == (Image *) NULL)
5792 {
cristyb988fe72009-09-16 01:01:10 +00005793 ThrowMSLException(OptionError,"NoImagesDefined",
5794 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005795 break;
5796 }
5797 if (attributes != (const xmlChar **) NULL)
5798 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5799 {
5800 keyword=(const char *) attributes[i++];
5801 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005802 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005803 CloneString(&value,attribute);
5804 switch (*keyword)
5805 {
5806 case 'G':
5807 case 'g':
5808 {
5809 if (LocaleCompare(keyword,"geometry") == 0)
5810 {
5811 flags=ParseRegionGeometry(msl_info->image[n],value,
5812 &geometry,&exception);
5813 break;
5814 }
5815 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5816 keyword);
5817 break;
5818 }
5819 case 'H':
5820 case 'h':
5821 {
5822 if (LocaleCompare(keyword,"height") == 0)
5823 {
cristye27293e2009-12-18 02:53:20 +00005824 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005825 break;
5826 }
5827 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5828 keyword);
5829 break;
5830 }
5831 case 'W':
5832 case 'w':
5833 {
5834 if (LocaleCompare(keyword,"width") == 0)
5835 {
cristyf2f27272009-12-17 14:48:46 +00005836 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005837 break;
5838 }
5839 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5840 keyword);
5841 break;
5842 }
5843 default:
5844 {
5845 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5846 keyword);
5847 break;
5848 }
5849 }
5850 }
5851 scale_image=ScaleImage(msl_info->image[n],geometry.width,
5852 geometry.height,&msl_info->image[n]->exception);
5853 if (scale_image == (Image *) NULL)
5854 break;
5855 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5856 msl_info->image[n]=scale_image;
5857 break;
5858 }
cristyb988fe72009-09-16 01:01:10 +00005859 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005860 {
5861 ColorspaceType
5862 colorspace;
5863
5864 MagickBooleanType
5865 verbose;
cristyb988fe72009-09-16 01:01:10 +00005866
cristy3ed852e2009-09-05 21:47:34 +00005867 /*
5868 Segment image.
5869 */
5870 if (msl_info->image[n] == (Image *) NULL)
5871 {
cristyb988fe72009-09-16 01:01:10 +00005872 ThrowMSLException(OptionError,"NoImagesDefined",
5873 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005874 break;
5875 }
5876 geometry_info.rho=1.0;
5877 geometry_info.sigma=1.5;
5878 colorspace=RGBColorspace;
5879 verbose=MagickFalse;
5880 if (attributes != (const xmlChar **) NULL)
5881 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5882 {
5883 keyword=(const char *) attributes[i++];
5884 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005885 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005886 CloneString(&value,attribute);
5887 switch (*keyword)
5888 {
5889 case 'C':
5890 case 'c':
5891 {
5892 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5893 {
cristyc1acd842011-05-19 23:05:47 +00005894 geometry_info.rho=InterpretLocaleValue(value,
5895 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005896 break;
5897 }
5898 if (LocaleCompare(keyword,"colorspace") == 0)
5899 {
cristy042ee782011-04-22 18:48:30 +00005900 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005901 MagickFalse,value);
5902 if (option < 0)
5903 ThrowMSLException(OptionError,
5904 "UnrecognizedColorspaceType",value);
5905 colorspace=(ColorspaceType) option;
5906 break;
5907 }
5908 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5909 keyword);
5910 break;
5911 }
5912 case 'G':
5913 case 'g':
5914 {
5915 if (LocaleCompare(keyword,"geometry") == 0)
5916 {
5917 flags=ParseGeometry(value,&geometry_info);
5918 if ((flags & SigmaValue) == 0)
5919 geometry_info.sigma=1.5;
5920 break;
5921 }
5922 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5923 keyword);
5924 break;
5925 }
5926 case 'S':
5927 case 's':
5928 {
5929 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5930 {
cristyc1acd842011-05-19 23:05:47 +00005931 geometry_info.sigma=InterpretLocaleValue(value,
5932 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005933 break;
5934 }
5935 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5936 keyword);
5937 break;
5938 }
5939 default:
5940 {
5941 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5942 keyword);
5943 break;
5944 }
5945 }
5946 }
5947 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5948 geometry_info.rho,geometry_info.sigma);
5949 break;
5950 }
cristyb988fe72009-09-16 01:01:10 +00005951 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005952 {
5953 if (msl_info->image[n] == (Image *) NULL)
5954 {
cristyb988fe72009-09-16 01:01:10 +00005955 ThrowMSLException(OptionError,"NoImagesDefined",
5956 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005957 break;
5958 }
5959
5960 if (attributes == (const xmlChar **) NULL)
5961 break;
5962 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5963 {
5964 keyword=(const char *) attributes[i++];
5965 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005966 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005967 switch (*keyword)
5968 {
cristy3ed852e2009-09-05 21:47:34 +00005969 case 'C':
5970 case 'c':
5971 {
5972 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005973 {
cristy2c8b6312009-09-16 02:37:23 +00005974 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005975 {
cristy2c8b6312009-09-16 02:37:23 +00005976 const char
5977 *property;
5978
5979 property=GetImageProperty(msl_info->attributes[j],"id");
5980 if (LocaleCompare(property,value) == 0)
5981 {
5982 SetImageMask(msl_info->image[n],msl_info->image[j]);
5983 break;
5984 }
cristy3ed852e2009-09-05 21:47:34 +00005985 }
cristy2c8b6312009-09-16 02:37:23 +00005986 break;
cristy3ed852e2009-09-05 21:47:34 +00005987 }
cristy3ed852e2009-09-05 21:47:34 +00005988 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005989 {
cristy2c8b6312009-09-16 02:37:23 +00005990 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005991 {
cristy2c8b6312009-09-16 02:37:23 +00005992 const char
5993 *property;
5994
5995 property=GetImageProperty(msl_info->attributes[j],"id");
5996 if (LocaleCompare(property,value) == 0)
5997 {
5998 SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5999 break;
6000 }
cristy3ed852e2009-09-05 21:47:34 +00006001 }
cristy2c8b6312009-09-16 02:37:23 +00006002 break;
cristy3ed852e2009-09-05 21:47:34 +00006003 }
cristy2c8b6312009-09-16 02:37:23 +00006004 if (LocaleCompare(keyword,"colorspace") == 0)
6005 {
cristybb503372010-05-27 20:51:26 +00006006 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00006007 colorspace;
6008
cristy042ee782011-04-22 18:48:30 +00006009 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00006010 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00006011 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00006012 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00006013 value);
6014 (void) TransformImageColorspace(msl_info->image[n],
6015 (ColorspaceType) colorspace);
6016 break;
6017 }
6018 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006019 break;
6020 }
6021 case 'D':
6022 case 'd':
6023 {
cristy2c8b6312009-09-16 02:37:23 +00006024 if (LocaleCompare(keyword,"density") == 0)
6025 {
6026 flags=ParseGeometry(value,&geometry_info);
6027 msl_info->image[n]->x_resolution=geometry_info.rho;
6028 msl_info->image[n]->y_resolution=geometry_info.sigma;
6029 if ((flags & SigmaValue) == 0)
6030 msl_info->image[n]->y_resolution=
6031 msl_info->image[n]->x_resolution;
6032 break;
6033 }
6034 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006035 break;
6036 }
6037 case 'O':
6038 case 'o':
6039 {
6040 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006041 {
cristy4c08aed2011-07-01 19:47:50 +00006042 ssize_t opac = OpaqueAlpha,
cristybb503372010-05-27 20:51:26 +00006043 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006044
cristy2c8b6312009-09-16 02:37:23 +00006045 if (value[len-1] == '%') {
6046 char tmp[100];
6047 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006048 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006049 opac = (int)(QuantumRange * ((float)opac/100));
6050 } else
cristyf2f27272009-12-17 14:48:46 +00006051 opac = StringToLong( value );
cristy2c8b6312009-09-16 02:37:23 +00006052 (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6053 break;
cristy3ed852e2009-09-05 21:47:34 +00006054 }
cristy2c8b6312009-09-16 02:37:23 +00006055 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006056 break;
6057 }
6058 case 'P':
6059 case 'p':
6060 {
6061 if (LocaleCompare(keyword, "page") == 0)
6062 {
6063 char
6064 page[MaxTextExtent];
6065
6066 const char
6067 *image_option;
6068
6069 MagickStatusType
6070 flags;
6071
6072 RectangleInfo
6073 geometry;
6074
6075 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6076 image_option=GetImageOption(msl_info->image_info[n],"page");
6077 if (image_option != (const char *) NULL)
6078 flags=ParseAbsoluteGeometry(image_option,&geometry);
6079 flags=ParseAbsoluteGeometry(value,&geometry);
cristyb51dff52011-05-19 16:55:47 +00006080 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
cristye8c25f92010-06-03 00:53:06 +00006081 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006082 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristyb51dff52011-05-19 16:55:47 +00006083 (void) FormatLocaleString(page,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00006084 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6085 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006086 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006087 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6088 msl_info->image_info[n]->page=GetPageGeometry(page);
6089 break;
6090 }
cristy2c8b6312009-09-16 02:37:23 +00006091 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006092 break;
6093 }
6094 default:
6095 {
cristy2c8b6312009-09-16 02:37:23 +00006096 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006097 break;
6098 }
6099 }
6100 }
6101 break;
6102 }
cristyb988fe72009-09-16 01:01:10 +00006103 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006104 {
6105 Image
6106 *shade_image;
6107
6108 MagickBooleanType
6109 gray;
6110
6111 /*
6112 Shade image.
6113 */
6114 if (msl_info->image[n] == (Image *) NULL)
6115 {
cristyb988fe72009-09-16 01:01:10 +00006116 ThrowMSLException(OptionError,"NoImagesDefined",
6117 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006118 break;
6119 }
6120 gray=MagickFalse;
6121 if (attributes != (const xmlChar **) NULL)
6122 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6123 {
6124 keyword=(const char *) attributes[i++];
6125 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006126 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006127 CloneString(&value,attribute);
6128 switch (*keyword)
6129 {
6130 case 'A':
6131 case 'a':
6132 {
6133 if (LocaleCompare(keyword,"azimuth") == 0)
6134 {
cristyc1acd842011-05-19 23:05:47 +00006135 geometry_info.rho=InterpretLocaleValue(value,
6136 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006137 break;
6138 }
6139 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6140 keyword);
6141 break;
6142 }
6143 case 'E':
6144 case 'e':
6145 {
6146 if (LocaleCompare(keyword,"elevation") == 0)
6147 {
cristyc1acd842011-05-19 23:05:47 +00006148 geometry_info.sigma=InterpretLocaleValue(value,
6149 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006150 break;
6151 }
6152 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6153 keyword);
6154 break;
6155 }
6156 case 'G':
6157 case 'g':
6158 {
6159 if (LocaleCompare(keyword,"geometry") == 0)
6160 {
6161 flags=ParseGeometry(value,&geometry_info);
6162 if ((flags & SigmaValue) == 0)
6163 geometry_info.sigma=1.0;
6164 break;
6165 }
6166 if (LocaleCompare(keyword,"gray") == 0)
6167 {
cristy042ee782011-04-22 18:48:30 +00006168 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006169 value);
6170 if (option < 0)
6171 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6172 value);
6173 gray=(MagickBooleanType) option;
6174 break;
6175 }
6176 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6177 keyword);
6178 break;
6179 }
6180 default:
6181 {
6182 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6183 keyword);
6184 break;
6185 }
6186 }
6187 }
6188 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6189 geometry_info.sigma,&msl_info->image[n]->exception);
6190 if (shade_image == (Image *) NULL)
6191 break;
6192 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6193 msl_info->image[n]=shade_image;
6194 break;
6195 }
cristyb988fe72009-09-16 01:01:10 +00006196 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006197 {
6198 Image
6199 *shadow_image;
6200
6201 /*
6202 Shear image.
6203 */
6204 if (msl_info->image[n] == (Image *) NULL)
6205 {
cristyb988fe72009-09-16 01:01:10 +00006206 ThrowMSLException(OptionError,"NoImagesDefined",
6207 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006208 break;
6209 }
6210 if (attributes != (const xmlChar **) NULL)
6211 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6212 {
6213 keyword=(const char *) attributes[i++];
6214 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006215 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006216 CloneString(&value,attribute);
6217 switch (*keyword)
6218 {
6219 case 'G':
6220 case 'g':
6221 {
6222 if (LocaleCompare(keyword,"geometry") == 0)
6223 {
6224 flags=ParseGeometry(value,&geometry_info);
6225 if ((flags & SigmaValue) == 0)
6226 geometry_info.sigma=1.0;
6227 break;
6228 }
6229 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6230 keyword);
6231 break;
6232 }
6233 case 'O':
6234 case 'o':
6235 {
6236 if (LocaleCompare(keyword,"opacity") == 0)
6237 {
cristyf2f27272009-12-17 14:48:46 +00006238 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006239 break;
6240 }
6241 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6242 keyword);
6243 break;
6244 }
6245 case 'S':
6246 case 's':
6247 {
6248 if (LocaleCompare(keyword,"sigma") == 0)
6249 {
cristyf2f27272009-12-17 14:48:46 +00006250 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006251 break;
6252 }
6253 break;
6254 }
6255 case 'X':
6256 case 'x':
6257 {
6258 if (LocaleCompare(keyword,"x") == 0)
6259 {
cristyc1acd842011-05-19 23:05:47 +00006260 geometry_info.xi=InterpretLocaleValue(value,
6261 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006262 break;
6263 }
6264 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6265 keyword);
6266 break;
6267 }
6268 case 'Y':
6269 case 'y':
6270 {
6271 if (LocaleCompare(keyword,"y") == 0)
6272 {
cristyf2f27272009-12-17 14:48:46 +00006273 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006274 break;
6275 }
6276 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6277 keyword);
6278 break;
6279 }
6280 default:
6281 {
6282 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6283 keyword);
6284 break;
6285 }
6286 }
6287 }
6288 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristybb503372010-05-27 20:51:26 +00006289 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
cristy0534a6b2010-03-18 01:19:38 +00006290 ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006291 if (shadow_image == (Image *) NULL)
6292 break;
6293 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6294 msl_info->image[n]=shadow_image;
6295 break;
6296 }
cristyb988fe72009-09-16 01:01:10 +00006297 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006298 {
6299 double radius = 0.0,
6300 sigma = 1.0;
6301
6302 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006303 {
6304 ThrowMSLException(OptionError,"NoImagesDefined",
6305 (const char *) tag);
6306 break;
6307 }
cristy3ed852e2009-09-05 21:47:34 +00006308 /*
6309 NOTE: sharpen can have no attributes, since we use all the defaults!
6310 */
6311 if (attributes != (const xmlChar **) NULL)
6312 {
6313 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6314 {
6315 keyword=(const char *) attributes[i++];
6316 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006317 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006318 switch (*keyword)
6319 {
6320 case 'R':
6321 case 'r':
6322 {
6323 if (LocaleCompare(keyword, "radius") == 0)
6324 {
cristyc1acd842011-05-19 23:05:47 +00006325 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006326 break;
6327 }
6328 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6329 break;
6330 }
6331 case 'S':
6332 case 's':
6333 {
6334 if (LocaleCompare(keyword,"sigma") == 0)
6335 {
cristyf2f27272009-12-17 14:48:46 +00006336 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006337 break;
6338 }
6339 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6340 break;
6341 }
6342 default:
6343 {
6344 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6345 break;
6346 }
6347 }
6348 }
6349 }
6350
6351 /*
6352 sharpen image.
6353 */
6354 {
6355 Image
6356 *newImage;
6357
6358 newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6359 if (newImage == (Image *) NULL)
6360 break;
6361 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6362 msl_info->image[n]=newImage;
6363 break;
6364 }
6365 }
cristyb988fe72009-09-16 01:01:10 +00006366 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006367 {
6368 /* init the values */
6369 width = height = 0;
6370 x = y = 0;
6371
6372 if (msl_info->image[n] == (Image *) NULL)
6373 {
cristyb988fe72009-09-16 01:01:10 +00006374 ThrowMSLException(OptionError,"NoImagesDefined",
6375 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006376 break;
6377 }
6378 if (attributes == (const xmlChar **) NULL)
6379 break;
6380 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6381 {
6382 keyword=(const char *) attributes[i++];
6383 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006384 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006385 switch (*keyword)
6386 {
6387 case 'G':
6388 case 'g':
6389 {
6390 if (LocaleCompare(keyword,"geometry") == 0)
6391 {
6392 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6393 break;
6394 }
6395 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6396 break;
6397 }
6398 case 'H':
6399 case 'h':
6400 {
6401 if (LocaleCompare(keyword,"height") == 0)
6402 {
cristyf2f27272009-12-17 14:48:46 +00006403 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006404 break;
6405 }
6406 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6407 break;
6408 }
6409 case 'W':
6410 case 'w':
6411 {
6412 if (LocaleCompare(keyword,"width") == 0)
6413 {
cristyf2f27272009-12-17 14:48:46 +00006414 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006415 break;
6416 }
6417 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6418 break;
6419 }
6420 default:
6421 {
6422 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6423 break;
6424 }
6425 }
6426 }
6427
6428 /*
6429 process image.
6430 */
6431 {
6432 Image
6433 *newImage;
6434 RectangleInfo
6435 rectInfo;
6436
6437 rectInfo.height = height;
6438 rectInfo.width = width;
6439 rectInfo.x = x;
6440 rectInfo.y = y;
6441
6442
6443 newImage=ShaveImage(msl_info->image[n], &rectInfo,
6444 &msl_info->image[n]->exception);
6445 if (newImage == (Image *) NULL)
6446 break;
6447 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6448 msl_info->image[n]=newImage;
6449 }
6450
6451 break;
6452 }
cristyb988fe72009-09-16 01:01:10 +00006453 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006454 {
6455 Image
6456 *shear_image;
6457
6458 /*
6459 Shear image.
6460 */
6461 if (msl_info->image[n] == (Image *) NULL)
6462 {
cristyb988fe72009-09-16 01:01:10 +00006463 ThrowMSLException(OptionError,"NoImagesDefined",
6464 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006465 break;
6466 }
6467 if (attributes != (const xmlChar **) NULL)
6468 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6469 {
6470 keyword=(const char *) attributes[i++];
6471 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006472 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006473 CloneString(&value,attribute);
6474 switch (*keyword)
6475 {
6476 case 'F':
6477 case 'f':
6478 {
6479 if (LocaleCompare(keyword, "fill") == 0)
6480 {
6481 (void) QueryColorDatabase(value,
6482 &msl_info->image[n]->background_color,&exception);
6483 break;
6484 }
6485 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6486 keyword);
6487 break;
6488 }
6489 case 'G':
6490 case 'g':
6491 {
6492 if (LocaleCompare(keyword,"geometry") == 0)
6493 {
6494 flags=ParseGeometry(value,&geometry_info);
6495 if ((flags & SigmaValue) == 0)
6496 geometry_info.sigma=1.0;
6497 break;
6498 }
6499 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6500 keyword);
6501 break;
6502 }
6503 case 'X':
6504 case 'x':
6505 {
6506 if (LocaleCompare(keyword,"x") == 0)
6507 {
cristyc1acd842011-05-19 23:05:47 +00006508 geometry_info.rho=InterpretLocaleValue(value,
6509 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006510 break;
6511 }
6512 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6513 keyword);
6514 break;
6515 }
6516 case 'Y':
6517 case 'y':
6518 {
6519 if (LocaleCompare(keyword,"y") == 0)
6520 {
cristyf2f27272009-12-17 14:48:46 +00006521 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006522 break;
6523 }
6524 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6525 keyword);
6526 break;
6527 }
6528 default:
6529 {
6530 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6531 keyword);
6532 break;
6533 }
6534 }
6535 }
6536 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6537 geometry_info.sigma,&msl_info->image[n]->exception);
6538 if (shear_image == (Image *) NULL)
6539 break;
6540 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6541 msl_info->image[n]=shear_image;
6542 break;
6543 }
cristyb988fe72009-09-16 01:01:10 +00006544 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006545 {
6546 /*
6547 Signature image.
6548 */
6549 if (msl_info->image[n] == (Image *) NULL)
6550 {
cristyb988fe72009-09-16 01:01:10 +00006551 ThrowMSLException(OptionError,"NoImagesDefined",
6552 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006553 break;
6554 }
6555 if (attributes != (const xmlChar **) NULL)
6556 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6557 {
6558 keyword=(const char *) attributes[i++];
6559 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006560 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006561 CloneString(&value,attribute);
6562 switch (*keyword)
6563 {
6564 default:
6565 {
6566 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6567 keyword);
6568 break;
6569 }
6570 }
6571 }
6572 (void) SignatureImage(msl_info->image[n]);
6573 break;
6574 }
cristyb988fe72009-09-16 01:01:10 +00006575 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006576 {
6577 /*
6578 Solarize image.
6579 */
6580 if (msl_info->image[n] == (Image *) NULL)
6581 {
cristyb988fe72009-09-16 01:01:10 +00006582 ThrowMSLException(OptionError,"NoImagesDefined",
6583 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006584 break;
6585 }
6586 geometry_info.rho=QuantumRange/2.0;
6587 if (attributes != (const xmlChar **) NULL)
6588 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6589 {
6590 keyword=(const char *) attributes[i++];
6591 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006592 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006593 CloneString(&value,attribute);
6594 switch (*keyword)
6595 {
6596 case 'G':
6597 case 'g':
6598 {
6599 if (LocaleCompare(keyword,"geometry") == 0)
6600 {
6601 flags=ParseGeometry(value,&geometry_info);
6602 break;
6603 }
6604 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6605 keyword);
6606 break;
6607 }
6608 case 'T':
6609 case 't':
6610 {
6611 if (LocaleCompare(keyword,"threshold") == 0)
6612 {
cristyc1acd842011-05-19 23:05:47 +00006613 geometry_info.rho=InterpretLocaleValue(value,
6614 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006615 break;
6616 }
6617 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6618 keyword);
6619 break;
6620 }
6621 default:
6622 {
6623 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6624 keyword);
6625 break;
6626 }
6627 }
6628 }
6629 (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6630 break;
6631 }
cristyb988fe72009-09-16 01:01:10 +00006632 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006633 {
6634 Image
6635 *spread_image;
6636
6637 /*
6638 Spread image.
6639 */
6640 if (msl_info->image[n] == (Image *) NULL)
6641 {
cristyb988fe72009-09-16 01:01:10 +00006642 ThrowMSLException(OptionError,"NoImagesDefined",
6643 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006644 break;
6645 }
6646 if (attributes != (const xmlChar **) NULL)
6647 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6648 {
6649 keyword=(const char *) attributes[i++];
6650 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006651 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006652 CloneString(&value,attribute);
6653 switch (*keyword)
6654 {
6655 case 'G':
6656 case 'g':
6657 {
6658 if (LocaleCompare(keyword,"geometry") == 0)
6659 {
6660 flags=ParseGeometry(value,&geometry_info);
6661 if ((flags & SigmaValue) == 0)
6662 geometry_info.sigma=1.0;
6663 break;
6664 }
6665 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6666 keyword);
6667 break;
6668 }
6669 case 'R':
6670 case 'r':
6671 {
6672 if (LocaleCompare(keyword,"radius") == 0)
6673 {
cristyc1acd842011-05-19 23:05:47 +00006674 geometry_info.rho=InterpretLocaleValue(value,
6675 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006676 break;
6677 }
6678 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6679 keyword);
6680 break;
6681 }
6682 default:
6683 {
6684 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6685 keyword);
6686 break;
6687 }
6688 }
6689 }
6690 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6691 &msl_info->image[n]->exception);
6692 if (spread_image == (Image *) NULL)
6693 break;
6694 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6695 msl_info->image[n]=spread_image;
6696 break;
6697 }
cristyb988fe72009-09-16 01:01:10 +00006698 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006699 {
6700 Image *
6701 watermark = (Image*)NULL;
6702
6703 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006704 {
6705 ThrowMSLException(OptionError,"NoImagesDefined",
6706 (const char *) tag);
6707 break;
6708 }
cristy3ed852e2009-09-05 21:47:34 +00006709 if (attributes == (const xmlChar **) NULL)
6710 break;
6711 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6712 {
6713 keyword=(const char *) attributes[i++];
6714 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006715 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006716 switch (*keyword)
6717 {
6718 case 'I':
6719 case 'i':
6720 {
6721 if (LocaleCompare(keyword,"image") == 0)
6722 {
6723 for (j=0; j<msl_info->n;j++)
6724 {
6725 const char *
6726 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6727 if (theAttr && LocaleCompare(theAttr, value) == 0)
6728 {
6729 watermark = msl_info->image[j];
6730 break;
6731 }
6732 }
6733 break;
6734 }
6735 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6736 break;
6737 }
6738 default:
6739 {
6740 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6741 break;
6742 }
6743 }
6744 }
6745
6746 /*
6747 process image.
6748 */
6749 if ( watermark != (Image*) NULL )
6750 {
6751 Image
6752 *newImage;
6753
6754 newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6755 if (newImage == (Image *) NULL)
6756 break;
6757 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6758 msl_info->image[n]=newImage;
6759 break;
6760 } else
6761 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6762 }
cristyb988fe72009-09-16 01:01:10 +00006763 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006764 {
6765 Image *
6766 stereoImage = (Image*)NULL;
6767
6768 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006769 {
6770 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6771 break;
6772 }
cristy3ed852e2009-09-05 21:47:34 +00006773 if (attributes == (const xmlChar **) NULL)
6774 break;
6775 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6776 {
6777 keyword=(const char *) attributes[i++];
6778 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006779 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006780 switch (*keyword)
6781 {
6782 case 'I':
6783 case 'i':
6784 {
6785 if (LocaleCompare(keyword,"image") == 0)
6786 {
6787 for (j=0; j<msl_info->n;j++)
6788 {
6789 const char *
6790 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6791 if (theAttr && LocaleCompare(theAttr, value) == 0)
6792 {
6793 stereoImage = msl_info->image[j];
6794 break;
6795 }
6796 }
6797 break;
6798 }
6799 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6800 break;
6801 }
6802 default:
6803 {
6804 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6805 break;
6806 }
6807 }
6808 }
6809
6810 /*
6811 process image.
6812 */
6813 if ( stereoImage != (Image*) NULL )
6814 {
6815 Image
6816 *newImage;
6817
6818 newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6819 if (newImage == (Image *) NULL)
6820 break;
6821 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6822 msl_info->image[n]=newImage;
6823 break;
6824 } else
6825 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6826 }
cristyb988fe72009-09-16 01:01:10 +00006827 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006828 {
6829 Image
6830 *p,
6831 *q,
6832 *swap;
6833
cristybb503372010-05-27 20:51:26 +00006834 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006835 index,
6836 swap_index;
6837
6838 if (msl_info->image[n] == (Image *) NULL)
6839 {
cristyb988fe72009-09-16 01:01:10 +00006840 ThrowMSLException(OptionError,"NoImagesDefined",
6841 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006842 break;
6843 }
6844 index=(-1);
6845 swap_index=(-2);
6846 if (attributes != (const xmlChar **) NULL)
6847 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6848 {
6849 keyword=(const char *) attributes[i++];
6850 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006851 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006852 CloneString(&value,attribute);
6853 switch (*keyword)
6854 {
6855 case 'G':
6856 case 'g':
6857 {
6858 if (LocaleCompare(keyword,"indexes") == 0)
6859 {
6860 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006861 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006862 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006863 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006864 break;
6865 }
6866 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6867 keyword);
6868 break;
6869 }
6870 default:
6871 {
6872 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6873 keyword);
6874 break;
6875 }
6876 }
6877 }
6878 /*
6879 Swap images.
6880 */
6881 p=GetImageFromList(msl_info->image[n],index);
6882 q=GetImageFromList(msl_info->image[n],swap_index);
6883 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6884 {
cristyb988fe72009-09-16 01:01:10 +00006885 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006886 break;
6887 }
6888 swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6889 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6890 ReplaceImageInList(&q,swap);
6891 msl_info->image[n]=GetFirstImageInList(q);
6892 break;
6893 }
cristyb988fe72009-09-16 01:01:10 +00006894 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006895 {
6896 Image
6897 *swirl_image;
6898
6899 /*
6900 Swirl image.
6901 */
6902 if (msl_info->image[n] == (Image *) NULL)
6903 {
cristyb988fe72009-09-16 01:01:10 +00006904 ThrowMSLException(OptionError,"NoImagesDefined",
6905 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006906 break;
6907 }
6908 if (attributes != (const xmlChar **) NULL)
6909 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6910 {
6911 keyword=(const char *) attributes[i++];
6912 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006913 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006914 CloneString(&value,attribute);
6915 switch (*keyword)
6916 {
6917 case 'D':
6918 case 'd':
6919 {
6920 if (LocaleCompare(keyword,"degrees") == 0)
6921 {
cristyc1acd842011-05-19 23:05:47 +00006922 geometry_info.rho=InterpretLocaleValue(value,
6923 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006924 break;
6925 }
6926 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6927 keyword);
6928 break;
6929 }
6930 case 'G':
6931 case 'g':
6932 {
6933 if (LocaleCompare(keyword,"geometry") == 0)
6934 {
6935 flags=ParseGeometry(value,&geometry_info);
6936 if ((flags & SigmaValue) == 0)
6937 geometry_info.sigma=1.0;
6938 break;
6939 }
6940 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6941 keyword);
6942 break;
6943 }
6944 default:
6945 {
6946 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6947 keyword);
6948 break;
6949 }
6950 }
6951 }
6952 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6953 &msl_info->image[n]->exception);
6954 if (swirl_image == (Image *) NULL)
6955 break;
6956 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6957 msl_info->image[n]=swirl_image;
6958 break;
6959 }
cristyb988fe72009-09-16 01:01:10 +00006960 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006961 {
6962 /*
6963 Sync image.
6964 */
6965 if (msl_info->image[n] == (Image *) NULL)
6966 {
cristyb988fe72009-09-16 01:01:10 +00006967 ThrowMSLException(OptionError,"NoImagesDefined",
6968 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006969 break;
6970 }
6971 if (attributes != (const xmlChar **) NULL)
6972 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6973 {
6974 keyword=(const char *) attributes[i++];
6975 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006976 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006977 CloneString(&value,attribute);
6978 switch (*keyword)
6979 {
6980 default:
6981 {
6982 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6983 keyword);
6984 break;
6985 }
6986 }
6987 }
6988 (void) SyncImage(msl_info->image[n]);
6989 break;
6990 }
6991 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6992 }
6993 case 'T':
6994 case 't':
6995 {
cristyb988fe72009-09-16 01:01:10 +00006996 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006997 {
6998 Image
6999 *texture_image;
7000
7001 /*
7002 Texture image.
7003 */
7004 if (msl_info->image[n] == (Image *) NULL)
7005 {
cristyb988fe72009-09-16 01:01:10 +00007006 ThrowMSLException(OptionError,"NoImagesDefined",
7007 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007008 break;
7009 }
7010 texture_image=NewImageList();
7011 if (attributes != (const xmlChar **) NULL)
7012 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7013 {
7014 keyword=(const char *) attributes[i++];
7015 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007016 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00007017 CloneString(&value,attribute);
7018 switch (*keyword)
7019 {
7020 case 'I':
7021 case 'i':
7022 {
7023 if (LocaleCompare(keyword,"image") == 0)
7024 for (j=0; j < msl_info->n; j++)
7025 {
7026 const char
7027 *attribute;
cristyb988fe72009-09-16 01:01:10 +00007028
cristy3ed852e2009-09-05 21:47:34 +00007029 attribute=GetImageProperty(msl_info->attributes[j],"id");
7030 if ((attribute != (const char *) NULL) &&
7031 (LocaleCompare(attribute,value) == 0))
7032 {
7033 texture_image=CloneImage(msl_info->image[j],0,0,
7034 MagickFalse,&exception);
7035 break;
7036 }
7037 }
7038 break;
7039 }
7040 default:
7041 {
7042 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7043 keyword);
7044 break;
7045 }
7046 }
7047 }
7048 (void) TextureImage(msl_info->image[n],texture_image);
7049 texture_image=DestroyImage(texture_image);
7050 break;
7051 }
cristyb988fe72009-09-16 01:01:10 +00007052 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007053 {
7054 /* init the values */
7055 double threshold = 0;
7056
7057 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007058 {
7059 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7060 break;
7061 }
cristy3ed852e2009-09-05 21:47:34 +00007062 if (attributes == (const xmlChar **) NULL)
7063 break;
7064 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7065 {
7066 keyword=(const char *) attributes[i++];
7067 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007068 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007069 switch (*keyword)
7070 {
7071 case 'T':
7072 case 't':
7073 {
7074 if (LocaleCompare(keyword,"threshold") == 0)
7075 {
cristyc1acd842011-05-19 23:05:47 +00007076 threshold = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007077 break;
7078 }
7079 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7080 break;
7081 }
7082 default:
7083 {
7084 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7085 break;
7086 }
7087 }
7088 }
7089
7090 /*
7091 process image.
7092 */
7093 {
7094 BilevelImageChannel(msl_info->image[n],
cristy9a9230e2011-04-26 14:56:14 +00007095 (ChannelType) ((ssize_t) (CompositeChannels &~ (ssize_t) OpacityChannel)),
cristy3ed852e2009-09-05 21:47:34 +00007096 threshold);
7097 break;
7098 }
7099 }
cristyb988fe72009-09-16 01:01:10 +00007100 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007101 {
7102 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007103 {
7104 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7105 break;
7106 }
cristy3ed852e2009-09-05 21:47:34 +00007107 if (attributes == (const xmlChar **) NULL)
7108 break;
7109 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7110 {
7111 keyword=(const char *) attributes[i++];
7112 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007113 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007114 switch (*keyword)
7115 {
7116 case 'C':
7117 case 'c':
7118 {
7119 if (LocaleCompare(keyword,"color") == 0)
7120 {
cristy4c08aed2011-07-01 19:47:50 +00007121 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00007122 target;
7123
7124 (void) QueryMagickColor(value,&target,&exception);
7125 (void) TransparentPaintImage(msl_info->image[n],&target,
cristy4c08aed2011-07-01 19:47:50 +00007126 TransparentAlpha,MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +00007127 break;
7128 }
7129 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7130 break;
7131 }
7132 default:
7133 {
7134 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7135 break;
7136 }
7137 }
7138 }
7139 break;
7140 }
cristyb988fe72009-09-16 01:01:10 +00007141 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007142 {
7143 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007144 {
7145 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7146 break;
7147 }
cristy3ed852e2009-09-05 21:47:34 +00007148
7149 /* no attributes here */
7150
7151 /* process the image */
7152 {
7153 Image
7154 *newImage;
7155 RectangleInfo
7156 rectInfo;
7157
7158 /* all zeros on a crop == trim edges! */
7159 rectInfo.height = rectInfo.width = 0;
7160 rectInfo.x = rectInfo.y = 0;
7161
7162 newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7163 if (newImage == (Image *) NULL)
7164 break;
7165 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7166 msl_info->image[n]=newImage;
7167 break;
7168 }
7169 }
7170 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7171 }
7172 case 'W':
7173 case 'w':
7174 {
cristyb988fe72009-09-16 01:01:10 +00007175 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007176 {
7177 if (msl_info->image[n] == (Image *) NULL)
7178 {
cristyb988fe72009-09-16 01:01:10 +00007179 ThrowMSLException(OptionError,"NoImagesDefined",
7180 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007181 break;
7182 }
7183 if (attributes == (const xmlChar **) NULL)
7184 break;
7185 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7186 {
7187 keyword=(const char *) attributes[i++];
7188 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007189 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007190 switch (*keyword)
7191 {
7192 case 'F':
7193 case 'f':
7194 {
7195 if (LocaleCompare(keyword,"filename") == 0)
7196 {
7197 (void) CopyMagickString(msl_info->image[n]->filename,value,
7198 MaxTextExtent);
7199 break;
7200 }
cristy4582cbb2009-09-23 00:35:43 +00007201 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007202 }
7203 default:
7204 {
cristy4582cbb2009-09-23 00:35:43 +00007205 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007206 break;
7207 }
7208 }
7209 }
7210
7211 /* process */
7212 {
7213 (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7214 break;
7215 }
7216 }
7217 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7218 }
7219 default:
7220 {
7221 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7222 break;
7223 }
7224 }
7225 if ( value != NULL )
7226 value=DestroyString(value);
7227 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7228}
7229
7230static void MSLEndElement(void *context,const xmlChar *tag)
7231{
cristybb503372010-05-27 20:51:26 +00007232 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007233 n;
7234
7235 MSLInfo
7236 *msl_info;
7237
7238 /*
7239 Called when the end of an element has been detected.
7240 */
7241 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7242 tag);
7243 msl_info=(MSLInfo *) context;
7244 n=msl_info->n;
7245 switch (*tag)
7246 {
7247 case 'C':
7248 case 'c':
7249 {
cristyb988fe72009-09-16 01:01:10 +00007250 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007251 {
7252 (void) DeleteImageProperty(msl_info->image[n],"comment");
7253 if (msl_info->content == (char *) NULL)
7254 break;
7255 StripString(msl_info->content);
7256 (void) SetImageProperty(msl_info->image[n],"comment",
7257 msl_info->content);
7258 break;
7259 }
7260 break;
7261 }
7262 case 'G':
7263 case 'g':
7264 {
cristyb988fe72009-09-16 01:01:10 +00007265 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007266 {
7267 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7268 {
cristybb503372010-05-27 20:51:26 +00007269 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007270 (msl_info->group_info[msl_info->number_groups-1].numImages);
7271 while ( i-- )
7272 {
7273 if (msl_info->image[msl_info->n] != (Image *) NULL)
7274 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7275 msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7276 msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7277 msl_info->n--;
7278 }
7279 }
7280 msl_info->number_groups--;
7281 }
7282 break;
7283 }
7284 case 'I':
7285 case 'i':
7286 {
cristyb988fe72009-09-16 01:01:10 +00007287 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007288 MSLPopImage(msl_info);
7289 break;
7290 }
7291 case 'L':
7292 case 'l':
7293 {
cristyb988fe72009-09-16 01:01:10 +00007294 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007295 {
7296 (void) DeleteImageProperty(msl_info->image[n],"label");
7297 if (msl_info->content == (char *) NULL)
7298 break;
7299 StripString(msl_info->content);
7300 (void) SetImageProperty(msl_info->image[n],"label",
7301 msl_info->content);
7302 break;
7303 }
7304 break;
7305 }
7306 case 'M':
7307 case 'm':
7308 {
cristyb988fe72009-09-16 01:01:10 +00007309 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007310 {
7311 /*
7312 This our base element.
7313 at the moment we don't do anything special
7314 but someday we might!
7315 */
7316 }
7317 break;
7318 }
7319 default:
7320 break;
7321 }
7322 if (msl_info->content != (char *) NULL)
7323 msl_info->content=DestroyString(msl_info->content);
7324}
7325
7326static void MSLCharacters(void *context,const xmlChar *c,int length)
7327{
7328 MSLInfo
7329 *msl_info;
7330
7331 register char
7332 *p;
7333
cristybb503372010-05-27 20:51:26 +00007334 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007335 i;
7336
7337 /*
7338 Receiving some characters from the parser.
7339 */
7340 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7341 " SAX.characters(%s,%d)",c,length);
7342 msl_info=(MSLInfo *) context;
7343 if (msl_info->content != (char *) NULL)
7344 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7345 strlen(msl_info->content)+length+MaxTextExtent,
7346 sizeof(*msl_info->content));
7347 else
7348 {
7349 msl_info->content=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +00007350 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00007351 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7352 sizeof(*msl_info->content));
7353 if (msl_info->content != (char *) NULL)
7354 *msl_info->content='\0';
7355 }
7356 if (msl_info->content == (char *) NULL)
7357 return;
7358 p=msl_info->content+strlen(msl_info->content);
7359 for (i=0; i < length; i++)
7360 *p++=c[i];
7361 *p='\0';
7362}
7363
7364static void MSLReference(void *context,const xmlChar *name)
7365{
7366 MSLInfo
7367 *msl_info;
7368
7369 xmlParserCtxtPtr
7370 parser;
7371
7372 /*
7373 Called when an entity reference is detected.
7374 */
7375 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7376 " SAX.reference(%s)",name);
7377 msl_info=(MSLInfo *) context;
7378 parser=msl_info->parser;
7379 if (*name == '#')
7380 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7381 else
7382 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7383}
7384
7385static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7386{
7387 MSLInfo
7388 *msl_info;
7389
7390 /*
7391 Receiving some ignorable whitespaces from the parser.
7392 */
7393 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7394 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7395 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007396 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007397}
7398
7399static void MSLProcessingInstructions(void *context,const xmlChar *target,
7400 const xmlChar *data)
7401{
7402 MSLInfo
7403 *msl_info;
7404
7405 /*
7406 A processing instruction has been parsed.
7407 */
7408 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7409 " SAX.processingInstruction(%s, %s)",
7410 target,data);
7411 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007412 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007413}
7414
7415static void MSLComment(void *context,const xmlChar *value)
7416{
7417 MSLInfo
7418 *msl_info;
7419
7420 /*
7421 A comment has been parsed.
7422 */
7423 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7424 " SAX.comment(%s)",value);
7425 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007426 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007427}
7428
7429static void MSLWarning(void *context,const char *format,...)
7430{
7431 char
7432 *message,
7433 reason[MaxTextExtent];
7434
7435 MSLInfo
7436 *msl_info;
7437
7438 va_list
7439 operands;
7440
7441 /**
7442 Display and format a warning messages, gives file, line, position and
7443 extra parameters.
7444 */
7445 va_start(operands,format);
7446 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7447 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7448 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007449 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007450#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7451 (void) vsprintf(reason,format,operands);
7452#else
7453 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7454#endif
7455 message=GetExceptionMessage(errno);
7456 ThrowMSLException(CoderError,reason,message);
7457 message=DestroyString(message);
7458 va_end(operands);
7459}
7460
7461static void MSLError(void *context,const char *format,...)
7462{
7463 char
7464 reason[MaxTextExtent];
7465
7466 MSLInfo
7467 *msl_info;
7468
7469 va_list
7470 operands;
7471
7472 /*
7473 Display and format a error formats, gives file, line, position and
7474 extra parameters.
7475 */
7476 va_start(operands,format);
7477 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7478 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7479 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007480 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007481#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7482 (void) vsprintf(reason,format,operands);
7483#else
7484 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7485#endif
7486 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7487 va_end(operands);
7488}
7489
7490static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7491{
7492 MSLInfo
7493 *msl_info;
7494
7495 xmlNodePtr
7496 child;
7497
7498 xmlParserCtxtPtr
7499 parser;
7500
7501 /*
7502 Called when a pcdata block has been parsed.
7503 */
7504 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7505 " SAX.pcdata(%s, %d)",value,length);
7506 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007507 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007508 parser=msl_info->parser;
7509 child=xmlGetLastChild(parser->node);
7510 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7511 {
7512 xmlTextConcat(child,value,length);
7513 return;
7514 }
7515 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7516}
7517
7518static void MSLExternalSubset(void *context,const xmlChar *name,
7519 const xmlChar *external_id,const xmlChar *system_id)
7520{
7521 MSLInfo
7522 *msl_info;
7523
7524 xmlParserCtxt
7525 parser_context;
7526
7527 xmlParserCtxtPtr
7528 parser;
7529
7530 xmlParserInputPtr
7531 input;
7532
7533 /*
7534 Does this document has an external subset?
7535 */
7536 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7537 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007538 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7539 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007540 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007541 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007542 parser=msl_info->parser;
7543 if (((external_id == NULL) && (system_id == NULL)) ||
7544 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7545 (msl_info->document == 0)))
7546 return;
7547 input=MSLResolveEntity(context,external_id,system_id);
7548 if (input == NULL)
7549 return;
7550 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7551 parser_context=(*parser);
7552 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7553 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7554 {
7555 parser->errNo=XML_ERR_NO_MEMORY;
7556 parser->input=parser_context.input;
7557 parser->inputNr=parser_context.inputNr;
7558 parser->inputMax=parser_context.inputMax;
7559 parser->inputTab=parser_context.inputTab;
7560 return;
7561 }
7562 parser->inputNr=0;
7563 parser->inputMax=5;
7564 parser->input=NULL;
7565 xmlPushInput(parser,input);
7566 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7567 if (input->filename == (char *) NULL)
7568 input->filename=(char *) xmlStrdup(system_id);
7569 input->line=1;
7570 input->col=1;
7571 input->base=parser->input->cur;
7572 input->cur=parser->input->cur;
7573 input->free=NULL;
7574 xmlParseExternalSubset(parser,external_id,system_id);
7575 while (parser->inputNr > 1)
7576 (void) xmlPopInput(parser);
7577 xmlFreeInputStream(parser->input);
7578 xmlFree(parser->inputTab);
7579 parser->input=parser_context.input;
7580 parser->inputNr=parser_context.inputNr;
7581 parser->inputMax=parser_context.inputMax;
7582 parser->inputTab=parser_context.inputTab;
7583}
7584
7585#if defined(__cplusplus) || defined(c_plusplus)
7586}
7587#endif
7588
7589static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7590 ExceptionInfo *exception)
7591{
cristy3ed852e2009-09-05 21:47:34 +00007592 char
7593 message[MaxTextExtent];
7594
7595 Image
7596 *msl_image;
7597
7598 int
7599 status;
7600
cristybb503372010-05-27 20:51:26 +00007601 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007602 n;
7603
7604 MSLInfo
7605 msl_info;
7606
cristy5f6f01c2009-11-19 19:36:42 +00007607 xmlSAXHandler
7608 sax_modules;
7609
cristy3ed852e2009-09-05 21:47:34 +00007610 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007611 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007612
7613 /*
7614 Open image file.
7615 */
7616 assert(image_info != (const ImageInfo *) NULL);
7617 assert(image_info->signature == MagickSignature);
7618 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007619 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7620 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007621 assert(image != (Image **) NULL);
7622 msl_image=AcquireImage(image_info);
7623 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7624 if (status == MagickFalse)
7625 {
7626 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7627 msl_image->filename);
7628 msl_image=DestroyImageList(msl_image);
7629 return(MagickFalse);
7630 }
7631 msl_image->columns=1;
7632 msl_image->rows=1;
7633 /*
7634 Parse MSL file.
7635 */
7636 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7637 msl_info.exception=exception;
7638 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7639 sizeof(*msl_info.image_info));
7640 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7641 sizeof(*msl_info.draw_info));
7642 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007643 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007644 msl_info.attributes=(Image **) AcquireMagickMemory(
7645 sizeof(*msl_info.attributes));
7646 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7647 sizeof(*msl_info.group_info));
7648 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7649 (msl_info.image == (Image **) NULL) ||
7650 (msl_info.attributes == (Image **) NULL) ||
7651 (msl_info.group_info == (MSLGroupInfo *) NULL))
7652 ThrowFatalException(ResourceLimitFatalError,
7653 "UnableToInterpretMSLImage");
7654 *msl_info.image_info=CloneImageInfo(image_info);
7655 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7656 *msl_info.attributes=AcquireImage(image_info);
7657 msl_info.group_info[0].numImages=0;
7658 /* the first slot is used to point to the MSL file image */
7659 *msl_info.image=msl_image;
7660 if (*image != (Image *) NULL)
7661 MSLPushImage(&msl_info,*image);
7662 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007663 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7664 sax_modules.internalSubset=MSLInternalSubset;
7665 sax_modules.isStandalone=MSLIsStandalone;
7666 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7667 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7668 sax_modules.resolveEntity=MSLResolveEntity;
7669 sax_modules.getEntity=MSLGetEntity;
7670 sax_modules.entityDecl=MSLEntityDeclaration;
7671 sax_modules.notationDecl=MSLNotationDeclaration;
7672 sax_modules.attributeDecl=MSLAttributeDeclaration;
7673 sax_modules.elementDecl=MSLElementDeclaration;
7674 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7675 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7676 sax_modules.startDocument=MSLStartDocument;
7677 sax_modules.endDocument=MSLEndDocument;
7678 sax_modules.startElement=MSLStartElement;
7679 sax_modules.endElement=MSLEndElement;
7680 sax_modules.reference=MSLReference;
7681 sax_modules.characters=MSLCharacters;
7682 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7683 sax_modules.processingInstruction=MSLProcessingInstructions;
7684 sax_modules.comment=MSLComment;
7685 sax_modules.warning=MSLWarning;
7686 sax_modules.error=MSLError;
7687 sax_modules.fatalError=MSLError;
7688 sax_modules.getParameterEntity=MSLGetParameterEntity;
7689 sax_modules.cdataBlock=MSLCDataBlock;
7690 sax_modules.externalSubset=MSLExternalSubset;
7691 sax_handler=(&sax_modules);
7692 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007693 msl_image->filename);
7694 while (ReadBlobString(msl_image,message) != (char *) NULL)
7695 {
cristybb503372010-05-27 20:51:26 +00007696 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007697 if (n == 0)
7698 continue;
7699 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7700 if (status != 0)
7701 break;
7702 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7703 if (msl_info.exception->severity >= ErrorException)
7704 break;
7705 }
7706 if (msl_info.exception->severity == UndefinedException)
7707 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7708 xmlFreeParserCtxt(msl_info.parser);
7709 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7710 xmlCleanupParser();
7711 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7712 msl_info.group_info);
7713 if (*image == (Image *) NULL)
7714 *image=(*msl_info.image);
cristy5f6f01c2009-11-19 19:36:42 +00007715 if ((*msl_info.image)->exception.severity != UndefinedException)
7716 return(MagickFalse);
7717 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007718}
7719
7720static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7721{
7722 Image
7723 *image;
7724
7725 /*
7726 Open image file.
7727 */
7728 assert(image_info != (const ImageInfo *) NULL);
7729 assert(image_info->signature == MagickSignature);
7730 if (image_info->debug != MagickFalse)
7731 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7732 image_info->filename);
7733 assert(exception != (ExceptionInfo *) NULL);
7734 assert(exception->signature == MagickSignature);
7735 image=(Image *) NULL;
7736 (void) ProcessMSLScript(image_info,&image,exception);
7737 return(GetFirstImageInList(image));
7738}
7739#endif
7740
7741/*
7742%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7743% %
7744% %
7745% %
7746% R e g i s t e r M S L I m a g e %
7747% %
7748% %
7749% %
7750%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7751%
7752% RegisterMSLImage() adds attributes for the MSL image format to
7753% the list of supported formats. The attributes include the image format
7754% tag, a method to read and/or write the format, whether the format
7755% supports the saving of more than one frame to the same file or blob,
7756% whether the format supports native in-memory I/O, and a brief
7757% description of the format.
7758%
7759% The format of the RegisterMSLImage method is:
7760%
cristybb503372010-05-27 20:51:26 +00007761% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007762%
7763*/
cristybb503372010-05-27 20:51:26 +00007764ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007765{
7766 MagickInfo
7767 *entry;
7768
7769 entry=SetMagickInfo("MSL");
7770#if defined(MAGICKCORE_XML_DELEGATE)
7771 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7772 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7773#endif
7774 entry->description=ConstantString("Magick Scripting Language");
7775 entry->module=ConstantString("MSL");
7776 (void) RegisterMagickInfo(entry);
7777 return(MagickImageCoderSignature);
7778}
7779
cristy6b9f7ed2010-04-24 01:08:02 +00007780#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007781/*
7782%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7783% %
7784% %
7785% %
cristyb988fe72009-09-16 01:01:10 +00007786% S e t M S L A t t r i b u t e s %
7787% %
7788% %
7789% %
7790%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7791%
7792% SetMSLAttributes() ...
7793%
7794% The format of the SetMSLAttributes method is:
7795%
7796% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007797% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007798%
7799% A description of each parameter follows:
7800%
7801% o msl_info: the MSL info.
7802%
cristyb20775d2009-09-16 01:51:41 +00007803% o keyword: the keyword.
7804%
7805% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007806%
7807*/
cristyb20775d2009-09-16 01:51:41 +00007808static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7809 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007810{
cristy4582cbb2009-09-23 00:35:43 +00007811 Image
7812 *attributes;
7813
cristyb20775d2009-09-16 01:51:41 +00007814 DrawInfo
7815 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007816
7817 ExceptionInfo
7818 *exception;
7819
cristy4582cbb2009-09-23 00:35:43 +00007820 GeometryInfo
7821 geometry_info;
7822
cristy4fa36e42009-09-18 14:24:06 +00007823 Image
7824 *image;
7825
cristyb20775d2009-09-16 01:51:41 +00007826 ImageInfo
7827 *image_info;
7828
cristy4582cbb2009-09-23 00:35:43 +00007829 int
7830 flags;
7831
cristybb503372010-05-27 20:51:26 +00007832 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007833 n;
7834
cristyb988fe72009-09-16 01:01:10 +00007835 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007836 if (keyword == (const char *) NULL)
7837 return(MagickTrue);
7838 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007839 return(MagickTrue);
7840 exception=msl_info->exception;
7841 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007842 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007843 image_info=msl_info->image_info[n];
7844 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007845 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007846 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007847 {
cristyfb758a52009-09-16 14:36:08 +00007848 case 'A':
7849 case 'a':
7850 {
7851 if (LocaleCompare(keyword,"adjoin") == 0)
7852 {
cristybb503372010-05-27 20:51:26 +00007853 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007854 adjoin;
7855
cristy042ee782011-04-22 18:48:30 +00007856 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007857 if (adjoin < 0)
7858 ThrowMSLException(OptionError,"UnrecognizedType",value);
7859 image_info->adjoin=(MagickBooleanType) adjoin;
7860 break;
7861 }
cristy4fa36e42009-09-18 14:24:06 +00007862 if (LocaleCompare(keyword,"alpha") == 0)
7863 {
cristybb503372010-05-27 20:51:26 +00007864 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007865 alpha;
7866
cristy042ee782011-04-22 18:48:30 +00007867 alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007868 if (alpha < 0)
7869 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007870 if (image != (Image *) NULL)
7871 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha);
7872 break;
7873 }
7874 if (LocaleCompare(keyword,"antialias") == 0)
7875 {
cristybb503372010-05-27 20:51:26 +00007876 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007877 antialias;
7878
cristy042ee782011-04-22 18:48:30 +00007879 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007880 if (antialias < 0)
7881 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7882 image_info->antialias=(MagickBooleanType) antialias;
7883 break;
7884 }
7885 if (LocaleCompare(keyword,"area-limit") == 0)
7886 {
7887 MagickSizeType
7888 limit;
7889
7890 limit=MagickResourceInfinity;
7891 if (LocaleCompare(value,"unlimited") != 0)
cristyf2f27272009-12-17 14:48:46 +00007892 limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007893 (void) SetMagickResourceLimit(AreaResource,limit);
7894 break;
7895 }
7896 if (LocaleCompare(keyword,"attenuate") == 0)
7897 {
7898 (void) SetImageOption(image_info,keyword,value);
7899 break;
7900 }
7901 if (LocaleCompare(keyword,"authenticate") == 0)
7902 {
7903 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007904 break;
7905 }
cristyfb758a52009-09-16 14:36:08 +00007906 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7907 break;
7908 }
cristyb20775d2009-09-16 01:51:41 +00007909 case 'B':
7910 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007911 {
cristyb20775d2009-09-16 01:51:41 +00007912 if (LocaleCompare(keyword,"background") == 0)
7913 {
cristy2c8b6312009-09-16 02:37:23 +00007914 (void) QueryColorDatabase(value,&image_info->background_color,
cristyb20775d2009-09-16 01:51:41 +00007915 exception);
7916 break;
7917 }
cristy4582cbb2009-09-23 00:35:43 +00007918 if (LocaleCompare(keyword,"bias") == 0)
7919 {
7920 if (image == (Image *) NULL)
7921 break;
cristyf2f27272009-12-17 14:48:46 +00007922 image->bias=SiPrefixToDouble(value,QuantumRange);
cristy4582cbb2009-09-23 00:35:43 +00007923 break;
7924 }
7925 if (LocaleCompare(keyword,"blue-primary") == 0)
7926 {
7927 if (image == (Image *) NULL)
7928 break;
7929 flags=ParseGeometry(value,&geometry_info);
7930 image->chromaticity.blue_primary.x=geometry_info.rho;
7931 image->chromaticity.blue_primary.y=geometry_info.sigma;
7932 if ((flags & SigmaValue) == 0)
7933 image->chromaticity.blue_primary.y=
7934 image->chromaticity.blue_primary.x;
7935 break;
7936 }
cristy2c8b6312009-09-16 02:37:23 +00007937 if (LocaleCompare(keyword,"bordercolor") == 0)
7938 {
7939 (void) QueryColorDatabase(value,&image_info->border_color,
7940 exception);
7941 break;
7942 }
7943 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7944 break;
7945 }
7946 case 'D':
7947 case 'd':
7948 {
7949 if (LocaleCompare(keyword,"density") == 0)
7950 {
7951 (void) CloneString(&image_info->density,value);
7952 (void) CloneString(&draw_info->density,value);
7953 break;
7954 }
cristyb20775d2009-09-16 01:51:41 +00007955 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7956 break;
7957 }
7958 case 'F':
7959 case 'f':
7960 {
7961 if (LocaleCompare(keyword,"fill") == 0)
7962 {
cristy2c8b6312009-09-16 02:37:23 +00007963 (void) QueryColorDatabase(value,&draw_info->fill,exception);
cristya30afaf2009-09-22 13:42:12 +00007964 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00007965 break;
7966 }
cristy4582cbb2009-09-23 00:35:43 +00007967 if (LocaleCompare(keyword,"filename") == 0)
7968 {
7969 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7970 break;
7971 }
7972 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7973 break;
7974 }
7975 case 'G':
7976 case 'g':
7977 {
7978 if (LocaleCompare(keyword,"gravity") == 0)
7979 {
cristybb503372010-05-27 20:51:26 +00007980 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007981 gravity;
7982
cristy042ee782011-04-22 18:48:30 +00007983 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007984 if (gravity < 0)
7985 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7986 (void) SetImageOption(image_info,keyword,value);
7987 break;
7988 }
cristyb20775d2009-09-16 01:51:41 +00007989 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7990 break;
7991 }
7992 case 'I':
7993 case 'i':
7994 {
7995 if (LocaleCompare(keyword,"id") == 0)
7996 {
cristy4582cbb2009-09-23 00:35:43 +00007997 (void) SetImageProperty(attributes,keyword,value);
cristy2c8b6312009-09-16 02:37:23 +00007998 break;
7999 }
8000 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8001 break;
8002 }
8003 case 'M':
8004 case 'm':
8005 {
8006 if (LocaleCompare(keyword,"magick") == 0)
8007 {
8008 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
8009 break;
8010 }
cristy2c8b6312009-09-16 02:37:23 +00008011 if (LocaleCompare(keyword,"mattecolor") == 0)
8012 {
8013 (void) QueryColorDatabase(value,&image_info->matte_color,
8014 exception);
cristyb20775d2009-09-16 01:51:41 +00008015 break;
8016 }
8017 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8018 break;
8019 }
8020 case 'P':
8021 case 'p':
8022 {
8023 if (LocaleCompare(keyword,"pointsize") == 0)
8024 {
cristyc1acd842011-05-19 23:05:47 +00008025 image_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8026 draw_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
cristyb20775d2009-09-16 01:51:41 +00008027 break;
8028 }
8029 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8030 break;
8031 }
cristy4582cbb2009-09-23 00:35:43 +00008032 case 'Q':
8033 case 'q':
8034 {
8035 if (LocaleCompare(keyword,"quality") == 0)
8036 {
cristyf2f27272009-12-17 14:48:46 +00008037 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008038 if (image == (Image *) NULL)
8039 break;
cristyf2f27272009-12-17 14:48:46 +00008040 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008041 break;
8042 }
8043 break;
8044 }
cristyb20775d2009-09-16 01:51:41 +00008045 case 'S':
8046 case 's':
8047 {
8048 if (LocaleCompare(keyword,"size") == 0)
8049 {
cristy2c8b6312009-09-16 02:37:23 +00008050 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008051 break;
8052 }
8053 if (LocaleCompare(keyword,"stroke") == 0)
8054 {
cristy2c8b6312009-09-16 02:37:23 +00008055 (void) QueryColorDatabase(value,&draw_info->stroke,exception);
cristya30afaf2009-09-22 13:42:12 +00008056 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008057 break;
8058 }
8059 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8060 break;
8061 }
8062 default:
8063 {
8064 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8065 break;
cristyb988fe72009-09-16 01:01:10 +00008066 }
8067 }
8068 return(MagickTrue);
8069}
cristy6b9f7ed2010-04-24 01:08:02 +00008070#endif
cristyb988fe72009-09-16 01:01:10 +00008071
8072/*
8073%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8074% %
8075% %
8076% %
cristy3ed852e2009-09-05 21:47:34 +00008077% U n r e g i s t e r M S L I m a g e %
8078% %
8079% %
8080% %
8081%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8082%
8083% UnregisterMSLImage() removes format registrations made by the
8084% MSL module from the list of supported formats.
8085%
8086% The format of the UnregisterMSLImage method is:
8087%
8088% UnregisterMSLImage(void)
8089%
8090*/
8091ModuleExport void UnregisterMSLImage(void)
8092{
8093 (void) UnregisterMagickInfo("MSL");
8094}
8095
8096#if defined(MAGICKCORE_XML_DELEGATE)
8097/*
8098%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8099% %
8100% %
8101% %
8102% W r i t e M S L I m a g e %
8103% %
8104% %
8105% %
8106%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8107%
8108% WriteMSLImage() writes an image to a file in MVG image format.
8109%
8110% The format of the WriteMSLImage method is:
8111%
8112% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8113%
8114% A description of each parameter follows.
8115%
8116% o image_info: the image info.
8117%
8118% o image: The image.
8119%
8120*/
8121static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8122{
8123 assert(image_info != (const ImageInfo *) NULL);
8124 assert(image_info->signature == MagickSignature);
8125 assert(image != (Image *) NULL);
8126 assert(image->signature == MagickSignature);
8127 if (image->debug != MagickFalse)
8128 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8129 (void) ReferenceImage(image);
8130 (void) ProcessMSLScript(image_info,&image,&image->exception);
8131 return(MagickTrue);
8132}
8133#endif