blob: 3a8fe622b5ed493010fe417b9296821c6c2b2893 [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);
cristy50fbc382011-07-07 02:19:17 +00003229 (void) GammaImage(msl_info->image[n],atof(gamma));
cristy3ed852e2009-09-05 21:47:34 +00003230 break;
3231 }
cristyb988fe72009-09-16 01:01:10 +00003232 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003233 {
3234 if (msl_info->image[n] == (Image *) NULL)
3235 {
cristyb988fe72009-09-16 01:01:10 +00003236 ThrowMSLException(OptionError,"NoImagesDefined",
3237 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003238 break;
3239 }
3240 if (attributes == (const xmlChar **) NULL)
3241 break;
3242 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3243 {
3244 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003245 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003246 (void) CopyMagickString(key,value,MaxTextExtent);
3247 switch (*keyword)
3248 {
3249 case 'H':
3250 case 'h':
3251 {
3252 if (LocaleCompare(keyword,"height") == 0)
3253 {
cristyb51dff52011-05-19 16:55:47 +00003254 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003255 (double) msl_info->image[n]->rows);
cristy3ed852e2009-09-05 21:47:34 +00003256 (void) SetImageProperty(msl_info->attributes[n],key,value);
3257 break;
3258 }
3259 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3260 }
3261 case 'W':
3262 case 'w':
3263 {
3264 if (LocaleCompare(keyword,"width") == 0)
3265 {
cristyb51dff52011-05-19 16:55:47 +00003266 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003267 (double) msl_info->image[n]->columns);
cristy3ed852e2009-09-05 21:47:34 +00003268 (void) SetImageProperty(msl_info->attributes[n],key,value);
3269 break;
3270 }
3271 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3272 }
3273 default:
3274 {
3275 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3276 break;
3277 }
3278 }
3279 }
3280 break;
3281 }
cristyb988fe72009-09-16 01:01:10 +00003282 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003283 {
3284 msl_info->number_groups++;
3285 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3286 msl_info->group_info,msl_info->number_groups+1UL,
3287 sizeof(*msl_info->group_info));
3288 break;
3289 }
3290 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3291 }
3292 case 'I':
3293 case 'i':
3294 {
cristyb988fe72009-09-16 01:01:10 +00003295 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003296 {
cristy3ed852e2009-09-05 21:47:34 +00003297 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003298 if (attributes == (const xmlChar **) NULL)
3299 break;
3300 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3301 {
3302 keyword=(const char *) attributes[i++];
3303 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003304 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00003305 switch (*keyword)
3306 {
cristyb988fe72009-09-16 01:01:10 +00003307 case 'C':
3308 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003309 {
cristyb988fe72009-09-16 01:01:10 +00003310 if (LocaleCompare(keyword,"color") == 0)
3311 {
3312 Image
3313 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003314
cristyb988fe72009-09-16 01:01:10 +00003315 (void) CopyMagickString(msl_info->image_info[n]->filename,
3316 "xc:",MaxTextExtent);
3317 (void) ConcatenateMagickString(msl_info->image_info[n]->
3318 filename,value,MaxTextExtent);
3319 next_image=ReadImage(msl_info->image_info[n],&exception);
3320 CatchException(&exception);
3321 if (next_image == (Image *) NULL)
3322 continue;
3323 if (msl_info->image[n] == (Image *) NULL)
3324 msl_info->image[n]=next_image;
3325 else
3326 {
3327 register Image
3328 *p;
cristy3ed852e2009-09-05 21:47:34 +00003329
cristyb988fe72009-09-16 01:01:10 +00003330 /*
3331 Link image into image list.
3332 */
3333 p=msl_info->image[n];
3334 while (p->next != (Image *) NULL)
3335 p=GetNextImageInList(p);
3336 next_image->previous=p;
3337 p->next=next_image;
3338 }
3339 break;
3340 }
cristyb20775d2009-09-16 01:51:41 +00003341 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003342 break;
3343 }
3344 default:
3345 {
cristyb20775d2009-09-16 01:51:41 +00003346 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003347 break;
3348 }
3349 }
3350 }
3351 break;
3352 }
cristyb988fe72009-09-16 01:01:10 +00003353 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003354 {
3355 Image
3356 *implode_image;
3357
3358 /*
3359 Implode image.
3360 */
3361 if (msl_info->image[n] == (Image *) NULL)
3362 {
cristyb988fe72009-09-16 01:01:10 +00003363 ThrowMSLException(OptionError,"NoImagesDefined",
3364 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003365 break;
3366 }
3367 if (attributes != (const xmlChar **) NULL)
3368 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3369 {
3370 keyword=(const char *) attributes[i++];
3371 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003372 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003373 CloneString(&value,attribute);
3374 switch (*keyword)
3375 {
3376 case 'A':
3377 case 'a':
3378 {
3379 if (LocaleCompare(keyword,"amount") == 0)
3380 {
cristyc1acd842011-05-19 23:05:47 +00003381 geometry_info.rho=InterpretLocaleValue(value,
3382 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003383 break;
3384 }
3385 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3386 keyword);
3387 break;
3388 }
3389 case 'G':
3390 case 'g':
3391 {
3392 if (LocaleCompare(keyword,"geometry") == 0)
3393 {
3394 flags=ParseGeometry(value,&geometry_info);
3395 if ((flags & SigmaValue) == 0)
3396 geometry_info.sigma=1.0;
3397 break;
3398 }
3399 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3400 keyword);
3401 break;
3402 }
3403 default:
3404 {
3405 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3406 keyword);
3407 break;
3408 }
3409 }
3410 }
3411 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3412 &msl_info->image[n]->exception);
3413 if (implode_image == (Image *) NULL)
3414 break;
3415 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3416 msl_info->image[n]=implode_image;
3417 break;
3418 }
3419 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3420 }
3421 case 'L':
3422 case 'l':
3423 {
cristyb988fe72009-09-16 01:01:10 +00003424 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003425 break;
cristyb988fe72009-09-16 01:01:10 +00003426 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003427 {
3428 double
3429 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3430
3431 if (msl_info->image[n] == (Image *) NULL)
3432 {
cristyb988fe72009-09-16 01:01:10 +00003433 ThrowMSLException(OptionError,"NoImagesDefined",
3434 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003435 break;
3436 }
3437 if (attributes == (const xmlChar **) NULL)
3438 break;
3439 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3440 {
3441 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003442 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003443 (void) CopyMagickString(key,value,MaxTextExtent);
3444 switch (*keyword)
3445 {
3446 case 'B':
3447 case 'b':
3448 {
3449 if (LocaleCompare(keyword,"black") == 0)
3450 {
cristyc1acd842011-05-19 23:05:47 +00003451 levelBlack = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003452 break;
3453 }
3454 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3455 break;
3456 }
3457 case 'G':
3458 case 'g':
3459 {
3460 if (LocaleCompare(keyword,"gamma") == 0)
3461 {
cristyc1acd842011-05-19 23:05:47 +00003462 levelGamma = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003463 break;
3464 }
3465 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3466 break;
3467 }
3468 case 'W':
3469 case 'w':
3470 {
3471 if (LocaleCompare(keyword,"white") == 0)
3472 {
cristyc1acd842011-05-19 23:05:47 +00003473 levelWhite = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003474 break;
3475 }
3476 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3477 break;
3478 }
3479 default:
3480 {
3481 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3482 break;
3483 }
3484 }
3485 }
3486
3487 /* process image */
cristyf89cb1d2011-07-07 01:24:37 +00003488 LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma);
3489 break;
cristy3ed852e2009-09-05 21:47:34 +00003490 }
3491 }
3492 case 'M':
3493 case 'm':
3494 {
cristyb988fe72009-09-16 01:01:10 +00003495 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003496 {
3497 Image
3498 *magnify_image;
3499
3500 /*
3501 Magnify image.
3502 */
3503 if (msl_info->image[n] == (Image *) NULL)
3504 {
cristyb988fe72009-09-16 01:01:10 +00003505 ThrowMSLException(OptionError,"NoImagesDefined",
3506 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003507 break;
3508 }
3509 if (attributes != (const xmlChar **) NULL)
3510 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3511 {
3512 keyword=(const char *) attributes[i++];
3513 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003514 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003515 CloneString(&value,attribute);
3516 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3517 }
3518 magnify_image=MagnifyImage(msl_info->image[n],
3519 &msl_info->image[n]->exception);
3520 if (magnify_image == (Image *) NULL)
3521 break;
3522 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3523 msl_info->image[n]=magnify_image;
3524 break;
3525 }
cristyb988fe72009-09-16 01:01:10 +00003526 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003527 {
3528 Image
3529 *affinity_image;
3530
3531 MagickBooleanType
3532 dither;
3533
3534 QuantizeInfo
3535 *quantize_info;
3536
3537 /*
3538 Map image.
3539 */
3540 if (msl_info->image[n] == (Image *) NULL)
3541 {
cristyb988fe72009-09-16 01:01:10 +00003542 ThrowMSLException(OptionError,"NoImagesDefined",
3543 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003544 break;
3545 }
3546 affinity_image=NewImageList();
3547 dither=MagickFalse;
3548 if (attributes != (const xmlChar **) NULL)
3549 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3550 {
3551 keyword=(const char *) attributes[i++];
3552 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003553 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003554 CloneString(&value,attribute);
3555 switch (*keyword)
3556 {
3557 case 'D':
3558 case 'd':
3559 {
3560 if (LocaleCompare(keyword,"dither") == 0)
3561 {
cristy042ee782011-04-22 18:48:30 +00003562 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003563 value);
3564 if (option < 0)
3565 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3566 value);
3567 dither=(MagickBooleanType) option;
3568 break;
3569 }
3570 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3571 keyword);
3572 break;
3573 }
3574 case 'I':
3575 case 'i':
3576 {
3577 if (LocaleCompare(keyword,"image") == 0)
3578 for (j=0; j < msl_info->n; j++)
3579 {
3580 const char
3581 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003582
cristy3ed852e2009-09-05 21:47:34 +00003583 attribute=GetImageProperty(msl_info->attributes[j],"id");
3584 if ((attribute != (const char *) NULL) &&
3585 (LocaleCompare(attribute,value) == 0))
3586 {
3587 affinity_image=CloneImage(msl_info->image[j],0,0,
3588 MagickFalse,&exception);
3589 break;
3590 }
3591 }
3592 break;
3593 }
3594 default:
3595 {
3596 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3597 keyword);
3598 break;
3599 }
3600 }
3601 }
3602 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3603 quantize_info->dither=dither;
3604 (void) RemapImages(quantize_info,msl_info->image[n],
3605 affinity_image);
3606 quantize_info=DestroyQuantizeInfo(quantize_info);
3607 affinity_image=DestroyImage(affinity_image);
3608 break;
3609 }
cristyb988fe72009-09-16 01:01:10 +00003610 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003611 {
3612 double
3613 opacity;
3614
cristy4c08aed2011-07-01 19:47:50 +00003615 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003616 target;
3617
3618 PaintMethod
3619 paint_method;
3620
3621 /*
3622 Matte floodfill image.
3623 */
3624 opacity=0.0;
3625 if (msl_info->image[n] == (Image *) NULL)
3626 {
cristyb988fe72009-09-16 01:01:10 +00003627 ThrowMSLException(OptionError,"NoImagesDefined",
3628 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003629 break;
3630 }
3631 SetGeometry(msl_info->image[n],&geometry);
3632 paint_method=FloodfillMethod;
3633 if (attributes != (const xmlChar **) NULL)
3634 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3635 {
3636 keyword=(const char *) attributes[i++];
3637 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003638 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003639 CloneString(&value,attribute);
3640 switch (*keyword)
3641 {
3642 case 'B':
3643 case 'b':
3644 {
3645 if (LocaleCompare(keyword,"bordercolor") == 0)
3646 {
3647 (void) QueryMagickColor(value,&target,&exception);
3648 paint_method=FillToBorderMethod;
3649 break;
3650 }
3651 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3652 keyword);
3653 break;
3654 }
3655 case 'F':
3656 case 'f':
3657 {
3658 if (LocaleCompare(keyword,"fuzz") == 0)
3659 {
cristyc1acd842011-05-19 23:05:47 +00003660 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
3661 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003662 break;
3663 }
3664 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3665 keyword);
3666 break;
3667 }
3668 case 'G':
3669 case 'g':
3670 {
3671 if (LocaleCompare(keyword,"geometry") == 0)
3672 {
3673 flags=ParsePageGeometry(msl_info->image[n],value,
3674 &geometry,&exception);
3675 if ((flags & HeightValue) == 0)
3676 geometry.height=geometry.width;
3677 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3678 geometry.x,geometry.y,&target,&exception);
3679 break;
3680 }
3681 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3682 keyword);
3683 break;
3684 }
3685 case 'O':
3686 case 'o':
3687 {
3688 if (LocaleCompare(keyword,"opacity") == 0)
3689 {
cristyc1acd842011-05-19 23:05:47 +00003690 opacity=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003691 break;
3692 }
3693 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3694 keyword);
3695 break;
3696 }
3697 case 'X':
3698 case 'x':
3699 {
3700 if (LocaleCompare(keyword,"x") == 0)
3701 {
cristyf2f27272009-12-17 14:48:46 +00003702 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003703 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3704 geometry.x,geometry.y,&target,&exception);
3705 break;
3706 }
3707 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3708 keyword);
3709 break;
3710 }
3711 case 'Y':
3712 case 'y':
3713 {
3714 if (LocaleCompare(keyword,"y") == 0)
3715 {
cristyf2f27272009-12-17 14:48:46 +00003716 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003717 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3718 geometry.x,geometry.y,&target,&exception);
3719 break;
3720 }
3721 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3722 keyword);
3723 break;
3724 }
3725 default:
3726 {
3727 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3728 keyword);
3729 break;
3730 }
3731 }
3732 }
3733 draw_info=CloneDrawInfo(msl_info->image_info[n],
3734 msl_info->draw_info[n]);
cristy4c08aed2011-07-01 19:47:50 +00003735 draw_info->fill.alpha=ClampToQuantum(opacity);
cristy3ed852e2009-09-05 21:47:34 +00003736 (void) FloodfillPaintImage(msl_info->image[n],OpacityChannel,
3737 draw_info,&target,geometry.x,geometry.y,
3738 paint_method == FloodfillMethod ? MagickFalse : MagickTrue);
3739 draw_info=DestroyDrawInfo(draw_info);
3740 break;
3741 }
cristyb988fe72009-09-16 01:01:10 +00003742 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003743 {
3744 Image
3745 *median_image;
3746
3747 /*
3748 Median-filter image.
3749 */
3750 if (msl_info->image[n] == (Image *) NULL)
3751 {
cristyb988fe72009-09-16 01:01:10 +00003752 ThrowMSLException(OptionError,"NoImagesDefined",
3753 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003754 break;
3755 }
3756 if (attributes != (const xmlChar **) NULL)
3757 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3758 {
3759 keyword=(const char *) attributes[i++];
3760 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003761 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003762 CloneString(&value,attribute);
3763 switch (*keyword)
3764 {
3765 case 'G':
3766 case 'g':
3767 {
3768 if (LocaleCompare(keyword,"geometry") == 0)
3769 {
3770 flags=ParseGeometry(value,&geometry_info);
3771 if ((flags & SigmaValue) == 0)
3772 geometry_info.sigma=1.0;
3773 break;
3774 }
3775 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3776 keyword);
3777 break;
3778 }
3779 case 'R':
3780 case 'r':
3781 {
3782 if (LocaleCompare(keyword,"radius") == 0)
3783 {
cristyc1acd842011-05-19 23:05:47 +00003784 geometry_info.rho=InterpretLocaleValue(value,
3785 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003786 break;
3787 }
3788 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3789 keyword);
3790 break;
3791 }
3792 default:
3793 {
3794 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3795 keyword);
3796 break;
3797 }
3798 }
3799 }
cristy733678d2011-03-18 21:29:28 +00003800 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003801 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3802 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003803 if (median_image == (Image *) NULL)
3804 break;
3805 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3806 msl_info->image[n]=median_image;
3807 break;
3808 }
cristyb988fe72009-09-16 01:01:10 +00003809 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003810 {
3811 Image
3812 *minify_image;
3813
3814 /*
3815 Minify image.
3816 */
3817 if (msl_info->image[n] == (Image *) NULL)
3818 {
cristyb988fe72009-09-16 01:01:10 +00003819 ThrowMSLException(OptionError,"NoImagesDefined",
3820 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003821 break;
3822 }
3823 if (attributes != (const xmlChar **) NULL)
3824 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3825 {
3826 keyword=(const char *) attributes[i++];
3827 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003828 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003829 CloneString(&value,attribute);
3830 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3831 }
3832 minify_image=MinifyImage(msl_info->image[n],
3833 &msl_info->image[n]->exception);
3834 if (minify_image == (Image *) NULL)
3835 break;
3836 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3837 msl_info->image[n]=minify_image;
3838 break;
3839 }
cristyb988fe72009-09-16 01:01:10 +00003840 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003841 break;
cristyb988fe72009-09-16 01:01:10 +00003842 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003843 {
3844 char
3845 modulate[MaxTextExtent];
3846
3847 /*
3848 Modulate image.
3849 */
3850 if (msl_info->image[n] == (Image *) NULL)
3851 {
cristyb988fe72009-09-16 01:01:10 +00003852 ThrowMSLException(OptionError,"NoImagesDefined",
3853 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003854 break;
3855 }
3856 geometry_info.rho=100.0;
3857 geometry_info.sigma=100.0;
3858 geometry_info.xi=100.0;
3859 if (attributes != (const xmlChar **) NULL)
3860 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3861 {
3862 keyword=(const char *) attributes[i++];
3863 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003864 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003865 CloneString(&value,attribute);
3866 switch (*keyword)
3867 {
3868 case 'B':
3869 case 'b':
3870 {
3871 if (LocaleCompare(keyword,"blackness") == 0)
3872 {
cristyc1acd842011-05-19 23:05:47 +00003873 geometry_info.rho=InterpretLocaleValue(value,
3874 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003875 break;
3876 }
3877 if (LocaleCompare(keyword,"brightness") == 0)
3878 {
cristyc1acd842011-05-19 23:05:47 +00003879 geometry_info.rho=InterpretLocaleValue(value,
3880 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003881 break;
3882 }
3883 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3884 keyword);
3885 break;
3886 }
3887 case 'F':
3888 case 'f':
3889 {
3890 if (LocaleCompare(keyword,"factor") == 0)
3891 {
3892 flags=ParseGeometry(value,&geometry_info);
3893 break;
3894 }
3895 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3896 keyword);
3897 break;
3898 }
3899 case 'H':
3900 case 'h':
3901 {
3902 if (LocaleCompare(keyword,"hue") == 0)
3903 {
cristyc1acd842011-05-19 23:05:47 +00003904 geometry_info.xi=InterpretLocaleValue(value,
3905 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003906 break;
3907 }
3908 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3909 keyword);
3910 break;
3911 }
3912 case 'L':
3913 case 'l':
3914 {
3915 if (LocaleCompare(keyword,"lightness") == 0)
3916 {
cristyc1acd842011-05-19 23:05:47 +00003917 geometry_info.rho=InterpretLocaleValue(value,
3918 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003919 break;
3920 }
3921 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3922 keyword);
3923 break;
3924 }
3925 case 'S':
3926 case 's':
3927 {
3928 if (LocaleCompare(keyword,"saturation") == 0)
3929 {
cristyc1acd842011-05-19 23:05:47 +00003930 geometry_info.sigma=InterpretLocaleValue(value,
3931 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003932 break;
3933 }
3934 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3935 keyword);
3936 break;
3937 }
3938 case 'W':
3939 case 'w':
3940 {
3941 if (LocaleCompare(keyword,"whiteness") == 0)
3942 {
cristyc1acd842011-05-19 23:05:47 +00003943 geometry_info.sigma=InterpretLocaleValue(value,
3944 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003945 break;
3946 }
3947 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3948 keyword);
3949 break;
3950 }
3951 default:
3952 {
3953 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3954 keyword);
3955 break;
3956 }
3957 }
3958 }
cristyb51dff52011-05-19 16:55:47 +00003959 (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003960 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
3961 (void) ModulateImage(msl_info->image[n],modulate);
3962 break;
3963 }
3964 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3965 }
3966 case 'N':
3967 case 'n':
3968 {
cristyb988fe72009-09-16 01:01:10 +00003969 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003970 {
3971 MagickBooleanType
3972 gray;
3973
3974 /*
3975 Negate image.
3976 */
3977 if (msl_info->image[n] == (Image *) NULL)
3978 {
cristyb988fe72009-09-16 01:01:10 +00003979 ThrowMSLException(OptionError,"NoImagesDefined",
3980 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003981 break;
3982 }
3983 gray=MagickFalse;
3984 if (attributes != (const xmlChar **) NULL)
3985 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3986 {
3987 keyword=(const char *) attributes[i++];
3988 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003989 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003990 CloneString(&value,attribute);
3991 switch (*keyword)
3992 {
3993 case 'C':
3994 case 'c':
3995 {
3996 if (LocaleCompare(keyword,"channel") == 0)
3997 {
3998 option=ParseChannelOption(value);
3999 if (option < 0)
4000 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4001 value);
4002 channel=(ChannelType) option;
4003 break;
4004 }
4005 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4006 keyword);
4007 break;
4008 }
4009 case 'G':
4010 case 'g':
4011 {
4012 if (LocaleCompare(keyword,"gray") == 0)
4013 {
cristy042ee782011-04-22 18:48:30 +00004014 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004015 value);
4016 if (option < 0)
4017 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4018 value);
4019 gray=(MagickBooleanType) option;
4020 break;
4021 }
4022 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4023 keyword);
4024 break;
4025 }
4026 default:
4027 {
4028 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4029 keyword);
4030 break;
4031 }
4032 }
4033 }
cristy50fbc382011-07-07 02:19:17 +00004034 SetPixelComponentMap(msl_info->image[n],channel);
4035 (void) NegateImage(msl_info->image[n],gray);
cristy3ed852e2009-09-05 21:47:34 +00004036 break;
4037 }
cristyb988fe72009-09-16 01:01:10 +00004038 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004039 {
4040 /*
4041 Normalize image.
4042 */
4043 if (msl_info->image[n] == (Image *) NULL)
4044 {
cristyb988fe72009-09-16 01:01:10 +00004045 ThrowMSLException(OptionError,"NoImagesDefined",
4046 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004047 break;
4048 }
4049 if (attributes != (const xmlChar **) NULL)
4050 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4051 {
4052 keyword=(const char *) attributes[i++];
4053 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004054 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004055 CloneString(&value,attribute);
4056 switch (*keyword)
4057 {
4058 case 'C':
4059 case 'c':
4060 {
4061 if (LocaleCompare(keyword,"channel") == 0)
4062 {
4063 option=ParseChannelOption(value);
4064 if (option < 0)
4065 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4066 value);
4067 channel=(ChannelType) option;
4068 break;
4069 }
4070 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4071 keyword);
4072 break;
4073 }
4074 default:
4075 {
4076 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4077 keyword);
4078 break;
4079 }
4080 }
4081 }
cristy50fbc382011-07-07 02:19:17 +00004082 (void) NormalizeImage(msl_info->image[n]);
cristy3ed852e2009-09-05 21:47:34 +00004083 break;
4084 }
4085 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4086 }
4087 case 'O':
4088 case 'o':
4089 {
cristyb988fe72009-09-16 01:01:10 +00004090 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004091 {
4092 Image
4093 *paint_image;
4094
4095 /*
4096 Oil-paint image.
4097 */
4098 if (msl_info->image[n] == (Image *) NULL)
4099 {
cristyb988fe72009-09-16 01:01:10 +00004100 ThrowMSLException(OptionError,"NoImagesDefined",
4101 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004102 break;
4103 }
4104 if (attributes != (const xmlChar **) NULL)
4105 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4106 {
4107 keyword=(const char *) attributes[i++];
4108 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004109 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004110 CloneString(&value,attribute);
4111 switch (*keyword)
4112 {
4113 case 'G':
4114 case 'g':
4115 {
4116 if (LocaleCompare(keyword,"geometry") == 0)
4117 {
4118 flags=ParseGeometry(value,&geometry_info);
4119 if ((flags & SigmaValue) == 0)
4120 geometry_info.sigma=1.0;
4121 break;
4122 }
4123 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4124 keyword);
4125 break;
4126 }
4127 case 'R':
4128 case 'r':
4129 {
4130 if (LocaleCompare(keyword,"radius") == 0)
4131 {
cristyc1acd842011-05-19 23:05:47 +00004132 geometry_info.rho=InterpretLocaleValue(value,
4133 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004134 break;
4135 }
4136 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4137 keyword);
4138 break;
4139 }
4140 default:
4141 {
4142 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4143 keyword);
4144 break;
4145 }
4146 }
4147 }
4148 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4149 &msl_info->image[n]->exception);
4150 if (paint_image == (Image *) NULL)
4151 break;
4152 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4153 msl_info->image[n]=paint_image;
4154 break;
4155 }
cristyb988fe72009-09-16 01:01:10 +00004156 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004157 {
cristy4c08aed2011-07-01 19:47:50 +00004158 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004159 fill_color,
4160 target;
4161
4162 /*
4163 Opaque image.
4164 */
4165 if (msl_info->image[n] == (Image *) NULL)
4166 {
cristyb988fe72009-09-16 01:01:10 +00004167 ThrowMSLException(OptionError,"NoImagesDefined",
4168 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004169 break;
4170 }
4171 (void) QueryMagickColor("none",&target,&exception);
4172 (void) QueryMagickColor("none",&fill_color,&exception);
4173 if (attributes != (const xmlChar **) NULL)
4174 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4175 {
4176 keyword=(const char *) attributes[i++];
4177 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004178 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004179 CloneString(&value,attribute);
4180 switch (*keyword)
4181 {
4182 case 'C':
4183 case 'c':
4184 {
4185 if (LocaleCompare(keyword,"channel") == 0)
4186 {
4187 option=ParseChannelOption(value);
4188 if (option < 0)
4189 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4190 value);
4191 channel=(ChannelType) option;
4192 break;
4193 }
4194 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4195 keyword);
4196 break;
4197 }
4198 case 'F':
4199 case 'f':
4200 {
4201 if (LocaleCompare(keyword,"fill") == 0)
4202 {
4203 (void) QueryMagickColor(value,&fill_color,&exception);
4204 break;
4205 }
4206 if (LocaleCompare(keyword,"fuzz") == 0)
4207 {
cristyc1acd842011-05-19 23:05:47 +00004208 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
4209 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004210 break;
4211 }
4212 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4213 keyword);
4214 break;
4215 }
4216 default:
4217 {
4218 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4219 keyword);
4220 break;
4221 }
4222 }
4223 }
4224 (void) OpaquePaintImageChannel(msl_info->image[n],channel,
4225 &target,&fill_color,MagickFalse);
4226 break;
4227 }
4228 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4229 }
4230 case 'P':
4231 case 'p':
4232 {
cristyb988fe72009-09-16 01:01:10 +00004233 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004234 {
4235 if (attributes == (const xmlChar **) NULL)
4236 break;
4237 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4238 {
4239 keyword=(const char *) attributes[i++];
4240 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004241 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004242 CloneString(&value,attribute);
4243 switch (*keyword)
4244 {
4245 case 'O':
4246 case 'o':
4247 {
4248 if (LocaleCompare(keyword,"output") == 0)
4249 {
cristyb51dff52011-05-19 16:55:47 +00004250 (void) FormatLocaleFile(stdout,"%s",value);
cristy3ed852e2009-09-05 21:47:34 +00004251 break;
4252 }
4253 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4254 break;
4255 }
4256 default:
4257 {
4258 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4259 break;
4260 }
4261 }
4262 }
4263 break;
4264 }
cristy4fa36e42009-09-18 14:24:06 +00004265 if (LocaleCompare((const char *) tag, "profile") == 0)
4266 {
cristy4fa36e42009-09-18 14:24:06 +00004267 if (msl_info->image[n] == (Image *) NULL)
4268 {
4269 ThrowMSLException(OptionError,"NoImagesDefined",
4270 (const char *) tag);
4271 break;
4272 }
4273 if (attributes == (const xmlChar **) NULL)
4274 break;
4275 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4276 {
4277 const char
4278 *name;
4279
4280 const StringInfo
4281 *profile;
4282
4283 Image
4284 *profile_image;
4285
4286 ImageInfo
4287 *profile_info;
4288
4289 keyword=(const char *) attributes[i++];
4290 attribute=InterpretImageProperties(msl_info->image_info[n],
4291 msl_info->attributes[n],(const char *) attributes[i]);
4292 CloneString(&value,attribute);
4293 if (*keyword == '+')
4294 {
4295 /*
4296 Remove a profile from the image.
4297 */
4298 (void) ProfileImage(msl_info->image[n],keyword,
4299 (const unsigned char *) NULL,0,MagickTrue);
4300 continue;
4301 }
4302 /*
4303 Associate a profile with the image.
4304 */
4305 profile_info=CloneImageInfo(msl_info->image_info[n]);
4306 profile=GetImageProfile(msl_info->image[n],"iptc");
4307 if (profile != (StringInfo *) NULL)
4308 profile_info->profile=(void *) CloneStringInfo(profile);
4309 profile_image=GetImageCache(profile_info,keyword,&exception);
4310 profile_info=DestroyImageInfo(profile_info);
4311 if (profile_image == (Image *) NULL)
4312 {
4313 char
4314 name[MaxTextExtent],
4315 filename[MaxTextExtent];
4316
4317 register char
4318 *p;
4319
4320 StringInfo
4321 *profile;
4322
4323 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4324 (void) CopyMagickString(name,keyword,MaxTextExtent);
4325 for (p=filename; *p != '\0'; p++)
4326 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4327 (IsPathAccessible(keyword) == MagickFalse))
4328 {
4329 register char
4330 *q;
4331
4332 /*
4333 Look for profile name (e.g. name:profile).
4334 */
4335 (void) CopyMagickString(name,filename,(size_t)
4336 (p-filename+1));
4337 for (q=filename; *q != '\0'; q++)
4338 *q=(*++p);
4339 break;
4340 }
4341 profile=FileToStringInfo(filename,~0UL,&exception);
4342 if (profile != (StringInfo *) NULL)
4343 {
4344 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004345 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004346 GetStringInfoLength(profile),MagickFalse);
4347 profile=DestroyStringInfo(profile);
4348 }
4349 continue;
4350 }
4351 ResetImageProfileIterator(profile_image);
4352 name=GetNextImageProfile(profile_image);
4353 while (name != (const char *) NULL)
4354 {
4355 profile=GetImageProfile(profile_image,name);
4356 if (profile != (StringInfo *) NULL)
4357 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004358 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004359 GetStringInfoLength(profile),MagickFalse);
4360 name=GetNextImageProfile(profile_image);
4361 }
4362 profile_image=DestroyImage(profile_image);
4363 }
4364 break;
4365 }
cristy3ed852e2009-09-05 21:47:34 +00004366 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4367 }
4368 case 'Q':
4369 case 'q':
4370 {
cristyb988fe72009-09-16 01:01:10 +00004371 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004372 {
4373 QuantizeInfo
4374 quantize_info;
4375
4376 /*
4377 Quantize image.
4378 */
4379 if (msl_info->image[n] == (Image *) NULL)
4380 {
cristyb988fe72009-09-16 01:01:10 +00004381 ThrowMSLException(OptionError,"NoImagesDefined",
4382 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004383 break;
4384 }
4385 GetQuantizeInfo(&quantize_info);
4386 if (attributes != (const xmlChar **) NULL)
4387 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4388 {
4389 keyword=(const char *) attributes[i++];
4390 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004391 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004392 CloneString(&value,attribute);
4393 switch (*keyword)
4394 {
4395 case 'C':
4396 case 'c':
4397 {
4398 if (LocaleCompare(keyword,"colors") == 0)
4399 {
cristyf2f27272009-12-17 14:48:46 +00004400 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004401 break;
4402 }
4403 if (LocaleCompare(keyword,"colorspace") == 0)
4404 {
cristy042ee782011-04-22 18:48:30 +00004405 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004406 MagickFalse,value);
4407 if (option < 0)
4408 ThrowMSLException(OptionError,
4409 "UnrecognizedColorspaceType",value);
4410 quantize_info.colorspace=(ColorspaceType) option;
4411 break;
4412 }
4413 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4414 keyword);
4415 break;
4416 }
4417 case 'D':
4418 case 'd':
4419 {
4420 if (LocaleCompare(keyword,"dither") == 0)
4421 {
cristy042ee782011-04-22 18:48:30 +00004422 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004423 value);
4424 if (option < 0)
4425 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4426 value);
4427 quantize_info.dither=(MagickBooleanType) option;
4428 break;
4429 }
4430 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4431 keyword);
4432 break;
4433 }
4434 case 'M':
4435 case 'm':
4436 {
4437 if (LocaleCompare(keyword,"measure") == 0)
4438 {
cristy042ee782011-04-22 18:48:30 +00004439 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004440 value);
4441 if (option < 0)
4442 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4443 value);
4444 quantize_info.measure_error=(MagickBooleanType) option;
4445 break;
4446 }
4447 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4448 keyword);
4449 break;
4450 }
4451 case 'T':
4452 case 't':
4453 {
4454 if (LocaleCompare(keyword,"treedepth") == 0)
4455 {
cristyf2f27272009-12-17 14:48:46 +00004456 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004457 break;
4458 }
4459 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4460 keyword);
4461 break;
4462 }
4463 default:
4464 {
4465 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4466 keyword);
4467 break;
4468 }
4469 }
4470 }
4471 (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4472 break;
4473 }
cristyb988fe72009-09-16 01:01:10 +00004474 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004475 {
4476 char
4477 text[MaxTextExtent];
4478
4479 MagickBooleanType
4480 status;
4481
4482 TypeMetric
4483 metrics;
4484
4485 /*
4486 Query font metrics.
4487 */
4488 draw_info=CloneDrawInfo(msl_info->image_info[n],
4489 msl_info->draw_info[n]);
4490 angle=0.0;
4491 current=draw_info->affine;
4492 GetAffineMatrix(&affine);
4493 if (attributes != (const xmlChar **) NULL)
4494 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4495 {
4496 keyword=(const char *) attributes[i++];
4497 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004498 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004499 CloneString(&value,attribute);
4500 switch (*keyword)
4501 {
4502 case 'A':
4503 case 'a':
4504 {
4505 if (LocaleCompare(keyword,"affine") == 0)
4506 {
4507 char
4508 *p;
4509
4510 p=value;
cristyc1acd842011-05-19 23:05:47 +00004511 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004512 if (*p ==',')
4513 p++;
cristyc1acd842011-05-19 23:05:47 +00004514 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004515 if (*p ==',')
4516 p++;
cristyc1acd842011-05-19 23:05:47 +00004517 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004518 if (*p ==',')
4519 p++;
cristyc1acd842011-05-19 23:05:47 +00004520 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004521 if (*p ==',')
4522 p++;
cristyc1acd842011-05-19 23:05:47 +00004523 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004524 if (*p ==',')
4525 p++;
cristyc1acd842011-05-19 23:05:47 +00004526 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004527 break;
4528 }
4529 if (LocaleCompare(keyword,"align") == 0)
4530 {
cristy042ee782011-04-22 18:48:30 +00004531 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004532 value);
4533 if (option < 0)
4534 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4535 value);
4536 draw_info->align=(AlignType) option;
4537 break;
4538 }
4539 if (LocaleCompare(keyword,"antialias") == 0)
4540 {
cristy042ee782011-04-22 18:48:30 +00004541 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004542 value);
4543 if (option < 0)
4544 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4545 value);
4546 draw_info->stroke_antialias=(MagickBooleanType) option;
4547 draw_info->text_antialias=(MagickBooleanType) option;
4548 break;
4549 }
4550 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4551 keyword);
4552 break;
4553 }
4554 case 'D':
4555 case 'd':
4556 {
4557 if (LocaleCompare(keyword,"density") == 0)
4558 {
4559 CloneString(&draw_info->density,value);
4560 break;
4561 }
4562 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4563 keyword);
4564 break;
4565 }
4566 case 'E':
4567 case 'e':
4568 {
4569 if (LocaleCompare(keyword,"encoding") == 0)
4570 {
4571 CloneString(&draw_info->encoding,value);
4572 break;
4573 }
4574 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4575 keyword);
4576 break;
4577 }
4578 case 'F':
4579 case 'f':
4580 {
4581 if (LocaleCompare(keyword, "fill") == 0)
4582 {
4583 (void) QueryColorDatabase(value,&draw_info->fill,
4584 &exception);
4585 break;
4586 }
4587 if (LocaleCompare(keyword,"family") == 0)
4588 {
4589 CloneString(&draw_info->family,value);
4590 break;
4591 }
4592 if (LocaleCompare(keyword,"font") == 0)
4593 {
4594 CloneString(&draw_info->font,value);
4595 break;
4596 }
4597 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4598 keyword);
4599 break;
4600 }
4601 case 'G':
4602 case 'g':
4603 {
4604 if (LocaleCompare(keyword,"geometry") == 0)
4605 {
4606 flags=ParsePageGeometry(msl_info->image[n],value,
4607 &geometry,&exception);
4608 if ((flags & HeightValue) == 0)
4609 geometry.height=geometry.width;
4610 break;
4611 }
4612 if (LocaleCompare(keyword,"gravity") == 0)
4613 {
cristy042ee782011-04-22 18:48:30 +00004614 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004615 value);
4616 if (option < 0)
4617 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4618 value);
4619 draw_info->gravity=(GravityType) option;
4620 break;
4621 }
4622 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4623 keyword);
4624 break;
4625 }
4626 case 'P':
4627 case 'p':
4628 {
4629 if (LocaleCompare(keyword,"pointsize") == 0)
4630 {
cristyc1acd842011-05-19 23:05:47 +00004631 draw_info->pointsize=InterpretLocaleValue(value,
4632 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004633 break;
4634 }
4635 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4636 keyword);
4637 break;
4638 }
4639 case 'R':
4640 case 'r':
4641 {
4642 if (LocaleCompare(keyword,"rotate") == 0)
4643 {
cristyc1acd842011-05-19 23:05:47 +00004644 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004645 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4646 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4647 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4648 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4649 break;
4650 }
4651 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4652 keyword);
4653 break;
4654 }
4655 case 'S':
4656 case 's':
4657 {
4658 if (LocaleCompare(keyword,"scale") == 0)
4659 {
4660 flags=ParseGeometry(value,&geometry_info);
4661 if ((flags & SigmaValue) == 0)
4662 geometry_info.sigma=1.0;
4663 affine.sx=geometry_info.rho;
4664 affine.sy=geometry_info.sigma;
4665 break;
4666 }
4667 if (LocaleCompare(keyword,"skewX") == 0)
4668 {
cristyc1acd842011-05-19 23:05:47 +00004669 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004670 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4671 break;
4672 }
4673 if (LocaleCompare(keyword,"skewY") == 0)
4674 {
cristyc1acd842011-05-19 23:05:47 +00004675 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004676 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4677 break;
4678 }
4679 if (LocaleCompare(keyword,"stretch") == 0)
4680 {
cristy042ee782011-04-22 18:48:30 +00004681 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004682 value);
4683 if (option < 0)
4684 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4685 value);
4686 draw_info->stretch=(StretchType) option;
4687 break;
4688 }
4689 if (LocaleCompare(keyword, "stroke") == 0)
4690 {
4691 (void) QueryColorDatabase(value,&draw_info->stroke,
4692 &exception);
4693 break;
4694 }
4695 if (LocaleCompare(keyword,"strokewidth") == 0)
4696 {
cristyf2f27272009-12-17 14:48:46 +00004697 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004698 break;
4699 }
4700 if (LocaleCompare(keyword,"style") == 0)
4701 {
cristy042ee782011-04-22 18:48:30 +00004702 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004703 value);
4704 if (option < 0)
4705 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4706 value);
4707 draw_info->style=(StyleType) option;
4708 break;
4709 }
4710 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4711 keyword);
4712 break;
4713 }
4714 case 'T':
4715 case 't':
4716 {
4717 if (LocaleCompare(keyword,"text") == 0)
4718 {
4719 CloneString(&draw_info->text,value);
4720 break;
4721 }
4722 if (LocaleCompare(keyword,"translate") == 0)
4723 {
4724 flags=ParseGeometry(value,&geometry_info);
4725 if ((flags & SigmaValue) == 0)
4726 geometry_info.sigma=1.0;
4727 affine.tx=geometry_info.rho;
4728 affine.ty=geometry_info.sigma;
4729 break;
4730 }
4731 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4732 keyword);
4733 break;
4734 }
4735 case 'U':
4736 case 'u':
4737 {
4738 if (LocaleCompare(keyword, "undercolor") == 0)
4739 {
4740 (void) QueryColorDatabase(value,&draw_info->undercolor,
4741 &exception);
4742 break;
4743 }
4744 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4745 keyword);
4746 break;
4747 }
4748 case 'W':
4749 case 'w':
4750 {
4751 if (LocaleCompare(keyword,"weight") == 0)
4752 {
cristyf2f27272009-12-17 14:48:46 +00004753 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004754 break;
4755 }
4756 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4757 keyword);
4758 break;
4759 }
4760 case 'X':
4761 case 'x':
4762 {
4763 if (LocaleCompare(keyword,"x") == 0)
4764 {
cristyf2f27272009-12-17 14:48:46 +00004765 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004766 break;
4767 }
4768 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4769 keyword);
4770 break;
4771 }
4772 case 'Y':
4773 case 'y':
4774 {
4775 if (LocaleCompare(keyword,"y") == 0)
4776 {
cristyf2f27272009-12-17 14:48:46 +00004777 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004778 break;
4779 }
4780 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4781 keyword);
4782 break;
4783 }
4784 default:
4785 {
4786 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4787 keyword);
4788 break;
4789 }
4790 }
4791 }
cristyb51dff52011-05-19 16:55:47 +00004792 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00004793 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4794 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004795 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004796 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4797 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4798 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4799 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4800 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4801 affine.tx;
4802 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4803 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00004804 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4805 if (status != MagickFalse)
4806 {
4807 Image
4808 *image;
4809
4810 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004811 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004812 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004813 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004814 "%g",metrics.pixels_per_em.y);
4815 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004816 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004817 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004818 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004819 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004820 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004821 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004822 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004823 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004824 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004825 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004826 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004827 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004828 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004829 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004830 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004831 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004832 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004833 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004834 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004835 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004836 metrics.origin.y);
4837 }
4838 draw_info=DestroyDrawInfo(draw_info);
4839 break;
4840 }
4841 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4842 }
4843 case 'R':
4844 case 'r':
4845 {
cristyb988fe72009-09-16 01:01:10 +00004846 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004847 {
4848 MagickBooleanType
4849 raise;
4850
4851 /*
4852 Raise image.
4853 */
4854 if (msl_info->image[n] == (Image *) NULL)
4855 {
cristyb988fe72009-09-16 01:01:10 +00004856 ThrowMSLException(OptionError,"NoImagesDefined",
4857 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004858 break;
4859 }
4860 raise=MagickFalse;
4861 SetGeometry(msl_info->image[n],&geometry);
4862 if (attributes != (const xmlChar **) NULL)
4863 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4864 {
4865 keyword=(const char *) attributes[i++];
4866 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004867 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004868 CloneString(&value,attribute);
4869 switch (*keyword)
4870 {
4871 case 'G':
4872 case 'g':
4873 {
4874 if (LocaleCompare(keyword,"geometry") == 0)
4875 {
4876 flags=ParsePageGeometry(msl_info->image[n],value,
4877 &geometry,&exception);
4878 if ((flags & HeightValue) == 0)
4879 geometry.height=geometry.width;
4880 break;
4881 }
4882 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4883 keyword);
4884 break;
4885 }
4886 case 'H':
4887 case 'h':
4888 {
4889 if (LocaleCompare(keyword,"height") == 0)
4890 {
cristyf2f27272009-12-17 14:48:46 +00004891 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004892 break;
4893 }
4894 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4895 keyword);
4896 break;
4897 }
4898 case 'R':
4899 case 'r':
4900 {
4901 if (LocaleCompare(keyword,"raise") == 0)
4902 {
cristy042ee782011-04-22 18:48:30 +00004903 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004904 value);
4905 if (option < 0)
4906 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4907 value);
4908 raise=(MagickBooleanType) option;
4909 break;
4910 }
4911 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4912 keyword);
4913 break;
4914 }
4915 case 'W':
4916 case 'w':
4917 {
4918 if (LocaleCompare(keyword,"width") == 0)
4919 {
cristyf2f27272009-12-17 14:48:46 +00004920 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004921 break;
4922 }
4923 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4924 keyword);
4925 break;
4926 }
4927 default:
4928 {
4929 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4930 keyword);
4931 break;
4932 }
4933 }
4934 }
4935 (void) RaiseImage(msl_info->image[n],&geometry,raise);
4936 break;
4937 }
cristyb988fe72009-09-16 01:01:10 +00004938 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004939 {
4940 if (attributes == (const xmlChar **) NULL)
4941 break;
4942 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4943 {
4944 keyword=(const char *) attributes[i++];
4945 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004946 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00004947 switch (*keyword)
4948 {
4949 case 'F':
4950 case 'f':
4951 {
4952 if (LocaleCompare(keyword,"filename") == 0)
4953 {
4954 Image
4955 *image;
4956
4957 (void) CopyMagickString(msl_info->image_info[n]->filename,
4958 value,MaxTextExtent);
4959 image=ReadImage(msl_info->image_info[n],&exception);
4960 CatchException(&exception);
4961 if (image == (Image *) NULL)
4962 continue;
4963 AppendImageToList(&msl_info->image[n],image);
4964 break;
4965 }
cristy4582cbb2009-09-23 00:35:43 +00004966 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004967 break;
4968 }
4969 default:
4970 {
cristy4582cbb2009-09-23 00:35:43 +00004971 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004972 break;
4973 }
4974 }
4975 }
4976 break;
4977 }
cristyb988fe72009-09-16 01:01:10 +00004978 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004979 {
4980 Image
4981 *paint_image;
4982
4983 /*
4984 Reduce-noise image.
4985 */
4986 if (msl_info->image[n] == (Image *) NULL)
4987 {
cristyb988fe72009-09-16 01:01:10 +00004988 ThrowMSLException(OptionError,"NoImagesDefined",
4989 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004990 break;
4991 }
4992 if (attributes != (const xmlChar **) NULL)
4993 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4994 {
4995 keyword=(const char *) attributes[i++];
4996 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004997 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004998 CloneString(&value,attribute);
4999 switch (*keyword)
5000 {
5001 case 'G':
5002 case 'g':
5003 {
5004 if (LocaleCompare(keyword,"geometry") == 0)
5005 {
5006 flags=ParseGeometry(value,&geometry_info);
5007 if ((flags & SigmaValue) == 0)
5008 geometry_info.sigma=1.0;
5009 break;
5010 }
5011 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5012 keyword);
5013 break;
5014 }
5015 case 'R':
5016 case 'r':
5017 {
5018 if (LocaleCompare(keyword,"radius") == 0)
5019 {
cristyc1acd842011-05-19 23:05:47 +00005020 geometry_info.rho=InterpretLocaleValue(value,
5021 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005022 break;
5023 }
5024 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5025 keyword);
5026 break;
5027 }
5028 default:
5029 {
5030 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5031 keyword);
5032 break;
5033 }
5034 }
5035 }
cristy733678d2011-03-18 21:29:28 +00005036 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005037 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5038 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00005039 if (paint_image == (Image *) NULL)
5040 break;
5041 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5042 msl_info->image[n]=paint_image;
5043 break;
5044 }
cristyb988fe72009-09-16 01:01:10 +00005045 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005046 {
5047 /* init the values */
5048 width=msl_info->image[n]->page.width;
5049 height=msl_info->image[n]->page.height;
5050 x=msl_info->image[n]->page.x;
5051 y=msl_info->image[n]->page.y;
5052
5053 if (msl_info->image[n] == (Image *) NULL)
5054 {
cristyb988fe72009-09-16 01:01:10 +00005055 ThrowMSLException(OptionError,"NoImagesDefined",
5056 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005057 break;
5058 }
5059 if (attributes == (const xmlChar **) NULL)
5060 break;
5061 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5062 {
5063 keyword=(const char *) attributes[i++];
5064 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005065 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005066 switch (*keyword)
5067 {
5068 case 'G':
5069 case 'g':
5070 {
5071 if (LocaleCompare(keyword,"geometry") == 0)
5072 {
5073 int
5074 flags;
5075
5076 RectangleInfo
5077 geometry;
5078
5079 flags=ParseAbsoluteGeometry(value,&geometry);
5080 if ((flags & WidthValue) != 0)
5081 {
5082 if ((flags & HeightValue) == 0)
5083 geometry.height=geometry.width;
5084 width=geometry.width;
5085 height=geometry.height;
5086 }
5087 if ((flags & AspectValue) != 0)
5088 {
5089 if ((flags & XValue) != 0)
5090 x+=geometry.x;
5091 if ((flags & YValue) != 0)
5092 y+=geometry.y;
5093 }
5094 else
5095 {
5096 if ((flags & XValue) != 0)
5097 {
5098 x=geometry.x;
5099 if ((width == 0) && (geometry.x > 0))
5100 width=msl_info->image[n]->columns+geometry.x;
5101 }
5102 if ((flags & YValue) != 0)
5103 {
5104 y=geometry.y;
5105 if ((height == 0) && (geometry.y > 0))
5106 height=msl_info->image[n]->rows+geometry.y;
5107 }
5108 }
5109 break;
5110 }
5111 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5112 break;
5113 }
5114 case 'H':
5115 case 'h':
5116 {
5117 if (LocaleCompare(keyword,"height") == 0)
5118 {
cristyf2f27272009-12-17 14:48:46 +00005119 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005120 break;
5121 }
5122 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5123 break;
5124 }
5125 case 'W':
5126 case 'w':
5127 {
5128 if (LocaleCompare(keyword,"width") == 0)
5129 {
cristyf2f27272009-12-17 14:48:46 +00005130 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005131 break;
5132 }
5133 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5134 break;
5135 }
5136 case 'X':
5137 case 'x':
5138 {
5139 if (LocaleCompare(keyword,"x") == 0)
5140 {
cristyf2f27272009-12-17 14:48:46 +00005141 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005142 break;
5143 }
5144 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5145 break;
5146 }
5147 case 'Y':
5148 case 'y':
5149 {
5150 if (LocaleCompare(keyword,"y") == 0)
5151 {
cristyf2f27272009-12-17 14:48:46 +00005152 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005153 break;
5154 }
5155 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5156 break;
5157 }
5158 default:
5159 {
5160 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5161 break;
5162 }
5163 }
5164 }
5165
cristyb988fe72009-09-16 01:01:10 +00005166 msl_info->image[n]->page.width=width;
5167 msl_info->image[n]->page.height=height;
5168 msl_info->image[n]->page.x=x;
5169 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005170 break;
5171 }
cristyb988fe72009-09-16 01:01:10 +00005172 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005173 {
5174 double
5175 x_resolution,
5176 y_resolution;
5177
5178 if (msl_info->image[n] == (Image *) NULL)
5179 {
cristyb988fe72009-09-16 01:01:10 +00005180 ThrowMSLException(OptionError,"NoImagesDefined",
5181 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005182 break;
5183 }
5184 if (attributes == (const xmlChar **) NULL)
5185 break;
5186 x_resolution=DefaultResolution;
5187 y_resolution=DefaultResolution;
5188 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5189 {
5190 keyword=(const char *) attributes[i++];
5191 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005192 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005193 switch (*keyword)
5194 {
5195 case 'b':
5196 {
5197 if (LocaleCompare(keyword,"blur") == 0)
5198 {
cristyc1acd842011-05-19 23:05:47 +00005199 msl_info->image[n]->blur=InterpretLocaleValue(value,
5200 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005201 break;
5202 }
5203 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5204 break;
5205 }
5206 case 'G':
5207 case 'g':
5208 {
5209 if (LocaleCompare(keyword,"geometry") == 0)
5210 {
cristybb503372010-05-27 20:51:26 +00005211 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005212 flags;
5213
5214 flags=ParseGeometry(value,&geometry_info);
5215 if ((flags & SigmaValue) == 0)
5216 geometry_info.sigma*=geometry_info.rho;
5217 x_resolution=geometry_info.rho;
5218 y_resolution=geometry_info.sigma;
5219 break;
5220 }
5221 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5222 break;
5223 }
5224 case 'X':
5225 case 'x':
5226 {
5227 if (LocaleCompare(keyword,"x-resolution") == 0)
5228 {
cristyc1acd842011-05-19 23:05:47 +00005229 x_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005230 break;
5231 }
5232 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5233 break;
5234 }
5235 case 'Y':
5236 case 'y':
5237 {
5238 if (LocaleCompare(keyword,"y-resolution") == 0)
5239 {
cristyc1acd842011-05-19 23:05:47 +00005240 y_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005241 break;
5242 }
5243 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5244 break;
5245 }
5246 default:
5247 {
5248 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5249 break;
5250 }
5251 }
5252 }
5253 /*
5254 Resample image.
5255 */
5256 {
5257 double
5258 factor;
5259
5260 Image
5261 *resample_image;
5262
5263 factor=1.0;
5264 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5265 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005266 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy3ed852e2009-09-05 21:47:34 +00005267 (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5268 msl_info->image[n]->x_resolution))+0.5);
cristybb503372010-05-27 20:51:26 +00005269 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy3ed852e2009-09-05 21:47:34 +00005270 (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5271 msl_info->image[n]->y_resolution))+0.5);
5272 resample_image=ResizeImage(msl_info->image[n],width,height,
5273 msl_info->image[n]->filter,msl_info->image[n]->blur,
5274 &msl_info->image[n]->exception);
5275 if (resample_image == (Image *) NULL)
5276 break;
5277 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5278 msl_info->image[n]=resample_image;
5279 }
5280 break;
5281 }
cristyb988fe72009-09-16 01:01:10 +00005282 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005283 {
5284 double
5285 blur;
5286
5287 FilterTypes
5288 filter;
5289
5290 Image
5291 *resize_image;
5292
5293 /*
5294 Resize image.
5295 */
5296 if (msl_info->image[n] == (Image *) NULL)
5297 {
cristyb988fe72009-09-16 01:01:10 +00005298 ThrowMSLException(OptionError,"NoImagesDefined",
5299 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005300 break;
5301 }
5302 filter=UndefinedFilter;
5303 blur=1.0;
5304 if (attributes != (const xmlChar **) NULL)
5305 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5306 {
5307 keyword=(const char *) attributes[i++];
5308 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005309 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005310 CloneString(&value,attribute);
5311 switch (*keyword)
5312 {
5313 case 'F':
5314 case 'f':
5315 {
5316 if (LocaleCompare(keyword,"filter") == 0)
5317 {
cristy042ee782011-04-22 18:48:30 +00005318 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005319 value);
5320 if (option < 0)
5321 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5322 value);
5323 filter=(FilterTypes) option;
5324 break;
5325 }
5326 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5327 keyword);
5328 break;
5329 }
5330 case 'G':
5331 case 'g':
5332 {
5333 if (LocaleCompare(keyword,"geometry") == 0)
5334 {
5335 flags=ParseRegionGeometry(msl_info->image[n],value,
5336 &geometry,&exception);
5337 break;
5338 }
5339 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5340 keyword);
5341 break;
5342 }
5343 case 'H':
5344 case 'h':
5345 {
5346 if (LocaleCompare(keyword,"height") == 0)
5347 {
cristye27293e2009-12-18 02:53:20 +00005348 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005349 break;
5350 }
5351 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5352 keyword);
5353 break;
5354 }
5355 case 'S':
5356 case 's':
5357 {
5358 if (LocaleCompare(keyword,"support") == 0)
5359 {
cristyc1acd842011-05-19 23:05:47 +00005360 blur=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005361 break;
5362 }
5363 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5364 keyword);
5365 break;
5366 }
5367 case 'W':
5368 case 'w':
5369 {
5370 if (LocaleCompare(keyword,"width") == 0)
5371 {
cristyf2f27272009-12-17 14:48:46 +00005372 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005373 break;
5374 }
5375 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5376 keyword);
5377 break;
5378 }
5379 default:
5380 {
5381 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5382 keyword);
5383 break;
5384 }
5385 }
5386 }
5387 resize_image=ResizeImage(msl_info->image[n],geometry.width,
5388 geometry.height,filter,blur,&msl_info->image[n]->exception);
5389 if (resize_image == (Image *) NULL)
5390 break;
5391 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5392 msl_info->image[n]=resize_image;
5393 break;
5394 }
cristyb988fe72009-09-16 01:01:10 +00005395 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005396 {
5397 Image
5398 *roll_image;
5399
5400 /*
5401 Roll image.
5402 */
5403 if (msl_info->image[n] == (Image *) NULL)
5404 {
cristyb988fe72009-09-16 01:01:10 +00005405 ThrowMSLException(OptionError,"NoImagesDefined",
5406 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005407 break;
5408 }
5409 SetGeometry(msl_info->image[n],&geometry);
5410 if (attributes != (const xmlChar **) NULL)
5411 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5412 {
5413 keyword=(const char *) attributes[i++];
5414 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005415 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005416 CloneString(&value,attribute);
5417 switch (*keyword)
5418 {
5419 case 'G':
5420 case 'g':
5421 {
5422 if (LocaleCompare(keyword,"geometry") == 0)
5423 {
5424 flags=ParsePageGeometry(msl_info->image[n],value,
5425 &geometry,&exception);
5426 if ((flags & HeightValue) == 0)
5427 geometry.height=geometry.width;
5428 break;
5429 }
5430 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5431 keyword);
5432 break;
5433 }
5434 case 'X':
5435 case 'x':
5436 {
5437 if (LocaleCompare(keyword,"x") == 0)
5438 {
cristyf2f27272009-12-17 14:48:46 +00005439 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005440 break;
5441 }
5442 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5443 keyword);
5444 break;
5445 }
5446 case 'Y':
5447 case 'y':
5448 {
5449 if (LocaleCompare(keyword,"y") == 0)
5450 {
cristyf2f27272009-12-17 14:48:46 +00005451 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005452 break;
5453 }
5454 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5455 keyword);
5456 break;
5457 }
5458 default:
5459 {
5460 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5461 keyword);
5462 break;
5463 }
5464 }
5465 }
5466 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5467 &msl_info->image[n]->exception);
5468 if (roll_image == (Image *) NULL)
5469 break;
5470 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5471 msl_info->image[n]=roll_image;
5472 break;
5473 }
cristyb988fe72009-09-16 01:01:10 +00005474 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005475 {
5476 /* init the values */
5477 width=msl_info->image[n]->columns;
5478 height=msl_info->image[n]->rows;
5479 x = y = 0;
5480
5481 if (msl_info->image[n] == (Image *) NULL)
5482 {
cristyb988fe72009-09-16 01:01:10 +00005483 ThrowMSLException(OptionError,"NoImagesDefined",
5484 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005485 break;
5486 }
5487 if (attributes == (const xmlChar **) NULL)
5488 break;
5489 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5490 {
5491 keyword=(const char *) attributes[i++];
5492 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005493 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005494 switch (*keyword)
5495 {
5496 case 'G':
5497 case 'g':
5498 {
5499 if (LocaleCompare(keyword,"geometry") == 0)
5500 {
5501 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5502 break;
5503 }
5504 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5505 break;
5506 }
5507 case 'X':
5508 case 'x':
5509 {
5510 if (LocaleCompare(keyword,"x") == 0)
5511 {
cristyf2f27272009-12-17 14:48:46 +00005512 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005513 break;
5514 }
5515 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5516 break;
5517 }
5518 case 'Y':
5519 case 'y':
5520 {
5521 if (LocaleCompare(keyword,"y") == 0)
5522 {
cristyf2f27272009-12-17 14:48:46 +00005523 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005524 break;
5525 }
5526 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5527 break;
5528 }
5529 default:
5530 {
5531 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5532 break;
5533 }
5534 }
5535 }
5536
5537 /*
5538 process image.
5539 */
5540 {
5541 Image
5542 *newImage;
5543
5544 newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5545 if (newImage == (Image *) NULL)
5546 break;
5547 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5548 msl_info->image[n]=newImage;
5549 }
5550
5551 break;
5552 }
cristyb988fe72009-09-16 01:01:10 +00005553 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005554 {
5555 Image
5556 *rotate_image;
5557
5558 /*
5559 Rotate image.
5560 */
5561 if (msl_info->image[n] == (Image *) NULL)
5562 {
cristyb988fe72009-09-16 01:01:10 +00005563 ThrowMSLException(OptionError,"NoImagesDefined",
5564 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005565 break;
5566 }
5567 if (attributes != (const xmlChar **) NULL)
5568 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5569 {
5570 keyword=(const char *) attributes[i++];
5571 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005572 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005573 CloneString(&value,attribute);
5574 switch (*keyword)
5575 {
5576 case 'D':
5577 case 'd':
5578 {
5579 if (LocaleCompare(keyword,"degrees") == 0)
5580 {
cristyc1acd842011-05-19 23:05:47 +00005581 geometry_info.rho=InterpretLocaleValue(value,
5582 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005583 break;
5584 }
5585 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5586 keyword);
5587 break;
5588 }
5589 case 'G':
5590 case 'g':
5591 {
5592 if (LocaleCompare(keyword,"geometry") == 0)
5593 {
5594 flags=ParseGeometry(value,&geometry_info);
5595 if ((flags & SigmaValue) == 0)
5596 geometry_info.sigma=1.0;
5597 break;
5598 }
5599 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5600 keyword);
5601 break;
5602 }
5603 default:
5604 {
5605 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5606 keyword);
5607 break;
5608 }
5609 }
5610 }
5611 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5612 &msl_info->image[n]->exception);
5613 if (rotate_image == (Image *) NULL)
5614 break;
5615 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5616 msl_info->image[n]=rotate_image;
5617 break;
5618 }
cristyb988fe72009-09-16 01:01:10 +00005619 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005620 {
5621 /* init the values */
5622 double degrees = 0;
5623
5624 if (msl_info->image[n] == (Image *) NULL)
5625 {
cristyb988fe72009-09-16 01:01:10 +00005626 ThrowMSLException(OptionError,"NoImagesDefined",
5627 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005628 break;
5629 }
5630 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005631 break;
cristy3ed852e2009-09-05 21:47:34 +00005632 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5633 {
5634 keyword=(const char *) attributes[i++];
5635 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005636 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005637 switch (*keyword)
5638 {
5639 case 'D':
5640 case 'd':
5641 {
5642 if (LocaleCompare(keyword,"degrees") == 0)
5643 {
cristyc1acd842011-05-19 23:05:47 +00005644 degrees = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005645 break;
5646 }
5647 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5648 break;
5649 }
5650 default:
5651 {
5652 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5653 break;
5654 }
5655 }
5656 }
5657
5658 /*
5659 process image.
5660 */
5661 {
5662 Image
5663 *newImage;
5664
5665 newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5666 if (newImage == (Image *) NULL)
5667 break;
5668 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5669 msl_info->image[n]=newImage;
5670 }
5671
5672 break;
5673 }
5674 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5675 }
5676 case 'S':
5677 case 's':
5678 {
cristyb988fe72009-09-16 01:01:10 +00005679 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005680 {
5681 Image
5682 *sample_image;
5683
5684 /*
5685 Sample image.
5686 */
5687 if (msl_info->image[n] == (Image *) NULL)
5688 {
cristyb988fe72009-09-16 01:01:10 +00005689 ThrowMSLException(OptionError,"NoImagesDefined",
5690 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005691 break;
5692 }
5693 if (attributes != (const xmlChar **) NULL)
5694 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5695 {
5696 keyword=(const char *) attributes[i++];
5697 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005698 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005699 CloneString(&value,attribute);
5700 switch (*keyword)
5701 {
5702 case 'G':
5703 case 'g':
5704 {
5705 if (LocaleCompare(keyword,"geometry") == 0)
5706 {
5707 flags=ParseRegionGeometry(msl_info->image[n],value,
5708 &geometry,&exception);
5709 break;
5710 }
5711 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5712 keyword);
5713 break;
5714 }
5715 case 'H':
5716 case 'h':
5717 {
5718 if (LocaleCompare(keyword,"height") == 0)
5719 {
cristye27293e2009-12-18 02:53:20 +00005720 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005721 break;
5722 }
5723 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5724 keyword);
5725 break;
5726 }
5727 case 'W':
5728 case 'w':
5729 {
5730 if (LocaleCompare(keyword,"width") == 0)
5731 {
cristyf2f27272009-12-17 14:48:46 +00005732 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005733 break;
5734 }
5735 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5736 keyword);
5737 break;
5738 }
5739 default:
5740 {
5741 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5742 keyword);
5743 break;
5744 }
5745 }
5746 }
5747 sample_image=SampleImage(msl_info->image[n],geometry.width,
5748 geometry.height,&msl_info->image[n]->exception);
5749 if (sample_image == (Image *) NULL)
5750 break;
5751 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5752 msl_info->image[n]=sample_image;
5753 break;
5754 }
cristyb988fe72009-09-16 01:01:10 +00005755 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005756 {
5757 Image
5758 *scale_image;
5759
5760 /*
5761 Scale image.
5762 */
5763 if (msl_info->image[n] == (Image *) NULL)
5764 {
cristyb988fe72009-09-16 01:01:10 +00005765 ThrowMSLException(OptionError,"NoImagesDefined",
5766 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005767 break;
5768 }
5769 if (attributes != (const xmlChar **) NULL)
5770 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5771 {
5772 keyword=(const char *) attributes[i++];
5773 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005774 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005775 CloneString(&value,attribute);
5776 switch (*keyword)
5777 {
5778 case 'G':
5779 case 'g':
5780 {
5781 if (LocaleCompare(keyword,"geometry") == 0)
5782 {
5783 flags=ParseRegionGeometry(msl_info->image[n],value,
5784 &geometry,&exception);
5785 break;
5786 }
5787 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5788 keyword);
5789 break;
5790 }
5791 case 'H':
5792 case 'h':
5793 {
5794 if (LocaleCompare(keyword,"height") == 0)
5795 {
cristye27293e2009-12-18 02:53:20 +00005796 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005797 break;
5798 }
5799 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5800 keyword);
5801 break;
5802 }
5803 case 'W':
5804 case 'w':
5805 {
5806 if (LocaleCompare(keyword,"width") == 0)
5807 {
cristyf2f27272009-12-17 14:48:46 +00005808 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005809 break;
5810 }
5811 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5812 keyword);
5813 break;
5814 }
5815 default:
5816 {
5817 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5818 keyword);
5819 break;
5820 }
5821 }
5822 }
5823 scale_image=ScaleImage(msl_info->image[n],geometry.width,
5824 geometry.height,&msl_info->image[n]->exception);
5825 if (scale_image == (Image *) NULL)
5826 break;
5827 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5828 msl_info->image[n]=scale_image;
5829 break;
5830 }
cristyb988fe72009-09-16 01:01:10 +00005831 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005832 {
5833 ColorspaceType
5834 colorspace;
5835
5836 MagickBooleanType
5837 verbose;
cristyb988fe72009-09-16 01:01:10 +00005838
cristy3ed852e2009-09-05 21:47:34 +00005839 /*
5840 Segment image.
5841 */
5842 if (msl_info->image[n] == (Image *) NULL)
5843 {
cristyb988fe72009-09-16 01:01:10 +00005844 ThrowMSLException(OptionError,"NoImagesDefined",
5845 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005846 break;
5847 }
5848 geometry_info.rho=1.0;
5849 geometry_info.sigma=1.5;
5850 colorspace=RGBColorspace;
5851 verbose=MagickFalse;
5852 if (attributes != (const xmlChar **) NULL)
5853 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5854 {
5855 keyword=(const char *) attributes[i++];
5856 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005857 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005858 CloneString(&value,attribute);
5859 switch (*keyword)
5860 {
5861 case 'C':
5862 case 'c':
5863 {
5864 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5865 {
cristyc1acd842011-05-19 23:05:47 +00005866 geometry_info.rho=InterpretLocaleValue(value,
5867 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005868 break;
5869 }
5870 if (LocaleCompare(keyword,"colorspace") == 0)
5871 {
cristy042ee782011-04-22 18:48:30 +00005872 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005873 MagickFalse,value);
5874 if (option < 0)
5875 ThrowMSLException(OptionError,
5876 "UnrecognizedColorspaceType",value);
5877 colorspace=(ColorspaceType) option;
5878 break;
5879 }
5880 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5881 keyword);
5882 break;
5883 }
5884 case 'G':
5885 case 'g':
5886 {
5887 if (LocaleCompare(keyword,"geometry") == 0)
5888 {
5889 flags=ParseGeometry(value,&geometry_info);
5890 if ((flags & SigmaValue) == 0)
5891 geometry_info.sigma=1.5;
5892 break;
5893 }
5894 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5895 keyword);
5896 break;
5897 }
5898 case 'S':
5899 case 's':
5900 {
5901 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5902 {
cristyc1acd842011-05-19 23:05:47 +00005903 geometry_info.sigma=InterpretLocaleValue(value,
5904 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005905 break;
5906 }
5907 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5908 keyword);
5909 break;
5910 }
5911 default:
5912 {
5913 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5914 keyword);
5915 break;
5916 }
5917 }
5918 }
5919 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5920 geometry_info.rho,geometry_info.sigma);
5921 break;
5922 }
cristyb988fe72009-09-16 01:01:10 +00005923 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005924 {
5925 if (msl_info->image[n] == (Image *) NULL)
5926 {
cristyb988fe72009-09-16 01:01:10 +00005927 ThrowMSLException(OptionError,"NoImagesDefined",
5928 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005929 break;
5930 }
5931
5932 if (attributes == (const xmlChar **) NULL)
5933 break;
5934 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5935 {
5936 keyword=(const char *) attributes[i++];
5937 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005938 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005939 switch (*keyword)
5940 {
cristy3ed852e2009-09-05 21:47:34 +00005941 case 'C':
5942 case 'c':
5943 {
5944 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005945 {
cristy2c8b6312009-09-16 02:37:23 +00005946 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005947 {
cristy2c8b6312009-09-16 02:37:23 +00005948 const char
5949 *property;
5950
5951 property=GetImageProperty(msl_info->attributes[j],"id");
5952 if (LocaleCompare(property,value) == 0)
5953 {
5954 SetImageMask(msl_info->image[n],msl_info->image[j]);
5955 break;
5956 }
cristy3ed852e2009-09-05 21:47:34 +00005957 }
cristy2c8b6312009-09-16 02:37:23 +00005958 break;
cristy3ed852e2009-09-05 21:47:34 +00005959 }
cristy3ed852e2009-09-05 21:47:34 +00005960 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005961 {
cristy2c8b6312009-09-16 02:37:23 +00005962 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005963 {
cristy2c8b6312009-09-16 02:37:23 +00005964 const char
5965 *property;
5966
5967 property=GetImageProperty(msl_info->attributes[j],"id");
5968 if (LocaleCompare(property,value) == 0)
5969 {
5970 SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5971 break;
5972 }
cristy3ed852e2009-09-05 21:47:34 +00005973 }
cristy2c8b6312009-09-16 02:37:23 +00005974 break;
cristy3ed852e2009-09-05 21:47:34 +00005975 }
cristy2c8b6312009-09-16 02:37:23 +00005976 if (LocaleCompare(keyword,"colorspace") == 0)
5977 {
cristybb503372010-05-27 20:51:26 +00005978 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00005979 colorspace;
5980
cristy042ee782011-04-22 18:48:30 +00005981 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00005982 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00005983 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00005984 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00005985 value);
5986 (void) TransformImageColorspace(msl_info->image[n],
5987 (ColorspaceType) colorspace);
5988 break;
5989 }
5990 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005991 break;
5992 }
5993 case 'D':
5994 case 'd':
5995 {
cristy2c8b6312009-09-16 02:37:23 +00005996 if (LocaleCompare(keyword,"density") == 0)
5997 {
5998 flags=ParseGeometry(value,&geometry_info);
5999 msl_info->image[n]->x_resolution=geometry_info.rho;
6000 msl_info->image[n]->y_resolution=geometry_info.sigma;
6001 if ((flags & SigmaValue) == 0)
6002 msl_info->image[n]->y_resolution=
6003 msl_info->image[n]->x_resolution;
6004 break;
6005 }
6006 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006007 break;
6008 }
6009 case 'O':
6010 case 'o':
6011 {
6012 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006013 {
cristy4c08aed2011-07-01 19:47:50 +00006014 ssize_t opac = OpaqueAlpha,
cristybb503372010-05-27 20:51:26 +00006015 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006016
cristy2c8b6312009-09-16 02:37:23 +00006017 if (value[len-1] == '%') {
6018 char tmp[100];
6019 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006020 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006021 opac = (int)(QuantumRange * ((float)opac/100));
6022 } else
cristyf2f27272009-12-17 14:48:46 +00006023 opac = StringToLong( value );
cristy2c8b6312009-09-16 02:37:23 +00006024 (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6025 break;
cristy3ed852e2009-09-05 21:47:34 +00006026 }
cristy2c8b6312009-09-16 02:37:23 +00006027 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006028 break;
6029 }
6030 case 'P':
6031 case 'p':
6032 {
6033 if (LocaleCompare(keyword, "page") == 0)
6034 {
6035 char
6036 page[MaxTextExtent];
6037
6038 const char
6039 *image_option;
6040
6041 MagickStatusType
6042 flags;
6043
6044 RectangleInfo
6045 geometry;
6046
6047 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6048 image_option=GetImageOption(msl_info->image_info[n],"page");
6049 if (image_option != (const char *) NULL)
6050 flags=ParseAbsoluteGeometry(image_option,&geometry);
6051 flags=ParseAbsoluteGeometry(value,&geometry);
cristyb51dff52011-05-19 16:55:47 +00006052 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
cristye8c25f92010-06-03 00:53:06 +00006053 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006054 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristyb51dff52011-05-19 16:55:47 +00006055 (void) FormatLocaleString(page,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00006056 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6057 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006058 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006059 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6060 msl_info->image_info[n]->page=GetPageGeometry(page);
6061 break;
6062 }
cristy2c8b6312009-09-16 02:37:23 +00006063 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006064 break;
6065 }
6066 default:
6067 {
cristy2c8b6312009-09-16 02:37:23 +00006068 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006069 break;
6070 }
6071 }
6072 }
6073 break;
6074 }
cristyb988fe72009-09-16 01:01:10 +00006075 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006076 {
6077 Image
6078 *shade_image;
6079
6080 MagickBooleanType
6081 gray;
6082
6083 /*
6084 Shade image.
6085 */
6086 if (msl_info->image[n] == (Image *) NULL)
6087 {
cristyb988fe72009-09-16 01:01:10 +00006088 ThrowMSLException(OptionError,"NoImagesDefined",
6089 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006090 break;
6091 }
6092 gray=MagickFalse;
6093 if (attributes != (const xmlChar **) NULL)
6094 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6095 {
6096 keyword=(const char *) attributes[i++];
6097 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006098 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006099 CloneString(&value,attribute);
6100 switch (*keyword)
6101 {
6102 case 'A':
6103 case 'a':
6104 {
6105 if (LocaleCompare(keyword,"azimuth") == 0)
6106 {
cristyc1acd842011-05-19 23:05:47 +00006107 geometry_info.rho=InterpretLocaleValue(value,
6108 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006109 break;
6110 }
6111 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6112 keyword);
6113 break;
6114 }
6115 case 'E':
6116 case 'e':
6117 {
6118 if (LocaleCompare(keyword,"elevation") == 0)
6119 {
cristyc1acd842011-05-19 23:05:47 +00006120 geometry_info.sigma=InterpretLocaleValue(value,
6121 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006122 break;
6123 }
6124 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6125 keyword);
6126 break;
6127 }
6128 case 'G':
6129 case 'g':
6130 {
6131 if (LocaleCompare(keyword,"geometry") == 0)
6132 {
6133 flags=ParseGeometry(value,&geometry_info);
6134 if ((flags & SigmaValue) == 0)
6135 geometry_info.sigma=1.0;
6136 break;
6137 }
6138 if (LocaleCompare(keyword,"gray") == 0)
6139 {
cristy042ee782011-04-22 18:48:30 +00006140 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006141 value);
6142 if (option < 0)
6143 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6144 value);
6145 gray=(MagickBooleanType) option;
6146 break;
6147 }
6148 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6149 keyword);
6150 break;
6151 }
6152 default:
6153 {
6154 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6155 keyword);
6156 break;
6157 }
6158 }
6159 }
6160 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6161 geometry_info.sigma,&msl_info->image[n]->exception);
6162 if (shade_image == (Image *) NULL)
6163 break;
6164 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6165 msl_info->image[n]=shade_image;
6166 break;
6167 }
cristyb988fe72009-09-16 01:01:10 +00006168 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006169 {
6170 Image
6171 *shadow_image;
6172
6173 /*
6174 Shear image.
6175 */
6176 if (msl_info->image[n] == (Image *) NULL)
6177 {
cristyb988fe72009-09-16 01:01:10 +00006178 ThrowMSLException(OptionError,"NoImagesDefined",
6179 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006180 break;
6181 }
6182 if (attributes != (const xmlChar **) NULL)
6183 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6184 {
6185 keyword=(const char *) attributes[i++];
6186 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006187 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006188 CloneString(&value,attribute);
6189 switch (*keyword)
6190 {
6191 case 'G':
6192 case 'g':
6193 {
6194 if (LocaleCompare(keyword,"geometry") == 0)
6195 {
6196 flags=ParseGeometry(value,&geometry_info);
6197 if ((flags & SigmaValue) == 0)
6198 geometry_info.sigma=1.0;
6199 break;
6200 }
6201 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6202 keyword);
6203 break;
6204 }
6205 case 'O':
6206 case 'o':
6207 {
6208 if (LocaleCompare(keyword,"opacity") == 0)
6209 {
cristyf2f27272009-12-17 14:48:46 +00006210 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006211 break;
6212 }
6213 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6214 keyword);
6215 break;
6216 }
6217 case 'S':
6218 case 's':
6219 {
6220 if (LocaleCompare(keyword,"sigma") == 0)
6221 {
cristyf2f27272009-12-17 14:48:46 +00006222 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006223 break;
6224 }
6225 break;
6226 }
6227 case 'X':
6228 case 'x':
6229 {
6230 if (LocaleCompare(keyword,"x") == 0)
6231 {
cristyc1acd842011-05-19 23:05:47 +00006232 geometry_info.xi=InterpretLocaleValue(value,
6233 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006234 break;
6235 }
6236 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6237 keyword);
6238 break;
6239 }
6240 case 'Y':
6241 case 'y':
6242 {
6243 if (LocaleCompare(keyword,"y") == 0)
6244 {
cristyf2f27272009-12-17 14:48:46 +00006245 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006246 break;
6247 }
6248 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6249 keyword);
6250 break;
6251 }
6252 default:
6253 {
6254 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6255 keyword);
6256 break;
6257 }
6258 }
6259 }
6260 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristybb503372010-05-27 20:51:26 +00006261 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
cristy0534a6b2010-03-18 01:19:38 +00006262 ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006263 if (shadow_image == (Image *) NULL)
6264 break;
6265 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6266 msl_info->image[n]=shadow_image;
6267 break;
6268 }
cristyb988fe72009-09-16 01:01:10 +00006269 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006270 {
6271 double radius = 0.0,
6272 sigma = 1.0;
6273
6274 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006275 {
6276 ThrowMSLException(OptionError,"NoImagesDefined",
6277 (const char *) tag);
6278 break;
6279 }
cristy3ed852e2009-09-05 21:47:34 +00006280 /*
6281 NOTE: sharpen can have no attributes, since we use all the defaults!
6282 */
6283 if (attributes != (const xmlChar **) NULL)
6284 {
6285 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6286 {
6287 keyword=(const char *) attributes[i++];
6288 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006289 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006290 switch (*keyword)
6291 {
6292 case 'R':
6293 case 'r':
6294 {
6295 if (LocaleCompare(keyword, "radius") == 0)
6296 {
cristyc1acd842011-05-19 23:05:47 +00006297 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006298 break;
6299 }
6300 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6301 break;
6302 }
6303 case 'S':
6304 case 's':
6305 {
6306 if (LocaleCompare(keyword,"sigma") == 0)
6307 {
cristyf2f27272009-12-17 14:48:46 +00006308 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006309 break;
6310 }
6311 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6312 break;
6313 }
6314 default:
6315 {
6316 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6317 break;
6318 }
6319 }
6320 }
6321 }
6322
6323 /*
6324 sharpen image.
6325 */
6326 {
6327 Image
6328 *newImage;
6329
6330 newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6331 if (newImage == (Image *) NULL)
6332 break;
6333 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6334 msl_info->image[n]=newImage;
6335 break;
6336 }
6337 }
cristyb988fe72009-09-16 01:01:10 +00006338 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006339 {
6340 /* init the values */
6341 width = height = 0;
6342 x = y = 0;
6343
6344 if (msl_info->image[n] == (Image *) NULL)
6345 {
cristyb988fe72009-09-16 01:01:10 +00006346 ThrowMSLException(OptionError,"NoImagesDefined",
6347 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006348 break;
6349 }
6350 if (attributes == (const xmlChar **) NULL)
6351 break;
6352 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6353 {
6354 keyword=(const char *) attributes[i++];
6355 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006356 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006357 switch (*keyword)
6358 {
6359 case 'G':
6360 case 'g':
6361 {
6362 if (LocaleCompare(keyword,"geometry") == 0)
6363 {
6364 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6365 break;
6366 }
6367 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6368 break;
6369 }
6370 case 'H':
6371 case 'h':
6372 {
6373 if (LocaleCompare(keyword,"height") == 0)
6374 {
cristyf2f27272009-12-17 14:48:46 +00006375 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006376 break;
6377 }
6378 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6379 break;
6380 }
6381 case 'W':
6382 case 'w':
6383 {
6384 if (LocaleCompare(keyword,"width") == 0)
6385 {
cristyf2f27272009-12-17 14:48:46 +00006386 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006387 break;
6388 }
6389 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6390 break;
6391 }
6392 default:
6393 {
6394 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6395 break;
6396 }
6397 }
6398 }
6399
6400 /*
6401 process image.
6402 */
6403 {
6404 Image
6405 *newImage;
6406 RectangleInfo
6407 rectInfo;
6408
6409 rectInfo.height = height;
6410 rectInfo.width = width;
6411 rectInfo.x = x;
6412 rectInfo.y = y;
6413
6414
6415 newImage=ShaveImage(msl_info->image[n], &rectInfo,
6416 &msl_info->image[n]->exception);
6417 if (newImage == (Image *) NULL)
6418 break;
6419 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6420 msl_info->image[n]=newImage;
6421 }
6422
6423 break;
6424 }
cristyb988fe72009-09-16 01:01:10 +00006425 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006426 {
6427 Image
6428 *shear_image;
6429
6430 /*
6431 Shear image.
6432 */
6433 if (msl_info->image[n] == (Image *) NULL)
6434 {
cristyb988fe72009-09-16 01:01:10 +00006435 ThrowMSLException(OptionError,"NoImagesDefined",
6436 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006437 break;
6438 }
6439 if (attributes != (const xmlChar **) NULL)
6440 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6441 {
6442 keyword=(const char *) attributes[i++];
6443 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006444 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006445 CloneString(&value,attribute);
6446 switch (*keyword)
6447 {
6448 case 'F':
6449 case 'f':
6450 {
6451 if (LocaleCompare(keyword, "fill") == 0)
6452 {
6453 (void) QueryColorDatabase(value,
6454 &msl_info->image[n]->background_color,&exception);
6455 break;
6456 }
6457 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6458 keyword);
6459 break;
6460 }
6461 case 'G':
6462 case 'g':
6463 {
6464 if (LocaleCompare(keyword,"geometry") == 0)
6465 {
6466 flags=ParseGeometry(value,&geometry_info);
6467 if ((flags & SigmaValue) == 0)
6468 geometry_info.sigma=1.0;
6469 break;
6470 }
6471 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6472 keyword);
6473 break;
6474 }
6475 case 'X':
6476 case 'x':
6477 {
6478 if (LocaleCompare(keyword,"x") == 0)
6479 {
cristyc1acd842011-05-19 23:05:47 +00006480 geometry_info.rho=InterpretLocaleValue(value,
6481 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006482 break;
6483 }
6484 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6485 keyword);
6486 break;
6487 }
6488 case 'Y':
6489 case 'y':
6490 {
6491 if (LocaleCompare(keyword,"y") == 0)
6492 {
cristyf2f27272009-12-17 14:48:46 +00006493 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006494 break;
6495 }
6496 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6497 keyword);
6498 break;
6499 }
6500 default:
6501 {
6502 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6503 keyword);
6504 break;
6505 }
6506 }
6507 }
6508 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6509 geometry_info.sigma,&msl_info->image[n]->exception);
6510 if (shear_image == (Image *) NULL)
6511 break;
6512 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6513 msl_info->image[n]=shear_image;
6514 break;
6515 }
cristyb988fe72009-09-16 01:01:10 +00006516 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006517 {
6518 /*
6519 Signature image.
6520 */
6521 if (msl_info->image[n] == (Image *) NULL)
6522 {
cristyb988fe72009-09-16 01:01:10 +00006523 ThrowMSLException(OptionError,"NoImagesDefined",
6524 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006525 break;
6526 }
6527 if (attributes != (const xmlChar **) NULL)
6528 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6529 {
6530 keyword=(const char *) attributes[i++];
6531 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006532 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006533 CloneString(&value,attribute);
6534 switch (*keyword)
6535 {
6536 default:
6537 {
6538 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6539 keyword);
6540 break;
6541 }
6542 }
6543 }
6544 (void) SignatureImage(msl_info->image[n]);
6545 break;
6546 }
cristyb988fe72009-09-16 01:01:10 +00006547 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006548 {
6549 /*
6550 Solarize image.
6551 */
6552 if (msl_info->image[n] == (Image *) NULL)
6553 {
cristyb988fe72009-09-16 01:01:10 +00006554 ThrowMSLException(OptionError,"NoImagesDefined",
6555 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006556 break;
6557 }
6558 geometry_info.rho=QuantumRange/2.0;
6559 if (attributes != (const xmlChar **) NULL)
6560 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6561 {
6562 keyword=(const char *) attributes[i++];
6563 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006564 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006565 CloneString(&value,attribute);
6566 switch (*keyword)
6567 {
6568 case 'G':
6569 case 'g':
6570 {
6571 if (LocaleCompare(keyword,"geometry") == 0)
6572 {
6573 flags=ParseGeometry(value,&geometry_info);
6574 break;
6575 }
6576 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6577 keyword);
6578 break;
6579 }
6580 case 'T':
6581 case 't':
6582 {
6583 if (LocaleCompare(keyword,"threshold") == 0)
6584 {
cristyc1acd842011-05-19 23:05:47 +00006585 geometry_info.rho=InterpretLocaleValue(value,
6586 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006587 break;
6588 }
6589 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6590 keyword);
6591 break;
6592 }
6593 default:
6594 {
6595 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6596 keyword);
6597 break;
6598 }
6599 }
6600 }
6601 (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6602 break;
6603 }
cristyb988fe72009-09-16 01:01:10 +00006604 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006605 {
6606 Image
6607 *spread_image;
6608
6609 /*
6610 Spread image.
6611 */
6612 if (msl_info->image[n] == (Image *) NULL)
6613 {
cristyb988fe72009-09-16 01:01:10 +00006614 ThrowMSLException(OptionError,"NoImagesDefined",
6615 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006616 break;
6617 }
6618 if (attributes != (const xmlChar **) NULL)
6619 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6620 {
6621 keyword=(const char *) attributes[i++];
6622 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006623 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006624 CloneString(&value,attribute);
6625 switch (*keyword)
6626 {
6627 case 'G':
6628 case 'g':
6629 {
6630 if (LocaleCompare(keyword,"geometry") == 0)
6631 {
6632 flags=ParseGeometry(value,&geometry_info);
6633 if ((flags & SigmaValue) == 0)
6634 geometry_info.sigma=1.0;
6635 break;
6636 }
6637 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6638 keyword);
6639 break;
6640 }
6641 case 'R':
6642 case 'r':
6643 {
6644 if (LocaleCompare(keyword,"radius") == 0)
6645 {
cristyc1acd842011-05-19 23:05:47 +00006646 geometry_info.rho=InterpretLocaleValue(value,
6647 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006648 break;
6649 }
6650 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6651 keyword);
6652 break;
6653 }
6654 default:
6655 {
6656 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6657 keyword);
6658 break;
6659 }
6660 }
6661 }
6662 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6663 &msl_info->image[n]->exception);
6664 if (spread_image == (Image *) NULL)
6665 break;
6666 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6667 msl_info->image[n]=spread_image;
6668 break;
6669 }
cristyb988fe72009-09-16 01:01:10 +00006670 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006671 {
6672 Image *
6673 watermark = (Image*)NULL;
6674
6675 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006676 {
6677 ThrowMSLException(OptionError,"NoImagesDefined",
6678 (const char *) tag);
6679 break;
6680 }
cristy3ed852e2009-09-05 21:47:34 +00006681 if (attributes == (const xmlChar **) NULL)
6682 break;
6683 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6684 {
6685 keyword=(const char *) attributes[i++];
6686 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006687 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006688 switch (*keyword)
6689 {
6690 case 'I':
6691 case 'i':
6692 {
6693 if (LocaleCompare(keyword,"image") == 0)
6694 {
6695 for (j=0; j<msl_info->n;j++)
6696 {
6697 const char *
6698 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6699 if (theAttr && LocaleCompare(theAttr, value) == 0)
6700 {
6701 watermark = msl_info->image[j];
6702 break;
6703 }
6704 }
6705 break;
6706 }
6707 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6708 break;
6709 }
6710 default:
6711 {
6712 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6713 break;
6714 }
6715 }
6716 }
6717
6718 /*
6719 process image.
6720 */
6721 if ( watermark != (Image*) NULL )
6722 {
6723 Image
6724 *newImage;
6725
6726 newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6727 if (newImage == (Image *) NULL)
6728 break;
6729 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6730 msl_info->image[n]=newImage;
6731 break;
6732 } else
6733 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6734 }
cristyb988fe72009-09-16 01:01:10 +00006735 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006736 {
6737 Image *
6738 stereoImage = (Image*)NULL;
6739
6740 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006741 {
6742 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6743 break;
6744 }
cristy3ed852e2009-09-05 21:47:34 +00006745 if (attributes == (const xmlChar **) NULL)
6746 break;
6747 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6748 {
6749 keyword=(const char *) attributes[i++];
6750 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006751 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006752 switch (*keyword)
6753 {
6754 case 'I':
6755 case 'i':
6756 {
6757 if (LocaleCompare(keyword,"image") == 0)
6758 {
6759 for (j=0; j<msl_info->n;j++)
6760 {
6761 const char *
6762 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6763 if (theAttr && LocaleCompare(theAttr, value) == 0)
6764 {
6765 stereoImage = msl_info->image[j];
6766 break;
6767 }
6768 }
6769 break;
6770 }
6771 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6772 break;
6773 }
6774 default:
6775 {
6776 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6777 break;
6778 }
6779 }
6780 }
6781
6782 /*
6783 process image.
6784 */
6785 if ( stereoImage != (Image*) NULL )
6786 {
6787 Image
6788 *newImage;
6789
6790 newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6791 if (newImage == (Image *) NULL)
6792 break;
6793 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6794 msl_info->image[n]=newImage;
6795 break;
6796 } else
6797 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6798 }
cristyb988fe72009-09-16 01:01:10 +00006799 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006800 {
6801 Image
6802 *p,
6803 *q,
6804 *swap;
6805
cristybb503372010-05-27 20:51:26 +00006806 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006807 index,
6808 swap_index;
6809
6810 if (msl_info->image[n] == (Image *) NULL)
6811 {
cristyb988fe72009-09-16 01:01:10 +00006812 ThrowMSLException(OptionError,"NoImagesDefined",
6813 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006814 break;
6815 }
6816 index=(-1);
6817 swap_index=(-2);
6818 if (attributes != (const xmlChar **) NULL)
6819 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6820 {
6821 keyword=(const char *) attributes[i++];
6822 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006823 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006824 CloneString(&value,attribute);
6825 switch (*keyword)
6826 {
6827 case 'G':
6828 case 'g':
6829 {
6830 if (LocaleCompare(keyword,"indexes") == 0)
6831 {
6832 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006833 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006834 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006835 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006836 break;
6837 }
6838 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6839 keyword);
6840 break;
6841 }
6842 default:
6843 {
6844 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6845 keyword);
6846 break;
6847 }
6848 }
6849 }
6850 /*
6851 Swap images.
6852 */
6853 p=GetImageFromList(msl_info->image[n],index);
6854 q=GetImageFromList(msl_info->image[n],swap_index);
6855 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6856 {
cristyb988fe72009-09-16 01:01:10 +00006857 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006858 break;
6859 }
6860 swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6861 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6862 ReplaceImageInList(&q,swap);
6863 msl_info->image[n]=GetFirstImageInList(q);
6864 break;
6865 }
cristyb988fe72009-09-16 01:01:10 +00006866 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006867 {
6868 Image
6869 *swirl_image;
6870
6871 /*
6872 Swirl image.
6873 */
6874 if (msl_info->image[n] == (Image *) NULL)
6875 {
cristyb988fe72009-09-16 01:01:10 +00006876 ThrowMSLException(OptionError,"NoImagesDefined",
6877 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006878 break;
6879 }
6880 if (attributes != (const xmlChar **) NULL)
6881 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6882 {
6883 keyword=(const char *) attributes[i++];
6884 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006885 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006886 CloneString(&value,attribute);
6887 switch (*keyword)
6888 {
6889 case 'D':
6890 case 'd':
6891 {
6892 if (LocaleCompare(keyword,"degrees") == 0)
6893 {
cristyc1acd842011-05-19 23:05:47 +00006894 geometry_info.rho=InterpretLocaleValue(value,
6895 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006896 break;
6897 }
6898 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6899 keyword);
6900 break;
6901 }
6902 case 'G':
6903 case 'g':
6904 {
6905 if (LocaleCompare(keyword,"geometry") == 0)
6906 {
6907 flags=ParseGeometry(value,&geometry_info);
6908 if ((flags & SigmaValue) == 0)
6909 geometry_info.sigma=1.0;
6910 break;
6911 }
6912 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6913 keyword);
6914 break;
6915 }
6916 default:
6917 {
6918 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6919 keyword);
6920 break;
6921 }
6922 }
6923 }
6924 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6925 &msl_info->image[n]->exception);
6926 if (swirl_image == (Image *) NULL)
6927 break;
6928 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6929 msl_info->image[n]=swirl_image;
6930 break;
6931 }
cristyb988fe72009-09-16 01:01:10 +00006932 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006933 {
6934 /*
6935 Sync image.
6936 */
6937 if (msl_info->image[n] == (Image *) NULL)
6938 {
cristyb988fe72009-09-16 01:01:10 +00006939 ThrowMSLException(OptionError,"NoImagesDefined",
6940 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006941 break;
6942 }
6943 if (attributes != (const xmlChar **) NULL)
6944 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6945 {
6946 keyword=(const char *) attributes[i++];
6947 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006948 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006949 CloneString(&value,attribute);
6950 switch (*keyword)
6951 {
6952 default:
6953 {
6954 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6955 keyword);
6956 break;
6957 }
6958 }
6959 }
6960 (void) SyncImage(msl_info->image[n]);
6961 break;
6962 }
6963 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6964 }
6965 case 'T':
6966 case 't':
6967 {
cristyb988fe72009-09-16 01:01:10 +00006968 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006969 {
6970 Image
6971 *texture_image;
6972
6973 /*
6974 Texture image.
6975 */
6976 if (msl_info->image[n] == (Image *) NULL)
6977 {
cristyb988fe72009-09-16 01:01:10 +00006978 ThrowMSLException(OptionError,"NoImagesDefined",
6979 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006980 break;
6981 }
6982 texture_image=NewImageList();
6983 if (attributes != (const xmlChar **) NULL)
6984 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6985 {
6986 keyword=(const char *) attributes[i++];
6987 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006988 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006989 CloneString(&value,attribute);
6990 switch (*keyword)
6991 {
6992 case 'I':
6993 case 'i':
6994 {
6995 if (LocaleCompare(keyword,"image") == 0)
6996 for (j=0; j < msl_info->n; j++)
6997 {
6998 const char
6999 *attribute;
cristyb988fe72009-09-16 01:01:10 +00007000
cristy3ed852e2009-09-05 21:47:34 +00007001 attribute=GetImageProperty(msl_info->attributes[j],"id");
7002 if ((attribute != (const char *) NULL) &&
7003 (LocaleCompare(attribute,value) == 0))
7004 {
7005 texture_image=CloneImage(msl_info->image[j],0,0,
7006 MagickFalse,&exception);
7007 break;
7008 }
7009 }
7010 break;
7011 }
7012 default:
7013 {
7014 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7015 keyword);
7016 break;
7017 }
7018 }
7019 }
7020 (void) TextureImage(msl_info->image[n],texture_image);
7021 texture_image=DestroyImage(texture_image);
7022 break;
7023 }
cristyb988fe72009-09-16 01:01:10 +00007024 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007025 {
7026 /* init the values */
7027 double threshold = 0;
7028
7029 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007030 {
7031 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7032 break;
7033 }
cristy3ed852e2009-09-05 21:47:34 +00007034 if (attributes == (const xmlChar **) NULL)
7035 break;
7036 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7037 {
7038 keyword=(const char *) attributes[i++];
7039 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007040 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007041 switch (*keyword)
7042 {
7043 case 'T':
7044 case 't':
7045 {
7046 if (LocaleCompare(keyword,"threshold") == 0)
7047 {
cristyc1acd842011-05-19 23:05:47 +00007048 threshold = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007049 break;
7050 }
7051 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7052 break;
7053 }
7054 default:
7055 {
7056 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7057 break;
7058 }
7059 }
7060 }
7061
7062 /*
7063 process image.
7064 */
7065 {
7066 BilevelImageChannel(msl_info->image[n],
cristy9a9230e2011-04-26 14:56:14 +00007067 (ChannelType) ((ssize_t) (CompositeChannels &~ (ssize_t) OpacityChannel)),
cristy3ed852e2009-09-05 21:47:34 +00007068 threshold);
7069 break;
7070 }
7071 }
cristyb988fe72009-09-16 01:01:10 +00007072 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007073 {
7074 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007075 {
7076 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7077 break;
7078 }
cristy3ed852e2009-09-05 21:47:34 +00007079 if (attributes == (const xmlChar **) NULL)
7080 break;
7081 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7082 {
7083 keyword=(const char *) attributes[i++];
7084 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007085 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007086 switch (*keyword)
7087 {
7088 case 'C':
7089 case 'c':
7090 {
7091 if (LocaleCompare(keyword,"color") == 0)
7092 {
cristy4c08aed2011-07-01 19:47:50 +00007093 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00007094 target;
7095
7096 (void) QueryMagickColor(value,&target,&exception);
7097 (void) TransparentPaintImage(msl_info->image[n],&target,
cristy4c08aed2011-07-01 19:47:50 +00007098 TransparentAlpha,MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +00007099 break;
7100 }
7101 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7102 break;
7103 }
7104 default:
7105 {
7106 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7107 break;
7108 }
7109 }
7110 }
7111 break;
7112 }
cristyb988fe72009-09-16 01:01:10 +00007113 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007114 {
7115 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007116 {
7117 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7118 break;
7119 }
cristy3ed852e2009-09-05 21:47:34 +00007120
7121 /* no attributes here */
7122
7123 /* process the image */
7124 {
7125 Image
7126 *newImage;
7127 RectangleInfo
7128 rectInfo;
7129
7130 /* all zeros on a crop == trim edges! */
7131 rectInfo.height = rectInfo.width = 0;
7132 rectInfo.x = rectInfo.y = 0;
7133
7134 newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7135 if (newImage == (Image *) NULL)
7136 break;
7137 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7138 msl_info->image[n]=newImage;
7139 break;
7140 }
7141 }
7142 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7143 }
7144 case 'W':
7145 case 'w':
7146 {
cristyb988fe72009-09-16 01:01:10 +00007147 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007148 {
7149 if (msl_info->image[n] == (Image *) NULL)
7150 {
cristyb988fe72009-09-16 01:01:10 +00007151 ThrowMSLException(OptionError,"NoImagesDefined",
7152 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007153 break;
7154 }
7155 if (attributes == (const xmlChar **) NULL)
7156 break;
7157 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7158 {
7159 keyword=(const char *) attributes[i++];
7160 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007161 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007162 switch (*keyword)
7163 {
7164 case 'F':
7165 case 'f':
7166 {
7167 if (LocaleCompare(keyword,"filename") == 0)
7168 {
7169 (void) CopyMagickString(msl_info->image[n]->filename,value,
7170 MaxTextExtent);
7171 break;
7172 }
cristy4582cbb2009-09-23 00:35:43 +00007173 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007174 }
7175 default:
7176 {
cristy4582cbb2009-09-23 00:35:43 +00007177 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007178 break;
7179 }
7180 }
7181 }
7182
7183 /* process */
7184 {
7185 (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7186 break;
7187 }
7188 }
7189 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7190 }
7191 default:
7192 {
7193 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7194 break;
7195 }
7196 }
7197 if ( value != NULL )
7198 value=DestroyString(value);
7199 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7200}
7201
7202static void MSLEndElement(void *context,const xmlChar *tag)
7203{
cristybb503372010-05-27 20:51:26 +00007204 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007205 n;
7206
7207 MSLInfo
7208 *msl_info;
7209
7210 /*
7211 Called when the end of an element has been detected.
7212 */
7213 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7214 tag);
7215 msl_info=(MSLInfo *) context;
7216 n=msl_info->n;
7217 switch (*tag)
7218 {
7219 case 'C':
7220 case 'c':
7221 {
cristyb988fe72009-09-16 01:01:10 +00007222 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007223 {
7224 (void) DeleteImageProperty(msl_info->image[n],"comment");
7225 if (msl_info->content == (char *) NULL)
7226 break;
7227 StripString(msl_info->content);
7228 (void) SetImageProperty(msl_info->image[n],"comment",
7229 msl_info->content);
7230 break;
7231 }
7232 break;
7233 }
7234 case 'G':
7235 case 'g':
7236 {
cristyb988fe72009-09-16 01:01:10 +00007237 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007238 {
7239 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7240 {
cristybb503372010-05-27 20:51:26 +00007241 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007242 (msl_info->group_info[msl_info->number_groups-1].numImages);
7243 while ( i-- )
7244 {
7245 if (msl_info->image[msl_info->n] != (Image *) NULL)
7246 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7247 msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7248 msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7249 msl_info->n--;
7250 }
7251 }
7252 msl_info->number_groups--;
7253 }
7254 break;
7255 }
7256 case 'I':
7257 case 'i':
7258 {
cristyb988fe72009-09-16 01:01:10 +00007259 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007260 MSLPopImage(msl_info);
7261 break;
7262 }
7263 case 'L':
7264 case 'l':
7265 {
cristyb988fe72009-09-16 01:01:10 +00007266 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007267 {
7268 (void) DeleteImageProperty(msl_info->image[n],"label");
7269 if (msl_info->content == (char *) NULL)
7270 break;
7271 StripString(msl_info->content);
7272 (void) SetImageProperty(msl_info->image[n],"label",
7273 msl_info->content);
7274 break;
7275 }
7276 break;
7277 }
7278 case 'M':
7279 case 'm':
7280 {
cristyb988fe72009-09-16 01:01:10 +00007281 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007282 {
7283 /*
7284 This our base element.
7285 at the moment we don't do anything special
7286 but someday we might!
7287 */
7288 }
7289 break;
7290 }
7291 default:
7292 break;
7293 }
7294 if (msl_info->content != (char *) NULL)
7295 msl_info->content=DestroyString(msl_info->content);
7296}
7297
7298static void MSLCharacters(void *context,const xmlChar *c,int length)
7299{
7300 MSLInfo
7301 *msl_info;
7302
7303 register char
7304 *p;
7305
cristybb503372010-05-27 20:51:26 +00007306 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007307 i;
7308
7309 /*
7310 Receiving some characters from the parser.
7311 */
7312 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7313 " SAX.characters(%s,%d)",c,length);
7314 msl_info=(MSLInfo *) context;
7315 if (msl_info->content != (char *) NULL)
7316 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7317 strlen(msl_info->content)+length+MaxTextExtent,
7318 sizeof(*msl_info->content));
7319 else
7320 {
7321 msl_info->content=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +00007322 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00007323 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7324 sizeof(*msl_info->content));
7325 if (msl_info->content != (char *) NULL)
7326 *msl_info->content='\0';
7327 }
7328 if (msl_info->content == (char *) NULL)
7329 return;
7330 p=msl_info->content+strlen(msl_info->content);
7331 for (i=0; i < length; i++)
7332 *p++=c[i];
7333 *p='\0';
7334}
7335
7336static void MSLReference(void *context,const xmlChar *name)
7337{
7338 MSLInfo
7339 *msl_info;
7340
7341 xmlParserCtxtPtr
7342 parser;
7343
7344 /*
7345 Called when an entity reference is detected.
7346 */
7347 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7348 " SAX.reference(%s)",name);
7349 msl_info=(MSLInfo *) context;
7350 parser=msl_info->parser;
7351 if (*name == '#')
7352 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7353 else
7354 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7355}
7356
7357static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7358{
7359 MSLInfo
7360 *msl_info;
7361
7362 /*
7363 Receiving some ignorable whitespaces from the parser.
7364 */
7365 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7366 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7367 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007368 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007369}
7370
7371static void MSLProcessingInstructions(void *context,const xmlChar *target,
7372 const xmlChar *data)
7373{
7374 MSLInfo
7375 *msl_info;
7376
7377 /*
7378 A processing instruction has been parsed.
7379 */
7380 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7381 " SAX.processingInstruction(%s, %s)",
7382 target,data);
7383 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007384 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007385}
7386
7387static void MSLComment(void *context,const xmlChar *value)
7388{
7389 MSLInfo
7390 *msl_info;
7391
7392 /*
7393 A comment has been parsed.
7394 */
7395 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7396 " SAX.comment(%s)",value);
7397 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007398 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007399}
7400
7401static void MSLWarning(void *context,const char *format,...)
7402{
7403 char
7404 *message,
7405 reason[MaxTextExtent];
7406
7407 MSLInfo
7408 *msl_info;
7409
7410 va_list
7411 operands;
7412
7413 /**
7414 Display and format a warning messages, gives file, line, position and
7415 extra parameters.
7416 */
7417 va_start(operands,format);
7418 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7419 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7420 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007421 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007422#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7423 (void) vsprintf(reason,format,operands);
7424#else
7425 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7426#endif
7427 message=GetExceptionMessage(errno);
7428 ThrowMSLException(CoderError,reason,message);
7429 message=DestroyString(message);
7430 va_end(operands);
7431}
7432
7433static void MSLError(void *context,const char *format,...)
7434{
7435 char
7436 reason[MaxTextExtent];
7437
7438 MSLInfo
7439 *msl_info;
7440
7441 va_list
7442 operands;
7443
7444 /*
7445 Display and format a error formats, gives file, line, position and
7446 extra parameters.
7447 */
7448 va_start(operands,format);
7449 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7450 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7451 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007452 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007453#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7454 (void) vsprintf(reason,format,operands);
7455#else
7456 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7457#endif
7458 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7459 va_end(operands);
7460}
7461
7462static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7463{
7464 MSLInfo
7465 *msl_info;
7466
7467 xmlNodePtr
7468 child;
7469
7470 xmlParserCtxtPtr
7471 parser;
7472
7473 /*
7474 Called when a pcdata block has been parsed.
7475 */
7476 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7477 " SAX.pcdata(%s, %d)",value,length);
7478 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007479 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007480 parser=msl_info->parser;
7481 child=xmlGetLastChild(parser->node);
7482 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7483 {
7484 xmlTextConcat(child,value,length);
7485 return;
7486 }
7487 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7488}
7489
7490static void MSLExternalSubset(void *context,const xmlChar *name,
7491 const xmlChar *external_id,const xmlChar *system_id)
7492{
7493 MSLInfo
7494 *msl_info;
7495
7496 xmlParserCtxt
7497 parser_context;
7498
7499 xmlParserCtxtPtr
7500 parser;
7501
7502 xmlParserInputPtr
7503 input;
7504
7505 /*
7506 Does this document has an external subset?
7507 */
7508 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7509 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007510 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7511 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007512 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007513 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007514 parser=msl_info->parser;
7515 if (((external_id == NULL) && (system_id == NULL)) ||
7516 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7517 (msl_info->document == 0)))
7518 return;
7519 input=MSLResolveEntity(context,external_id,system_id);
7520 if (input == NULL)
7521 return;
7522 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7523 parser_context=(*parser);
7524 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7525 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7526 {
7527 parser->errNo=XML_ERR_NO_MEMORY;
7528 parser->input=parser_context.input;
7529 parser->inputNr=parser_context.inputNr;
7530 parser->inputMax=parser_context.inputMax;
7531 parser->inputTab=parser_context.inputTab;
7532 return;
7533 }
7534 parser->inputNr=0;
7535 parser->inputMax=5;
7536 parser->input=NULL;
7537 xmlPushInput(parser,input);
7538 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7539 if (input->filename == (char *) NULL)
7540 input->filename=(char *) xmlStrdup(system_id);
7541 input->line=1;
7542 input->col=1;
7543 input->base=parser->input->cur;
7544 input->cur=parser->input->cur;
7545 input->free=NULL;
7546 xmlParseExternalSubset(parser,external_id,system_id);
7547 while (parser->inputNr > 1)
7548 (void) xmlPopInput(parser);
7549 xmlFreeInputStream(parser->input);
7550 xmlFree(parser->inputTab);
7551 parser->input=parser_context.input;
7552 parser->inputNr=parser_context.inputNr;
7553 parser->inputMax=parser_context.inputMax;
7554 parser->inputTab=parser_context.inputTab;
7555}
7556
7557#if defined(__cplusplus) || defined(c_plusplus)
7558}
7559#endif
7560
7561static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7562 ExceptionInfo *exception)
7563{
cristy3ed852e2009-09-05 21:47:34 +00007564 char
7565 message[MaxTextExtent];
7566
7567 Image
7568 *msl_image;
7569
7570 int
7571 status;
7572
cristybb503372010-05-27 20:51:26 +00007573 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007574 n;
7575
7576 MSLInfo
7577 msl_info;
7578
cristy5f6f01c2009-11-19 19:36:42 +00007579 xmlSAXHandler
7580 sax_modules;
7581
cristy3ed852e2009-09-05 21:47:34 +00007582 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007583 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007584
7585 /*
7586 Open image file.
7587 */
7588 assert(image_info != (const ImageInfo *) NULL);
7589 assert(image_info->signature == MagickSignature);
7590 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007591 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7592 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007593 assert(image != (Image **) NULL);
7594 msl_image=AcquireImage(image_info);
7595 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7596 if (status == MagickFalse)
7597 {
7598 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7599 msl_image->filename);
7600 msl_image=DestroyImageList(msl_image);
7601 return(MagickFalse);
7602 }
7603 msl_image->columns=1;
7604 msl_image->rows=1;
7605 /*
7606 Parse MSL file.
7607 */
7608 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7609 msl_info.exception=exception;
7610 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7611 sizeof(*msl_info.image_info));
7612 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7613 sizeof(*msl_info.draw_info));
7614 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007615 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007616 msl_info.attributes=(Image **) AcquireMagickMemory(
7617 sizeof(*msl_info.attributes));
7618 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7619 sizeof(*msl_info.group_info));
7620 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7621 (msl_info.image == (Image **) NULL) ||
7622 (msl_info.attributes == (Image **) NULL) ||
7623 (msl_info.group_info == (MSLGroupInfo *) NULL))
7624 ThrowFatalException(ResourceLimitFatalError,
7625 "UnableToInterpretMSLImage");
7626 *msl_info.image_info=CloneImageInfo(image_info);
7627 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7628 *msl_info.attributes=AcquireImage(image_info);
7629 msl_info.group_info[0].numImages=0;
7630 /* the first slot is used to point to the MSL file image */
7631 *msl_info.image=msl_image;
7632 if (*image != (Image *) NULL)
7633 MSLPushImage(&msl_info,*image);
7634 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007635 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7636 sax_modules.internalSubset=MSLInternalSubset;
7637 sax_modules.isStandalone=MSLIsStandalone;
7638 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7639 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7640 sax_modules.resolveEntity=MSLResolveEntity;
7641 sax_modules.getEntity=MSLGetEntity;
7642 sax_modules.entityDecl=MSLEntityDeclaration;
7643 sax_modules.notationDecl=MSLNotationDeclaration;
7644 sax_modules.attributeDecl=MSLAttributeDeclaration;
7645 sax_modules.elementDecl=MSLElementDeclaration;
7646 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7647 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7648 sax_modules.startDocument=MSLStartDocument;
7649 sax_modules.endDocument=MSLEndDocument;
7650 sax_modules.startElement=MSLStartElement;
7651 sax_modules.endElement=MSLEndElement;
7652 sax_modules.reference=MSLReference;
7653 sax_modules.characters=MSLCharacters;
7654 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7655 sax_modules.processingInstruction=MSLProcessingInstructions;
7656 sax_modules.comment=MSLComment;
7657 sax_modules.warning=MSLWarning;
7658 sax_modules.error=MSLError;
7659 sax_modules.fatalError=MSLError;
7660 sax_modules.getParameterEntity=MSLGetParameterEntity;
7661 sax_modules.cdataBlock=MSLCDataBlock;
7662 sax_modules.externalSubset=MSLExternalSubset;
7663 sax_handler=(&sax_modules);
7664 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007665 msl_image->filename);
7666 while (ReadBlobString(msl_image,message) != (char *) NULL)
7667 {
cristybb503372010-05-27 20:51:26 +00007668 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007669 if (n == 0)
7670 continue;
7671 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7672 if (status != 0)
7673 break;
7674 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7675 if (msl_info.exception->severity >= ErrorException)
7676 break;
7677 }
7678 if (msl_info.exception->severity == UndefinedException)
7679 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7680 xmlFreeParserCtxt(msl_info.parser);
7681 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7682 xmlCleanupParser();
7683 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7684 msl_info.group_info);
7685 if (*image == (Image *) NULL)
7686 *image=(*msl_info.image);
cristy5f6f01c2009-11-19 19:36:42 +00007687 if ((*msl_info.image)->exception.severity != UndefinedException)
7688 return(MagickFalse);
7689 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007690}
7691
7692static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7693{
7694 Image
7695 *image;
7696
7697 /*
7698 Open image file.
7699 */
7700 assert(image_info != (const ImageInfo *) NULL);
7701 assert(image_info->signature == MagickSignature);
7702 if (image_info->debug != MagickFalse)
7703 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7704 image_info->filename);
7705 assert(exception != (ExceptionInfo *) NULL);
7706 assert(exception->signature == MagickSignature);
7707 image=(Image *) NULL;
7708 (void) ProcessMSLScript(image_info,&image,exception);
7709 return(GetFirstImageInList(image));
7710}
7711#endif
7712
7713/*
7714%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7715% %
7716% %
7717% %
7718% R e g i s t e r M S L I m a g e %
7719% %
7720% %
7721% %
7722%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7723%
7724% RegisterMSLImage() adds attributes for the MSL image format to
7725% the list of supported formats. The attributes include the image format
7726% tag, a method to read and/or write the format, whether the format
7727% supports the saving of more than one frame to the same file or blob,
7728% whether the format supports native in-memory I/O, and a brief
7729% description of the format.
7730%
7731% The format of the RegisterMSLImage method is:
7732%
cristybb503372010-05-27 20:51:26 +00007733% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007734%
7735*/
cristybb503372010-05-27 20:51:26 +00007736ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007737{
7738 MagickInfo
7739 *entry;
7740
7741 entry=SetMagickInfo("MSL");
7742#if defined(MAGICKCORE_XML_DELEGATE)
7743 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7744 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7745#endif
7746 entry->description=ConstantString("Magick Scripting Language");
7747 entry->module=ConstantString("MSL");
7748 (void) RegisterMagickInfo(entry);
7749 return(MagickImageCoderSignature);
7750}
7751
cristy6b9f7ed2010-04-24 01:08:02 +00007752#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007753/*
7754%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7755% %
7756% %
7757% %
cristyb988fe72009-09-16 01:01:10 +00007758% S e t M S L A t t r i b u t e s %
7759% %
7760% %
7761% %
7762%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7763%
7764% SetMSLAttributes() ...
7765%
7766% The format of the SetMSLAttributes method is:
7767%
7768% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007769% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007770%
7771% A description of each parameter follows:
7772%
7773% o msl_info: the MSL info.
7774%
cristyb20775d2009-09-16 01:51:41 +00007775% o keyword: the keyword.
7776%
7777% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007778%
7779*/
cristyb20775d2009-09-16 01:51:41 +00007780static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7781 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007782{
cristy4582cbb2009-09-23 00:35:43 +00007783 Image
7784 *attributes;
7785
cristyb20775d2009-09-16 01:51:41 +00007786 DrawInfo
7787 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007788
7789 ExceptionInfo
7790 *exception;
7791
cristy4582cbb2009-09-23 00:35:43 +00007792 GeometryInfo
7793 geometry_info;
7794
cristy4fa36e42009-09-18 14:24:06 +00007795 Image
7796 *image;
7797
cristyb20775d2009-09-16 01:51:41 +00007798 ImageInfo
7799 *image_info;
7800
cristy4582cbb2009-09-23 00:35:43 +00007801 int
7802 flags;
7803
cristybb503372010-05-27 20:51:26 +00007804 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007805 n;
7806
cristyb988fe72009-09-16 01:01:10 +00007807 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007808 if (keyword == (const char *) NULL)
7809 return(MagickTrue);
7810 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007811 return(MagickTrue);
7812 exception=msl_info->exception;
7813 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007814 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007815 image_info=msl_info->image_info[n];
7816 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007817 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007818 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007819 {
cristyfb758a52009-09-16 14:36:08 +00007820 case 'A':
7821 case 'a':
7822 {
7823 if (LocaleCompare(keyword,"adjoin") == 0)
7824 {
cristybb503372010-05-27 20:51:26 +00007825 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007826 adjoin;
7827
cristy042ee782011-04-22 18:48:30 +00007828 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007829 if (adjoin < 0)
7830 ThrowMSLException(OptionError,"UnrecognizedType",value);
7831 image_info->adjoin=(MagickBooleanType) adjoin;
7832 break;
7833 }
cristy4fa36e42009-09-18 14:24:06 +00007834 if (LocaleCompare(keyword,"alpha") == 0)
7835 {
cristybb503372010-05-27 20:51:26 +00007836 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007837 alpha;
7838
cristy042ee782011-04-22 18:48:30 +00007839 alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007840 if (alpha < 0)
7841 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007842 if (image != (Image *) NULL)
7843 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha);
7844 break;
7845 }
7846 if (LocaleCompare(keyword,"antialias") == 0)
7847 {
cristybb503372010-05-27 20:51:26 +00007848 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007849 antialias;
7850
cristy042ee782011-04-22 18:48:30 +00007851 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007852 if (antialias < 0)
7853 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7854 image_info->antialias=(MagickBooleanType) antialias;
7855 break;
7856 }
7857 if (LocaleCompare(keyword,"area-limit") == 0)
7858 {
7859 MagickSizeType
7860 limit;
7861
7862 limit=MagickResourceInfinity;
7863 if (LocaleCompare(value,"unlimited") != 0)
cristyf2f27272009-12-17 14:48:46 +00007864 limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007865 (void) SetMagickResourceLimit(AreaResource,limit);
7866 break;
7867 }
7868 if (LocaleCompare(keyword,"attenuate") == 0)
7869 {
7870 (void) SetImageOption(image_info,keyword,value);
7871 break;
7872 }
7873 if (LocaleCompare(keyword,"authenticate") == 0)
7874 {
7875 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007876 break;
7877 }
cristyfb758a52009-09-16 14:36:08 +00007878 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7879 break;
7880 }
cristyb20775d2009-09-16 01:51:41 +00007881 case 'B':
7882 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007883 {
cristyb20775d2009-09-16 01:51:41 +00007884 if (LocaleCompare(keyword,"background") == 0)
7885 {
cristy2c8b6312009-09-16 02:37:23 +00007886 (void) QueryColorDatabase(value,&image_info->background_color,
cristyb20775d2009-09-16 01:51:41 +00007887 exception);
7888 break;
7889 }
cristy4582cbb2009-09-23 00:35:43 +00007890 if (LocaleCompare(keyword,"bias") == 0)
7891 {
7892 if (image == (Image *) NULL)
7893 break;
cristyf2f27272009-12-17 14:48:46 +00007894 image->bias=SiPrefixToDouble(value,QuantumRange);
cristy4582cbb2009-09-23 00:35:43 +00007895 break;
7896 }
7897 if (LocaleCompare(keyword,"blue-primary") == 0)
7898 {
7899 if (image == (Image *) NULL)
7900 break;
7901 flags=ParseGeometry(value,&geometry_info);
7902 image->chromaticity.blue_primary.x=geometry_info.rho;
7903 image->chromaticity.blue_primary.y=geometry_info.sigma;
7904 if ((flags & SigmaValue) == 0)
7905 image->chromaticity.blue_primary.y=
7906 image->chromaticity.blue_primary.x;
7907 break;
7908 }
cristy2c8b6312009-09-16 02:37:23 +00007909 if (LocaleCompare(keyword,"bordercolor") == 0)
7910 {
7911 (void) QueryColorDatabase(value,&image_info->border_color,
7912 exception);
7913 break;
7914 }
7915 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7916 break;
7917 }
7918 case 'D':
7919 case 'd':
7920 {
7921 if (LocaleCompare(keyword,"density") == 0)
7922 {
7923 (void) CloneString(&image_info->density,value);
7924 (void) CloneString(&draw_info->density,value);
7925 break;
7926 }
cristyb20775d2009-09-16 01:51:41 +00007927 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7928 break;
7929 }
7930 case 'F':
7931 case 'f':
7932 {
7933 if (LocaleCompare(keyword,"fill") == 0)
7934 {
cristy2c8b6312009-09-16 02:37:23 +00007935 (void) QueryColorDatabase(value,&draw_info->fill,exception);
cristya30afaf2009-09-22 13:42:12 +00007936 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00007937 break;
7938 }
cristy4582cbb2009-09-23 00:35:43 +00007939 if (LocaleCompare(keyword,"filename") == 0)
7940 {
7941 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7942 break;
7943 }
7944 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7945 break;
7946 }
7947 case 'G':
7948 case 'g':
7949 {
7950 if (LocaleCompare(keyword,"gravity") == 0)
7951 {
cristybb503372010-05-27 20:51:26 +00007952 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007953 gravity;
7954
cristy042ee782011-04-22 18:48:30 +00007955 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007956 if (gravity < 0)
7957 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7958 (void) SetImageOption(image_info,keyword,value);
7959 break;
7960 }
cristyb20775d2009-09-16 01:51:41 +00007961 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7962 break;
7963 }
7964 case 'I':
7965 case 'i':
7966 {
7967 if (LocaleCompare(keyword,"id") == 0)
7968 {
cristy4582cbb2009-09-23 00:35:43 +00007969 (void) SetImageProperty(attributes,keyword,value);
cristy2c8b6312009-09-16 02:37:23 +00007970 break;
7971 }
7972 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7973 break;
7974 }
7975 case 'M':
7976 case 'm':
7977 {
7978 if (LocaleCompare(keyword,"magick") == 0)
7979 {
7980 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
7981 break;
7982 }
cristy2c8b6312009-09-16 02:37:23 +00007983 if (LocaleCompare(keyword,"mattecolor") == 0)
7984 {
7985 (void) QueryColorDatabase(value,&image_info->matte_color,
7986 exception);
cristyb20775d2009-09-16 01:51:41 +00007987 break;
7988 }
7989 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7990 break;
7991 }
7992 case 'P':
7993 case 'p':
7994 {
7995 if (LocaleCompare(keyword,"pointsize") == 0)
7996 {
cristyc1acd842011-05-19 23:05:47 +00007997 image_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
7998 draw_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
cristyb20775d2009-09-16 01:51:41 +00007999 break;
8000 }
8001 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8002 break;
8003 }
cristy4582cbb2009-09-23 00:35:43 +00008004 case 'Q':
8005 case 'q':
8006 {
8007 if (LocaleCompare(keyword,"quality") == 0)
8008 {
cristyf2f27272009-12-17 14:48:46 +00008009 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008010 if (image == (Image *) NULL)
8011 break;
cristyf2f27272009-12-17 14:48:46 +00008012 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008013 break;
8014 }
8015 break;
8016 }
cristyb20775d2009-09-16 01:51:41 +00008017 case 'S':
8018 case 's':
8019 {
8020 if (LocaleCompare(keyword,"size") == 0)
8021 {
cristy2c8b6312009-09-16 02:37:23 +00008022 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008023 break;
8024 }
8025 if (LocaleCompare(keyword,"stroke") == 0)
8026 {
cristy2c8b6312009-09-16 02:37:23 +00008027 (void) QueryColorDatabase(value,&draw_info->stroke,exception);
cristya30afaf2009-09-22 13:42:12 +00008028 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008029 break;
8030 }
8031 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8032 break;
8033 }
8034 default:
8035 {
8036 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8037 break;
cristyb988fe72009-09-16 01:01:10 +00008038 }
8039 }
8040 return(MagickTrue);
8041}
cristy6b9f7ed2010-04-24 01:08:02 +00008042#endif
cristyb988fe72009-09-16 01:01:10 +00008043
8044/*
8045%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8046% %
8047% %
8048% %
cristy3ed852e2009-09-05 21:47:34 +00008049% U n r e g i s t e r M S L I m a g e %
8050% %
8051% %
8052% %
8053%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8054%
8055% UnregisterMSLImage() removes format registrations made by the
8056% MSL module from the list of supported formats.
8057%
8058% The format of the UnregisterMSLImage method is:
8059%
8060% UnregisterMSLImage(void)
8061%
8062*/
8063ModuleExport void UnregisterMSLImage(void)
8064{
8065 (void) UnregisterMagickInfo("MSL");
8066}
8067
8068#if defined(MAGICKCORE_XML_DELEGATE)
8069/*
8070%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8071% %
8072% %
8073% %
8074% W r i t e M S L I m a g e %
8075% %
8076% %
8077% %
8078%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8079%
8080% WriteMSLImage() writes an image to a file in MVG image format.
8081%
8082% The format of the WriteMSLImage method is:
8083%
8084% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8085%
8086% A description of each parameter follows.
8087%
8088% o image_info: the image info.
8089%
8090% o image: The image.
8091%
8092*/
8093static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8094{
8095 assert(image_info != (const ImageInfo *) NULL);
8096 assert(image_info->signature == MagickSignature);
8097 assert(image != (Image *) NULL);
8098 assert(image->signature == MagickSignature);
8099 if (image->debug != MagickFalse)
8100 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8101 (void) ReferenceImage(image);
8102 (void) ProcessMSLScript(image_info,&image,&image->exception);
8103 return(MagickTrue);
8104}
8105#endif