blob: 078a0b49be348fe137629b445398fa862b1c277f [file] [log] [blame]
anthony805a2d42011-09-25 08:25:12 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% OOO PPPP EEEE RRRR AA TTTTTT III OOO N N %
7% O O P P E R R A A TT I O O NN N %
8% O O PPPP EEE RRRR AAAA TT I O O N N N %
9% O O P E R R A A TT I O O N NN %
10% OOO P EEEE R RR A A TT III OOO N N %
11% %
12% %
13% MagickWand Module Methods %
14% %
15% Software Design %
16% John Cristy %
cristy0a0ca4f2011-09-28 01:15:28 +000017% September 2011 %
anthony805a2d42011-09-25 08:25:12 +000018% %
19% %
20% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% Apply the given options (settings, and simple, or sequence operations) to
37% the given image(s) according to the current "image_info" and "draw_info"
38% settings.
39%
40% The final goal is to allow the execution in a strict one option at a time
41% manner that is needed for 'pipelining and file scripting' of options in
42% IMv7.
43%
44% Anthony Thyssen, Sept 2011
45*/
cristy0a0ca4f2011-09-28 01:15:28 +000046#if 0
anthony805a2d42011-09-25 08:25:12 +000047
48/*
49 Include declarations.
50*/
51#include "MagickWand/studio.h"
52#include "MagickWand/MagickWand.h"
53#include "MagickWand/mogrify-private.h"
54#include "MagickCore/monitor-private.h"
55#include "MagickCore/thread-private.h"
56#include "MagickCore/string-private.h"
57
58/*
59 Define declarations.
60*/
61#define UndefinedCompressionQuality 0UL
62/*
63 Constant declaration. (temporary exports)
64*/
65static const char
66 BackgroundColor[] = "#fff", /* white */
67 BorderColor[] = "#dfdfdf", /* gray */
68 MatteColor[] = "#bdbdbd"; /* gray */
69
70/*
71** Function to report on the progress of image operations
72*/
73static MagickBooleanType MonitorProgress(const char *text,
74 const MagickOffsetType offset,const MagickSizeType extent,
75 void *wand_unused(client_data))
76{
77 char
78 message[MaxTextExtent],
79 tag[MaxTextExtent];
80
81 const char
82 *locale_message;
83
84 register char
85 *p;
86
87 if (extent < 2)
88 return(MagickTrue);
89 (void) CopyMagickMemory(tag,text,MaxTextExtent);
90 p=strrchr(tag,'/');
91 if (p != (char *) NULL)
92 *p='\0';
93 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
94 locale_message=GetLocaleMessage(message);
95 if (locale_message == message)
96 locale_message=tag;
97 if (p == (char *) NULL)
98 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
99 locale_message,(long) offset,(unsigned long) extent,(long)
100 (100L*offset/(extent-1)));
101 else
102 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
103 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
104 (100L*offset/(extent-1)));
105 if (offset == (MagickOffsetType) (extent-1))
106 (void) FormatLocaleFile(stderr,"\n");
107 (void) fflush(stderr);
108 return(MagickTrue);
109}
110
111/*
112** GetImageCache() will read an image into a image cache if not already
113** present then return the image that is in the cache under that filename.
114*/
115static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
116 ExceptionInfo *exception)
117{
118 char
119 key[MaxTextExtent];
120
121 ExceptionInfo
122 *sans_exception;
123
124 Image
125 *image;
126
127 ImageInfo
128 *read_info;
129
130 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
131 sans_exception=AcquireExceptionInfo();
132 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
133 sans_exception=DestroyExceptionInfo(sans_exception);
134 if (image != (Image *) NULL)
135 return(image);
136 read_info=CloneImageInfo(image_info);
137 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
138 image=ReadImage(read_info,exception);
139 read_info=DestroyImageInfo(read_info);
140 if (image != (Image *) NULL)
141 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
142 return(image);
143}
144
145/*
146** SparseColorOption() parse the complex -sparse-color argument into an
147** an array of floating point values than call SparseColorImage().
148** Argument is a complex mix of floating-point pixel coodinates, and color
149** specifications (or direct floating point numbers). The number of floats
150** needed to represent a color varies depending on teh current channel
151** setting.
152*/
153static Image *SparseColorOption(const Image *image,
154 const SparseColorMethod method,const char *arguments,
155 const MagickBooleanType color_from_image,ExceptionInfo *exception)
156{
157 char
158 token[MaxTextExtent];
159
160 const char
161 *p;
162
163 double
164 *sparse_arguments;
165
166 Image
167 *sparse_image;
168
169 PixelInfo
170 color;
171
172 MagickBooleanType
173 error;
174
175 register size_t
176 x;
177
178 size_t
179 number_arguments,
180 number_colors;
181
182 assert(image != (Image *) NULL);
183 assert(image->signature == MagickSignature);
184 if (image->debug != MagickFalse)
185 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
186 assert(exception != (ExceptionInfo *) NULL);
187 assert(exception->signature == MagickSignature);
188 /*
189 Limit channels according to image - and add up number of color channel.
190 */
191 number_colors=0;
192 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
193 number_colors++;
194 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
195 number_colors++;
196 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
197 number_colors++;
198 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
199 (image->colorspace == CMYKColorspace))
200 number_colors++;
201 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
202 (image->matte != MagickFalse))
203 number_colors++;
204
205 /*
206 Read string, to determine number of arguments needed,
207 */
208 p=arguments;
209 x=0;
210 while( *p != '\0' )
211 {
212 GetMagickToken(p,&p,token);
213 if ( token[0] == ',' ) continue;
214 if ( isalpha((int) token[0]) || token[0] == '#' ) {
215 if ( color_from_image ) {
216 (void) ThrowMagickException(exception,GetMagickModule(),
217 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
218 "Color arg given, when colors are coming from image");
219 return( (Image *)NULL);
220 }
221 x += number_colors; /* color argument */
222 }
223 else {
224 x++; /* floating point argument */
225 }
226 }
227 error=MagickTrue;
228 if ( color_from_image ) {
229 /* just the control points are being given */
230 error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse;
231 number_arguments=(x/2)*(2+number_colors);
232 }
233 else {
234 /* control points and color values */
235 error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
236 number_arguments=x;
237 }
238 if ( error ) {
239 (void) ThrowMagickException(exception,GetMagickModule(),
240 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
241 "Invalid number of Arguments");
242 return( (Image *)NULL);
243 }
244
245 /* Allocate and fill in the floating point arguments */
246 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
247 sizeof(*sparse_arguments));
248 if (sparse_arguments == (double *) NULL) {
249 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
250 "MemoryAllocationFailed","%s","SparseColorOption");
251 return( (Image *)NULL);
252 }
253 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
254 sizeof(*sparse_arguments));
255 p=arguments;
256 x=0;
257 while( *p != '\0' && x < number_arguments ) {
258 /* X coordinate */
259 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
260 if ( token[0] == '\0' ) break;
261 if ( isalpha((int) token[0]) || token[0] == '#' ) {
262 (void) ThrowMagickException(exception,GetMagickModule(),
263 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
264 "Color found, instead of X-coord");
265 error = MagickTrue;
266 break;
267 }
268 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
269 /* Y coordinate */
270 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
271 if ( token[0] == '\0' ) break;
272 if ( isalpha((int) token[0]) || token[0] == '#' ) {
273 (void) ThrowMagickException(exception,GetMagickModule(),
274 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
275 "Color found, instead of Y-coord");
276 error = MagickTrue;
277 break;
278 }
279 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
280 /* color values for this control point */
281#if 0
282 if ( (color_from_image ) {
283 /* get color from image */
284 /* HOW??? */
285 }
286 else
287#endif
288 {
289 /* color name or function given in string argument */
290 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
291 if ( token[0] == '\0' ) break;
292 if ( isalpha((int) token[0]) || token[0] == '#' ) {
293 /* Color string given */
294 (void) QueryMagickColor(token,&color,exception);
295 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
296 sparse_arguments[x++] = QuantumScale*color.red;
297 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
298 sparse_arguments[x++] = QuantumScale*color.green;
299 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
300 sparse_arguments[x++] = QuantumScale*color.blue;
301 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
302 (image->colorspace == CMYKColorspace))
303 sparse_arguments[x++] = QuantumScale*color.black;
304 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
305 (image->matte != MagickFalse))
306 sparse_arguments[x++] = QuantumScale*color.alpha;
307 }
308 else {
309 /* Colors given as a set of floating point values - experimental */
310 /* NB: token contains the first floating point value to use! */
311 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
312 {
313 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
314 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
315 break;
316 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
317 token[0] = ','; /* used this token - get another */
318 }
319 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
320 {
321 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
322 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
323 break;
324 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
325 token[0] = ','; /* used this token - get another */
326 }
327 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
328 {
329 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
330 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
331 break;
332 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
333 token[0] = ','; /* used this token - get another */
334 }
335 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
336 (image->colorspace == CMYKColorspace))
337 {
338 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
339 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
340 break;
341 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
342 token[0] = ','; /* used this token - get another */
343 }
344 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
345 (image->matte != MagickFalse))
346 {
347 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
348 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
349 break;
350 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
351 token[0] = ','; /* used this token - get another */
352 }
353 }
354 }
355 }
356 if ( number_arguments != x && !error ) {
357 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
358 "InvalidArgument","`%s': %s","sparse-color","Argument Parsing Error");
359 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
360 return( (Image *)NULL);
361 }
362 if ( error )
363 return( (Image *)NULL);
364
365 /* Call the Interpolation function with the parsed arguments */
366 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
367 exception);
368 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
369 return( sparse_image );
370}
371
372/*
373%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374% %
375% %
376% %
377+ S e t t i n g s O p t i o n I n f o %
378% %
379% %
380% %
381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382%
383% SettingsOptionInfo() saves the given single settings argv[0] into a
384% ImageInfo structure for later use by various image processing operations.
385%
386% The format of the SettingsOptionInfo method is:
387%
388% MagickBooleanType SettingsOptionInfo(ImageInfo *image_info,
389% const int argc, const char **argv,ExceptionInfo *exception)
390%
391% A description of each parameter follows:
392%
393% o image_info: the image info..
394%
395% o argc: Specifies a pointer to an integer describing the number of
396% elements in the argument vector.
397%
398% o argv: Specifies a pointer to a text array containing the command line
399% arguments.
400%
401% o exception: return any errors or warnings in this structure.
402%
403*/
404WandExport MagickBooleanType SettingsOptionInfo(ImageInfo *image_info,
cristy0a0ca4f2011-09-28 01:15:28 +0000405 const int argc,const char **argv,ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000406{
407 GeometryInfo
408 geometry_info;
409
410 /*
411 Initialize method variables.
412 */
413 assert(image_info != (ImageInfo *) NULL);
414 assert(image_info->signature == MagickSignature);
415 if (image_info->debug != MagickFalse)
416 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
417 image_info->filename);
418 if (argc < 0)
419 return(MagickTrue);
420 /*
421 Set the image settings for one image.
422 */
423 switch (*(argv[0]+1))
424 {
425 case 'a':
426 {
427 if (LocaleCompare("adjoin",argv[0]+1) == 0)
428 {
429 image_info->adjoin=(*argv[0] == '-') ? MagickTrue : MagickFalse;
430 break;
431 }
432 if (LocaleCompare("antialias",argv[0]+1) == 0)
433 {
434 image_info->antialias=(*argv[0] == '-') ? MagickTrue : MagickFalse;
435 break;
436 }
437 if (LocaleCompare("attenuate",argv[0]+1) == 0)
438 {
439 if (*argv[0] == '+')
440 {
441 (void) DeleteImageOption(image_info,argv[0]+1);
442 break;
443 }
444 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
445 break;
446 }
447 if (LocaleCompare("authenticate",argv[0]+1) == 0)
448 {
449 if (*argv[0] == '+')
450 (void) CloneString(&image_info->authenticate,(char *) NULL);
451 else
452 (void) CloneString(&image_info->authenticate,argv[1]);
453 break;
454 }
455 break;
456 }
457 case 'b':
458 {
459 if (LocaleCompare("background",argv[0]+1) == 0)
460 {
461 if (*argv[0] == '+')
462 {
463 (void) DeleteImageOption(image_info,argv[0]+1);
464 (void) QueryColorDatabase(BackgroundColor,
465 &image_info->background_color,exception);
466 break;
467 }
468 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
469 (void) QueryColorDatabase(argv[1],&image_info->background_color,
470 exception);
471 break;
472 }
473 if (LocaleCompare("bias",argv[0]+1) == 0)
474 {
475 if (*argv[0] == '+')
476 {
477 (void) SetImageOption(image_info,argv[0]+1,"0.0");
478 break;
479 }
480 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
481 break;
482 }
483 if (LocaleCompare("black-point-compensation",argv[0]+1) == 0)
484 {
485 if (*argv[0] == '+')
486 {
487 (void) SetImageOption(image_info,argv[0]+1,"false");
488 break;
489 }
490 (void) SetImageOption(image_info,argv[0]+1,"true");
491 break;
492 }
493 if (LocaleCompare("blue-primary",argv[0]+1) == 0)
494 {
495 if (*argv[0] == '+')
496 {
497 (void) SetImageOption(image_info,argv[0]+1,"0.0");
498 break;
499 }
500 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
501 break;
502 }
503 if (LocaleCompare("bordercolor",argv[0]+1) == 0)
504 {
505 if (*argv[0] == '+')
506 {
507 (void) DeleteImageOption(image_info,argv[0]+1);
508 (void) QueryColorDatabase(BorderColor,&image_info->border_color,
509 exception);
510 break;
511 }
512 (void) QueryColorDatabase(argv[1],&image_info->border_color,
513 exception);
514 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
515 break;
516 }
517 if (LocaleCompare("box",argv[0]+1) == 0)
518 {
519 if (*argv[0] == '+')
520 {
521 (void) SetImageOption(image_info,"undercolor","none");
522 break;
523 }
524 (void) SetImageOption(image_info,"undercolor",argv[1]);
525 break;
526 }
527 break;
528 }
529 case 'c':
530 {
531 if (LocaleCompare("cache",argv[0]+1) == 0)
532 {
533 MagickSizeType
534 limit;
535
536 limit=MagickResourceInfinity;
537 if (LocaleCompare("unlimited",argv[1]) != 0)
538 limit=(MagickSizeType) SiPrefixToDouble(argv[1],100.0);
539 (void) SetMagickResourceLimit(MemoryResource,limit);
540 (void) SetMagickResourceLimit(MapResource,2*limit);
541 break;
542 }
543 if (LocaleCompare("caption",argv[0]+1) == 0)
544 {
545 if (*argv[0] == '+')
546 {
547 (void) DeleteImageOption(image_info,argv[0]+1);
548 break;
549 }
550 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
551 break;
552 }
553 if (LocaleCompare("channel",argv[0]+1) == 0)
554 {
555 if (*argv[0] == '+')
556 {
557 image_info->channel=DefaultChannels;
558 break;
559 }
560 image_info->channel=(ChannelType) ParseChannelOption(argv[1]);
561 break;
562 }
563 if (LocaleCompare("colors",argv[0]+1) == 0)
564 {
565 image_info->colors=StringToUnsignedLong(argv[1]);
566 break;
567 }
568 if (LocaleCompare("colorspace",argv[0]+1) == 0)
569 {
570 if (*argv[0] == '+')
571 {
572 image_info->colorspace=UndefinedColorspace;
573 (void) SetImageOption(image_info,argv[0]+1,"undefined");
574 break;
575 }
576 image_info->colorspace=(ColorspaceType) ParseCommandOption(
577 MagickColorspaceOptions,MagickFalse,argv[1]);
578 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
579 break;
580 }
581 if (LocaleCompare("comment",argv[0]+1) == 0)
582 {
583 if (*argv[0] == '+')
584 {
585 (void) DeleteImageOption(image_info,argv[0]+1);
586 break;
587 }
588 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
589 break;
590 }
591 if (LocaleCompare("compose",argv[0]+1) == 0)
592 {
593 if (*argv[0] == '+')
594 {
595 (void) SetImageOption(image_info,argv[0]+1,"undefined");
596 break;
597 }
598 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
599 break;
600 }
601 if (LocaleCompare("compress",argv[0]+1) == 0)
602 {
603 if (*argv[0] == '+')
604 {
605 image_info->compression=UndefinedCompression;
606 (void) SetImageOption(image_info,argv[0]+1,"undefined");
607 break;
608 }
609 image_info->compression=(CompressionType) ParseCommandOption(
610 MagickCompressOptions,MagickFalse,argv[1]);
611 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
612 break;
613 }
614 break;
615 }
616 case 'd':
617 {
618 if (LocaleCompare("debug",argv[0]+1) == 0)
619 {
620 if (*argv[0] == '+')
621 (void) SetLogEventMask("none");
622 else
623 (void) SetLogEventMask(argv[1]);
624 image_info->debug=IsEventLogging();
625 break;
626 }
627 if (LocaleCompare("define",argv[0]+1) == 0)
628 {
629 if (*argv[0] == '+')
630 {
631 if (LocaleNCompare(argv[1],"registry:",9) == 0)
632 (void) DeleteImageRegistry(argv[1]+9);
633 else
634 (void) DeleteImageOption(image_info,argv[1]);
635 break;
636 }
637 if (LocaleNCompare(argv[1],"registry:",9) == 0)
638 {
639 (void) DefineImageRegistry(StringRegistryType,argv[1]+9,
640 exception);
641 break;
642 }
643 (void) DefineImageOption(image_info,argv[1]);
644 break;
645 }
646 if (LocaleCompare("delay",argv[0]+1) == 0)
647 {
648 if (*argv[0] == '+')
649 {
650 (void) SetImageOption(image_info,argv[0]+1,"0");
651 break;
652 }
653 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
654 break;
655 }
656 if (LocaleCompare("density",argv[0]+1) == 0)
657 {
658 /*
659 Set image density.
660 */
661 if (*argv[0] == '+')
662 {
663 if (image_info->density != (char *) NULL)
664 image_info->density=DestroyString(image_info->density);
665 (void) SetImageOption(image_info,argv[0]+1,"72");
666 break;
667 }
668 (void) CloneString(&image_info->density,argv[1]);
669 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
670 break;
671 }
672 if (LocaleCompare("depth",argv[0]+1) == 0)
673 {
674 if (*argv[0] == '+')
675 {
676 image_info->depth=MAGICKCORE_QUANTUM_DEPTH;
677 break;
678 }
679 image_info->depth=StringToUnsignedLong(argv[1]);
680 break;
681 }
682 if (LocaleCompare("direction",argv[0]+1) == 0)
683 {
684 if (*argv[0] == '+')
685 {
686 (void) SetImageOption(image_info,argv[0]+1,"undefined");
687 break;
688 }
689 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
690 break;
691 }
692 if (LocaleCompare("display",argv[0]+1) == 0)
693 {
694 if (*argv[0] == '+')
695 {
696 if (image_info->server_name != (char *) NULL)
697 image_info->server_name=DestroyString(
698 image_info->server_name);
699 break;
700 }
701 (void) CloneString(&image_info->server_name,argv[1]);
702 break;
703 }
704 if (LocaleCompare("dispose",argv[0]+1) == 0)
705 {
706 if (*argv[0] == '+')
707 {
708 (void) SetImageOption(image_info,argv[0]+1,"undefined");
709 break;
710 }
711 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
712 break;
713 }
714 if (LocaleCompare("dither",argv[0]+1) == 0)
715 {
716 if (*argv[0] == '+')
717 {
718 image_info->dither=MagickFalse;
719 (void) SetImageOption(image_info,argv[0]+1,"none");
720 break;
721 }
722 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
723 image_info->dither=MagickTrue;
724 break;
725 }
726 break;
727 }
728 case 'e':
729 {
730 if (LocaleCompare("encoding",argv[0]+1) == 0)
731 {
732 if (*argv[0] == '+')
733 {
734 (void) SetImageOption(image_info,argv[0]+1,"undefined");
735 break;
736 }
737 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
738 break;
739 }
740 if (LocaleCompare("endian",argv[0]+1) == 0)
741 {
742 if (*argv[0] == '+')
743 {
744 image_info->endian=UndefinedEndian;
745 (void) SetImageOption(image_info,argv[0]+1,"undefined");
746 break;
747 }
748 image_info->endian=(EndianType) ParseCommandOption(
749 MagickEndianOptions,MagickFalse,argv[1]);
750 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
751 break;
752 }
753 if (LocaleCompare("extract",argv[0]+1) == 0)
754 {
755 /*
756 Set image extract geometry.
757 */
758 if (*argv[0] == '+')
759 {
760 if (image_info->extract != (char *) NULL)
761 image_info->extract=DestroyString(image_info->extract);
762 break;
763 }
764 (void) CloneString(&image_info->extract,argv[1]);
765 break;
766 }
767 break;
768 }
769 case 'f':
770 {
771 if (LocaleCompare("fill",argv[0]+1) == 0)
772 {
773 if (*argv[0] == '+')
774 {
775 (void) SetImageOption(image_info,argv[0]+1,"none");
776 break;
777 }
778 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
779 break;
780 }
781 if (LocaleCompare("filter",argv[0]+1) == 0)
782 {
783 if (*argv[0] == '+')
784 {
785 (void) SetImageOption(image_info,argv[0]+1,"undefined");
786 break;
787 }
788 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
789 break;
790 }
791 if (LocaleCompare("font",argv[0]+1) == 0)
792 {
793 if (*argv[0] == '+')
794 {
795 if (image_info->font != (char *) NULL)
796 image_info->font=DestroyString(image_info->font);
797 break;
798 }
799 (void) CloneString(&image_info->font,argv[1]);
800 break;
801 }
802 if (LocaleCompare("format",argv[0]+1) == 0)
803 {
804 register const char
805 *q;
806
807 for (q=strchr(argv[1],'%'); q != (char *) NULL; q=strchr(q+1,'%'))
808 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
809 image_info->ping=MagickFalse;
810 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
811 break;
812 }
813 if (LocaleCompare("fuzz",argv[0]+1) == 0)
814 {
815 if (*argv[0] == '+')
816 {
817 image_info->fuzz=0.0;
818 (void) SetImageOption(image_info,argv[0]+1,"0");
819 break;
820 }
821 image_info->fuzz=SiPrefixToDouble(argv[1],(double) QuantumRange+
822 1.0);
823 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
824 break;
825 }
826 break;
827 }
828 case 'g':
829 {
830 if (LocaleCompare("gravity",argv[0]+1) == 0)
831 {
832 if (*argv[0] == '+')
833 {
834 (void) SetImageOption(image_info,argv[0]+1,"undefined");
835 break;
836 }
837 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
838 break;
839 }
840 if (LocaleCompare("green-primary",argv[0]+1) == 0)
841 {
842 if (*argv[0] == '+')
843 {
844 (void) SetImageOption(image_info,argv[0]+1,"0.0");
845 break;
846 }
847 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
848 break;
849 }
850 break;
851 }
852 case 'i':
853 {
854 if (LocaleCompare("intent",argv[0]+1) == 0)
855 {
856 if (*argv[0] == '+')
857 {
858 (void) SetImageOption(image_info,argv[0]+1,"undefined");
859 break;
860 }
861 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
862 break;
863 }
864 if (LocaleCompare("interlace",argv[0]+1) == 0)
865 {
866 if (*argv[0] == '+')
867 {
868 image_info->interlace=UndefinedInterlace;
869 (void) SetImageOption(image_info,argv[0]+1,"undefined");
870 break;
871 }
872 image_info->interlace=(InterlaceType) ParseCommandOption(
873 MagickInterlaceOptions,MagickFalse,argv[1]);
874 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
875 break;
876 }
877 if (LocaleCompare("interline-spacing",argv[0]+1) == 0)
878 {
879 if (*argv[0] == '+')
880 {
881 (void) SetImageOption(image_info,argv[0]+1,"undefined");
882 break;
883 }
884 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
885 break;
886 }
887 if (LocaleCompare("interpolate",argv[0]+1) == 0)
888 {
889 if (*argv[0] == '+')
890 {
891 (void) SetImageOption(image_info,argv[0]+1,"undefined");
892 break;
893 }
894 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
895 break;
896 }
897 if (LocaleCompare("interword-spacing",argv[0]+1) == 0)
898 {
899 if (*argv[0] == '+')
900 {
901 (void) SetImageOption(image_info,argv[0]+1,"undefined");
902 break;
903 }
904 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
905 break;
906 }
907 break;
908 }
909 case 'k':
910 {
911 if (LocaleCompare("kerning",argv[0]+1) == 0)
912 {
913 if (*argv[0] == '+')
914 {
915 (void) SetImageOption(image_info,argv[0]+1,"undefined");
916 break;
917 }
918 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
919 break;
920 }
921 break;
922 }
923 case 'l':
924 {
925 if (LocaleCompare("label",argv[0]+1) == 0)
926 {
927 if (*argv[0] == '+')
928 {
929 (void) DeleteImageOption(image_info,argv[0]+1);
930 break;
931 }
932 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
933 break;
934 }
935 if (LocaleCompare("limit",argv[0]+1) == 0)
936 {
937 MagickSizeType
938 limit;
939
940 ResourceType
941 type;
942
943 if (*argv[0] == '+')
944 break;
945 type=(ResourceType) ParseCommandOption(MagickResourceOptions,
946 MagickFalse,argv[1]);
947 limit=MagickResourceInfinity;
948 if (LocaleCompare("unlimited",argv[2]) != 0)
949 limit=(MagickSizeType) SiPrefixToDouble(argv[2],100.0);
950 (void) SetMagickResourceLimit(type,limit);
951 break;
952 }
953 if (LocaleCompare("list",argv[0]+1) == 0)
954 {
955 ssize_t
956 list;
957
958 /*
959 Display configuration list.
960 */
961 list=ParseCommandOption(MagickListOptions,MagickFalse,argv[1]);
962 switch (list)
963 {
964 case MagickCoderOptions:
965 {
966 (void) ListCoderInfo((FILE *) NULL,exception);
967 break;
968 }
969 case MagickColorOptions:
970 {
971 (void) ListColorInfo((FILE *) NULL,exception);
972 break;
973 }
974 case MagickConfigureOptions:
975 {
976 (void) ListConfigureInfo((FILE *) NULL,exception);
977 break;
978 }
979 case MagickDelegateOptions:
980 {
981 (void) ListDelegateInfo((FILE *) NULL,exception);
982 break;
983 }
984 case MagickFontOptions:
985 {
986 (void) ListTypeInfo((FILE *) NULL,exception);
987 break;
988 }
989 case MagickFormatOptions:
990 {
991 (void) ListMagickInfo((FILE *) NULL,exception);
992 break;
993 }
994 case MagickLocaleOptions:
995 {
996 (void) ListLocaleInfo((FILE *) NULL,exception);
997 break;
998 }
999 case MagickLogOptions:
1000 {
1001 (void) ListLogInfo((FILE *) NULL,exception);
1002 break;
1003 }
1004 case MagickMagicOptions:
1005 {
1006 (void) ListMagicInfo((FILE *) NULL,exception);
1007 break;
1008 }
1009 case MagickMimeOptions:
1010 {
1011 (void) ListMimeInfo((FILE *) NULL,exception);
1012 break;
1013 }
1014 case MagickModuleOptions:
1015 {
1016 (void) ListModuleInfo((FILE *) NULL,exception);
1017 break;
1018 }
1019 case MagickPolicyOptions:
1020 {
1021 (void) ListPolicyInfo((FILE *) NULL,exception);
1022 break;
1023 }
1024 case MagickResourceOptions:
1025 {
1026 (void) ListMagickResourceInfo((FILE *) NULL,exception);
1027 break;
1028 }
1029 case MagickThresholdOptions:
1030 {
1031 (void) ListThresholdMaps((FILE *) NULL,exception);
1032 break;
1033 }
1034 default:
1035 {
1036 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
1037 exception);
1038 break;
1039 }
1040 }
1041 break;
1042 }
1043 if (LocaleCompare("log",argv[0]+1) == 0)
1044 {
1045 if (*argv[0] == '+')
1046 break;
1047 (void) SetLogFormat(argv[1]);
1048 break;
1049 }
1050 if (LocaleCompare("loop",argv[0]+1) == 0)
1051 {
1052 if (*argv[0] == '+')
1053 {
1054 (void) SetImageOption(image_info,argv[0]+1,"0");
1055 break;
1056 }
1057 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1058 break;
1059 }
1060 break;
1061 }
1062 case 'm':
1063 {
1064 if (LocaleCompare("matte",argv[0]+1) == 0)
1065 {
1066 if (*argv[0] == '+')
1067 {
1068 (void) SetImageOption(image_info,argv[0]+1,"false");
1069 break;
1070 }
1071 (void) SetImageOption(image_info,argv[0]+1,"true");
1072 break;
1073 }
1074 if (LocaleCompare("mattecolor",argv[0]+1) == 0)
1075 {
1076 if (*argv[0] == '+')
1077 {
1078 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1079 (void) QueryColorDatabase(MatteColor,&image_info->matte_color,
1080 exception);
1081 break;
1082 }
1083 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1084 (void) QueryColorDatabase(argv[1],&image_info->matte_color,
1085 exception);
1086 break;
1087 }
1088 if (LocaleCompare("monitor",argv[0]+1) == 0)
1089 {
1090 (void) SetImageInfoProgressMonitor(image_info,MonitorProgress,
1091 (void *) NULL);
1092 break;
1093 }
1094 if (LocaleCompare("monochrome",argv[0]+1) == 0)
1095 {
1096 image_info->monochrome=(*argv[0] == '-') ? MagickTrue : MagickFalse;
1097 break;
1098 }
1099 break;
1100 }
1101 case 'o':
1102 {
1103 if (LocaleCompare("orient",argv[0]+1) == 0)
1104 {
1105 if (*argv[0] == '+')
1106 {
1107 image_info->orientation=UndefinedOrientation;
1108 (void) SetImageOption(image_info,argv[0]+1,"undefined");
1109 break;
1110 }
1111 image_info->orientation=(OrientationType) ParseCommandOption(
1112 MagickOrientationOptions,MagickFalse,argv[1]);
1113 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1114 break;
1115 }
1116 }
1117 case 'p':
1118 {
1119 if (LocaleCompare("page",argv[0]+1) == 0)
1120 {
1121 char
1122 *canonical_page,
1123 page[MaxTextExtent];
1124
1125 const char
1126 *image_option;
1127
1128 MagickStatusType
1129 flags;
1130
1131 RectangleInfo
1132 geometry;
1133
1134 if (*argv[0] == '+')
1135 {
1136 (void) DeleteImageOption(image_info,argv[0]+1);
1137 (void) CloneString(&image_info->page,(char *) NULL);
1138 break;
1139 }
1140 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
1141 image_option=GetImageOption(image_info,"page");
1142 if (image_option != (const char *) NULL)
1143 flags=ParseAbsoluteGeometry(image_option,&geometry);
1144 canonical_page=GetPageGeometry(argv[1]);
1145 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1146 canonical_page=DestroyString(canonical_page);
1147 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1148 (unsigned long) geometry.width,(unsigned long) geometry.height);
1149 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1150 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1151 (unsigned long) geometry.width,(unsigned long) geometry.height,
1152 (long) geometry.x,(long) geometry.y);
1153 (void) SetImageOption(image_info,argv[0]+1,page);
1154 (void) CloneString(&image_info->page,page);
1155 break;
1156 }
1157 if (LocaleCompare("pen",argv[0]+1) == 0)
1158 {
1159 if (*argv[0] == '+')
1160 {
1161 (void) SetImageOption(image_info,argv[0]+1,"none");
1162 break;
1163 }
1164 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1165 break;
1166 }
1167 if (LocaleCompare("ping",argv[0]+1) == 0)
1168 {
1169 image_info->ping=(*argv[0] == '-') ? MagickTrue : MagickFalse;
1170 break;
1171 }
1172 if (LocaleCompare("pointsize",argv[0]+1) == 0)
1173 {
1174 if (*argv[0] == '+')
1175 geometry_info.rho=0.0;
1176 else
1177 (void) ParseGeometry(argv[1],&geometry_info);
1178 image_info->pointsize=geometry_info.rho;
1179 break;
1180 }
1181 if (LocaleCompare("precision",argv[0]+1) == 0)
1182 {
1183 (void) SetMagickPrecision(StringToInteger(argv[1]));
1184 break;
1185 }
1186 if (LocaleCompare("preview",argv[0]+1) == 0)
1187 {
1188 /*
1189 Preview image.
1190 */
1191 if (*argv[0] == '+')
1192 {
1193 image_info->preview_type=UndefinedPreview;
1194 break;
1195 }
1196 image_info->preview_type=(PreviewType) ParseCommandOption(
1197 MagickPreviewOptions,MagickFalse,argv[1]);
1198 break;
1199 }
1200 break;
1201 }
1202 case 'q':
1203 {
1204 if (LocaleCompare("quality",argv[0]+1) == 0)
1205 {
1206 /*
1207 Set image compression quality.
1208 */
1209 if (*argv[0] == '+')
1210 {
1211 image_info->quality=UndefinedCompressionQuality;
1212 (void) SetImageOption(image_info,argv[0]+1,"0");
1213 break;
1214 }
1215 image_info->quality=StringToUnsignedLong(argv[1]);
1216 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1217 break;
1218 }
1219 if (LocaleCompare("quiet",argv[0]+1) == 0)
1220 {
1221 static WarningHandler
1222 warning_handler = (WarningHandler) NULL;
1223
1224 if (*argv[0] == '+')
1225 {
1226 /*
1227 Restore error or warning messages.
1228 */
1229 warning_handler=SetWarningHandler(warning_handler);
1230 break;
1231 }
1232 /*
1233 Suppress error or warning messages.
1234 */
1235 warning_handler=SetWarningHandler((WarningHandler) NULL);
1236 break;
1237 }
1238 break;
1239 }
1240 case 'r':
1241 {
1242 if (LocaleCompare("red-primary",argv[0]+1) == 0)
1243 {
1244 if (*argv[0] == '+')
1245 {
1246 (void) SetImageOption(image_info,argv[0]+1,"0.0");
1247 break;
1248 }
1249 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1250 break;
1251 }
1252 break;
1253 }
1254 case 's':
1255 {
1256 if (LocaleCompare("sampling-factor",argv[0]+1) == 0)
1257 {
1258 /*
1259 Set image sampling factor.
1260 */
1261 if (*argv[0] == '+')
1262 {
1263 if (image_info->sampling_factor != (char *) NULL)
1264 image_info->sampling_factor=DestroyString(
1265 image_info->sampling_factor);
1266 break;
1267 }
1268 (void) CloneString(&image_info->sampling_factor,argv[1]);
1269 break;
1270 }
1271 if (LocaleCompare("scene",argv[0]+1) == 0)
1272 {
1273 /*
1274 Set image scene.
1275 */
1276 if (*argv[0] == '+')
1277 {
1278 image_info->scene=0;
1279 (void) SetImageOption(image_info,argv[0]+1,"0");
1280 break;
1281 }
1282 image_info->scene=StringToUnsignedLong(argv[1]);
1283 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1284 break;
1285 }
1286 if (LocaleCompare("seed",argv[0]+1) == 0)
1287 {
1288 size_t
1289 seed;
1290
1291 if (*argv[0] == '+')
1292 {
1293 seed=(size_t) time((time_t *) NULL);
1294 SeedPseudoRandomGenerator(seed);
1295 break;
1296 }
1297 seed=StringToUnsignedLong(argv[1]);
1298 SeedPseudoRandomGenerator(seed);
1299 break;
1300 }
1301 if (LocaleCompare("size",argv[0]+1) == 0)
1302 {
1303 if (*argv[0] == '+')
1304 {
1305 if (image_info->size != (char *) NULL)
1306 image_info->size=DestroyString(image_info->size);
1307 break;
1308 }
1309 (void) CloneString(&image_info->size,argv[1]);
1310 break;
1311 }
1312 if (LocaleCompare("stroke",argv[0]+1) == 0)
1313 {
1314 if (*argv[0] == '+')
1315 {
1316 (void) SetImageOption(image_info,argv[0]+1,"none");
1317 break;
1318 }
1319 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1320 break;
1321 }
1322 if (LocaleCompare("strokewidth",argv[0]+1) == 0)
1323 {
1324 if (*argv[0] == '+')
1325 {
1326 (void) SetImageOption(image_info,argv[0]+1,"0");
1327 break;
1328 }
1329 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1330 break;
1331 }
1332 if (LocaleCompare("synchronize",argv[0]+1) == 0)
1333 {
1334 if (*argv[0] == '+')
1335 {
1336 image_info->synchronize=MagickFalse;
1337 break;
1338 }
1339 image_info->synchronize=MagickTrue;
1340 break;
1341 }
1342 break;
1343 }
1344 case 't':
1345 {
1346 if (LocaleCompare("taint",argv[0]+1) == 0)
1347 {
1348 if (*argv[0] == '+')
1349 {
1350 (void) SetImageOption(image_info,argv[0]+1,"false");
1351 break;
1352 }
1353 (void) SetImageOption(image_info,argv[0]+1,"true");
1354 break;
1355 }
1356 if (LocaleCompare("texture",argv[0]+1) == 0)
1357 {
1358 if (*argv[0] == '+')
1359 {
1360 if (image_info->texture != (char *) NULL)
1361 image_info->texture=DestroyString(image_info->texture);
1362 break;
1363 }
1364 (void) CloneString(&image_info->texture,argv[1]);
1365 break;
1366 }
1367 if (LocaleCompare("tile-offset",argv[0]+1) == 0)
1368 {
1369 if (*argv[0] == '+')
1370 {
1371 (void) SetImageOption(image_info,argv[0]+1,"0");
1372 break;
1373 }
1374 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1375 break;
1376 }
1377 if (LocaleCompare("transparent-color",argv[0]+1) == 0)
1378 {
1379 if (*argv[0] == '+')
1380 {
1381 (void) QueryColorDatabase("none",&image_info->transparent_color, exception);
1382 (void) SetImageOption(image_info,argv[0]+1,"none");
1383 break;
1384 }
1385 (void) QueryColorDatabase(argv[1],&image_info->transparent_color,
1386 exception);
1387 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1388 break;
1389 }
1390 if (LocaleCompare("type",argv[0]+1) == 0)
1391 {
1392 if (*argv[0] == '+')
1393 {
1394 image_info->type=UndefinedType;
1395 (void) SetImageOption(image_info,argv[0]+1,"undefined");
1396 break;
1397 }
1398 image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
1399 MagickFalse,argv[1]);
1400 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1401 break;
1402 }
1403 break;
1404 }
1405 case 'u':
1406 {
1407 if (LocaleCompare("undercolor",argv[0]+1) == 0)
1408 {
1409 if (*argv[0] == '+')
1410 {
1411 (void) DeleteImageOption(image_info,argv[0]+1);
1412 break;
1413 }
1414 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1415 break;
1416 }
1417 if (LocaleCompare("units",argv[0]+1) == 0)
1418 {
1419 if (*argv[0] == '+')
1420 {
1421 image_info->units=UndefinedResolution;
1422 (void) SetImageOption(image_info,argv[0]+1,"undefined");
1423 break;
1424 }
1425 image_info->units=(ResolutionType) ParseCommandOption(
1426 MagickResolutionOptions,MagickFalse,argv[1]);
1427 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1428 break;
1429 }
1430 break;
1431 }
1432 case 'v':
1433 {
1434 if (LocaleCompare("verbose",argv[0]+1) == 0)
1435 {
1436 if (*argv[0] == '+')
1437 {
1438 image_info->verbose=MagickFalse;
1439 break;
1440 }
1441 image_info->verbose=MagickTrue;
1442 image_info->ping=MagickFalse;
1443 break;
1444 }
1445 if (LocaleCompare("view",argv[0]+1) == 0)
1446 {
1447 if (*argv[0] == '+')
1448 {
1449 if (image_info->view != (char *) NULL)
1450 image_info->view=DestroyString(image_info->view);
1451 break;
1452 }
1453 (void) CloneString(&image_info->view,argv[1]);
1454 break;
1455 }
1456 if (LocaleCompare("virtual-pixel",argv[0]+1) == 0)
1457 {
1458 if (*argv[0] == '+')
1459 {
1460 image_info->virtual_pixel_method=UndefinedVirtualPixelMethod;
1461 (void) SetImageOption(image_info,argv[0]+1,"undefined");
1462 break;
1463 }
1464 image_info->virtual_pixel_method=(VirtualPixelMethod)
1465 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,argv[1]);
1466 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1467 break;
1468 }
1469 break;
1470 }
1471 case 'w':
1472 {
1473 if (LocaleCompare("white-point",argv[0]+1) == 0)
1474 {
1475 if (*argv[0] == '+')
1476 {
1477 (void) SetImageOption(image_info,argv[0]+1,"0.0");
1478 break;
1479 }
1480 (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1481 break;
1482 }
1483 break;
1484 }
1485 default:
1486 break;
1487 }
1488 return(MagickTrue);
1489}
1490
1491/*
1492%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1493% %
1494% %
1495% %
1496+ S i m p l e O p e r a t i o n I m a g e %
1497% %
1498% %
1499% %
1500%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1501%
1502% SimpleOperationImage() apply one simple operation on one image.
1503% The image however may be part of a longer list of images.
1504%
1505% The image in the list may be modified in three different ways...
1506%
1507% * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1508% * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1509% * replace by a list of images (-separate and -crop only!)
1510%
1511% In each case the result is returned into the list, and the pointer to the
1512% modified image (last image added if replaced by a list of images) is
1513% returned. As the image pointed to may be replaced, the first image in the
1514% list may also change. GetFirstImageInList() should be used by caller if
1515% they wish return the Image pointer to the first image in list.
1516%
1517% The format of the SimpleOperationImage method is:
1518%
1519% MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
1520% const int argc,const char **argv,Image **image)
1521%
1522% A description of each parameter follows:
1523%
1524% o image_info: the image info..
1525%
1526% o argc: Specifies a pointer to an integer describing the number of
1527% elements in the argument vector.
1528%
1529% o argv: Specifies a pointer to a text array containing the command line
1530% arguments.
1531%
1532% o image: the image.
1533%
1534% o exception: return any errors or warnings in this structure.
1535%
1536*/
1537MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
1538 const int wand_unused(argc), const char **argv,Image **image,
1539 ExceptionInfo *exception)
1540{
1541 Image *
1542 new_image;
1543
1544 ChannelType
1545 channel;
1546
1547 const char
1548 *format;
1549
1550 DrawInfo
1551 *draw_info;
1552
1553 GeometryInfo
1554 geometry_info;
1555
1556 RectangleInfo
1557 geometry;
1558
1559 MagickStatusType
1560 status;
1561
1562 PixelInfo
1563 fill;
1564
1565 MagickStatusType
1566 flags;
1567
1568 QuantizeInfo
1569 *quantize_info;
1570
1571 assert(image_info != (const ImageInfo *) NULL);
1572 assert(image_info->signature == MagickSignature);
1573 assert(image != (Image **) NULL);
1574 assert((*image)->signature == MagickSignature);
1575 if ((*image)->debug != MagickFalse)
1576 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
1577
1578 draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
1579 quantize_info=AcquireQuantizeInfo(image_info);
1580 SetGeometryInfo(&geometry_info);
1581 GetPixelInfo(*image,&fill);
1582 SetPixelInfoPacket(*image,&(*image)->background_color,&fill);
1583 channel=image_info->channel;
1584 format=GetImageOption(image_info,"format");
1585
1586 new_image = (Image *)NULL;
1587
1588 switch (*(argv[0]+1))
1589 {
1590 case 'a':
1591 {
1592 if (LocaleCompare("adaptive-blur",argv[0]+1) == 0)
1593 {
1594 /*
1595 Adaptive blur image.
1596 */
1597 (void) SyncImageSettings(image_info,*image);
1598 flags=ParseGeometry(argv[1],&geometry_info);
1599 if ((flags & SigmaValue) == 0)
1600 geometry_info.sigma=1.0;
1601 if ((flags & XiValue) == 0)
1602 geometry_info.xi=0.0;
1603 new_image=AdaptiveBlurImage(*image,geometry_info.rho,
1604 geometry_info.sigma,geometry_info.xi,exception);
1605 break;
1606 }
1607 if (LocaleCompare("adaptive-resize",argv[0]+1) == 0)
1608 {
1609 /*
1610 Adaptive resize image.
1611 */
1612 (void) SyncImageSettings(image_info,*image);
1613 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
1614 new_image=AdaptiveResizeImage(*image,geometry.width,
1615 geometry.height,exception);
1616 break;
1617 }
1618 if (LocaleCompare("adaptive-sharpen",argv[0]+1) == 0)
1619 {
1620 /*
1621 Adaptive sharpen image.
1622 */
1623 (void) SyncImageSettings(image_info,*image);
1624 flags=ParseGeometry(argv[1],&geometry_info);
1625 if ((flags & SigmaValue) == 0)
1626 geometry_info.sigma=1.0;
1627 if ((flags & XiValue) == 0)
1628 geometry_info.xi=0.0;
1629 new_image=AdaptiveSharpenImage(*image,geometry_info.rho,
1630 geometry_info.sigma,geometry_info.xi,exception);
1631 break;
1632 }
1633 if (LocaleCompare("affine",argv[0]+1) == 0)
1634 {
1635 /*
1636 Affine matrix.
1637 */
1638 if (*argv[0] == '+')
1639 {
1640 GetAffineMatrix(&draw_info->affine);
1641 break;
1642 }
1643 (void) ParseAffineGeometry(argv[1],&draw_info->affine,exception);
1644 break;
1645 }
1646 if (LocaleCompare("alpha",argv[0]+1) == 0)
1647 {
1648 AlphaChannelType
1649 alpha_type;
1650
1651 (void) SyncImageSettings(image_info,*image);
1652 alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
1653 MagickFalse,argv[1]);
1654 (void) SetImageAlphaChannel(*image,alpha_type,exception);
1655 break;
1656 }
1657 if (LocaleCompare("annotate",argv[0]+1) == 0)
1658 {
1659 char
1660 *text,
1661 geometry[MaxTextExtent];
1662
1663 /*
1664 Annotate image.
1665 */
1666 (void) SyncImageSettings(image_info,*image);
1667 SetGeometryInfo(&geometry_info);
1668 flags=ParseGeometry(argv[1],&geometry_info);
1669 if ((flags & SigmaValue) == 0)
1670 geometry_info.sigma=geometry_info.rho;
1671 text=InterpretImageProperties(image_info,*image,argv[2],
1672 exception);
1673 if (text == (char *) NULL)
1674 break;
1675 (void) CloneString(&draw_info->text,text);
1676 text=DestroyString(text);
1677 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1678 geometry_info.xi,geometry_info.psi);
1679 (void) CloneString(&draw_info->geometry,geometry);
1680 draw_info->affine.sx=cos(DegreesToRadians(
1681 fmod(geometry_info.rho,360.0)));
1682 draw_info->affine.rx=sin(DegreesToRadians(
1683 fmod(geometry_info.rho,360.0)));
1684 draw_info->affine.ry=(-sin(DegreesToRadians(
1685 fmod(geometry_info.sigma,360.0))));
1686 draw_info->affine.sy=cos(DegreesToRadians(
1687 fmod(geometry_info.sigma,360.0)));
1688 (void) AnnotateImage(*image,draw_info,exception);
1689 break;
1690 }
1691 if (LocaleCompare("antialias",argv[0]+1) == 0)
1692 {
1693 draw_info->stroke_antialias=(*argv[0] == '-') ? MagickTrue :
1694 MagickFalse;
1695 draw_info->text_antialias=(*argv[0] == '-') ? MagickTrue :
1696 MagickFalse;
1697 break;
1698 }
1699 if (LocaleCompare("auto-gamma",argv[0]+1) == 0)
1700 {
1701 /*
1702 Auto Adjust Gamma of image based on its mean
1703 */
1704 (void) SyncImageSettings(image_info,*image);
1705 (void) AutoGammaImage(*image,exception);
1706 break;
1707 }
1708 if (LocaleCompare("auto-level",argv[0]+1) == 0)
1709 {
1710 /*
1711 Perfectly Normalize (max/min stretch) the image
1712 */
1713 (void) SyncImageSettings(image_info,*image);
1714 (void) AutoLevelImage(*image,exception);
1715 break;
1716 }
1717 if (LocaleCompare("auto-orient",argv[0]+1) == 0)
1718 {
1719 (void) SyncImageSettings(image_info,*image);
1720 switch ((*image)->orientation)
1721 {
1722 case TopRightOrientation:
1723 {
1724 new_image=FlopImage(*image,exception);
1725 break;
1726 }
1727 case BottomRightOrientation:
1728 {
1729 new_image=RotateImage(*image,180.0,exception);
1730 break;
1731 }
1732 case BottomLeftOrientation:
1733 {
1734 new_image=FlipImage(*image,exception);
1735 break;
1736 }
1737 case LeftTopOrientation:
1738 {
1739 new_image=TransposeImage(*image,exception);
1740 break;
1741 }
1742 case RightTopOrientation:
1743 {
1744 new_image=RotateImage(*image,90.0,exception);
1745 break;
1746 }
1747 case RightBottomOrientation:
1748 {
1749 new_image=TransverseImage(*image,exception);
1750 break;
1751 }
1752 case LeftBottomOrientation:
1753 {
1754 new_image=RotateImage(*image,270.0,exception);
1755 break;
1756 }
1757 default:
1758 break;
1759 }
1760 if (new_image != (Image *) NULL)
1761 new_image->orientation=TopLeftOrientation;
1762 break;
1763 }
1764 break;
1765 }
1766 case 'b':
1767 {
1768 if (LocaleCompare("black-threshold",argv[0]+1) == 0)
1769 {
1770 /*
1771 Black threshold image.
1772 */
1773 (void) SyncImageSettings(image_info,*image);
1774 (void) BlackThresholdImage(*image,argv[1],exception);
1775 InheritException(exception,&(*image)->exception);
1776 break;
1777 }
1778 if (LocaleCompare("blue-shift",argv[0]+1) == 0)
1779 {
1780 /*
1781 Blue shift image.
1782 */
1783 (void) SyncImageSettings(image_info,*image);
1784 geometry_info.rho=1.5;
1785 if (*argv[0] == '-')
1786 flags=ParseGeometry(argv[1],&geometry_info);
1787 new_image=BlueShiftImage(*image,geometry_info.rho,exception);
1788 break;
1789 }
1790 if (LocaleCompare("blur",argv[0]+1) == 0)
1791 {
1792 /*
1793 Two pass gaussian blur of image.
1794 */
1795 (void) SyncImageSettings(image_info,*image);
1796 flags=ParseGeometry(argv[1],&geometry_info);
1797 if ((flags & SigmaValue) == 0)
1798 geometry_info.sigma=1.0;
1799 if ((flags & XiValue) == 0)
1800 geometry_info.xi=0.0;
1801 new_image=BlurImage(*image,geometry_info.rho,
1802 geometry_info.sigma,geometry_info.xi,exception);
1803 break;
1804 }
1805 if (LocaleCompare("border",argv[0]+1) == 0)
1806 {
1807 /*
1808 Surround image with a border of solid color.
1809 */
1810 (void) SyncImageSettings(image_info,*image);
1811 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
1812 if ((flags & SigmaValue) == 0)
1813 geometry.height=geometry.width;
1814 new_image=BorderImage(*image,&geometry,exception);
1815 break;
1816 }
1817 if (LocaleCompare("bordercolor",argv[0]+1) == 0)
1818 {
1819 if (*argv[0] == '+')
1820 {
1821 (void) QueryColorDatabase(BorderColor,&draw_info->border_color,
1822 exception);
1823 break;
1824 }
1825 (void) QueryColorDatabase(argv[1],&draw_info->border_color,
1826 exception);
1827 break;
1828 }
1829 if (LocaleCompare("box",argv[0]+1) == 0)
1830 {
1831 (void) QueryColorDatabase(argv[1],&draw_info->undercolor,
1832 exception);
1833 break;
1834 }
1835 if (LocaleCompare("brightness-contrast",argv[0]+1) == 0)
1836 {
1837 double
1838 brightness,
1839 contrast;
1840
1841 GeometryInfo
1842 geometry_info;
1843
1844 MagickStatusType
1845 flags;
1846
1847 /*
1848 Brightness / contrast image.
1849 */
1850 (void) SyncImageSettings(image_info,*image);
1851 flags=ParseGeometry(argv[1],&geometry_info);
1852 brightness=geometry_info.rho;
1853 contrast=0.0;
1854 if ((flags & SigmaValue) != 0)
1855 contrast=geometry_info.sigma;
1856 (void) BrightnessContrastImage(*image,brightness,contrast,
1857 exception);
1858 InheritException(exception,&(*image)->exception);
1859 break;
1860 }
1861 break;
1862 }
1863 case 'c':
1864 {
1865 if (LocaleCompare("cdl",argv[0]+1) == 0)
1866 {
1867 char
1868 *color_correction_collection;
1869
1870 /*
1871 Color correct with a color decision list.
1872 */
1873 (void) SyncImageSettings(image_info,*image);
1874 color_correction_collection=FileToString(argv[1],~0,exception);
1875 if (color_correction_collection == (char *) NULL)
1876 break;
1877 (void) ColorDecisionListImage(*image,color_correction_collection,
1878 exception);
1879 InheritException(exception,&(*image)->exception);
1880 break;
1881 }
1882 if (LocaleCompare("channel",argv[0]+1) == 0)
1883 {
1884 if (*argv[0] == '+')
1885 channel=DefaultChannels;
1886 else
1887 channel=(ChannelType) ParseChannelOption(argv[1]);
1888 SetPixelChannelMap(*image,channel);
1889 break;
1890 }
1891 if (LocaleCompare("charcoal",argv[0]+1) == 0)
1892 {
1893 /*
1894 Charcoal image.
1895 */
1896 (void) SyncImageSettings(image_info,*image);
1897 flags=ParseGeometry(argv[1],&geometry_info);
1898 if ((flags & SigmaValue) == 0)
1899 geometry_info.sigma=1.0;
1900 if ((flags & XiValue) == 0)
1901 geometry_info.xi=1.0;
1902 new_image=CharcoalImage(*image,geometry_info.rho,
1903 geometry_info.sigma,geometry_info.xi,exception);
1904 break;
1905 }
1906 if (LocaleCompare("chop",argv[0]+1) == 0)
1907 {
1908 /*
1909 Chop the image.
1910 */
1911 (void) SyncImageSettings(image_info,*image);
1912 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
1913 new_image=ChopImage(*image,&geometry,exception);
1914 break;
1915 }
1916 if (LocaleCompare("clamp",argv[0]+1) == 0)
1917 {
1918 /*
1919 Clamp image.
1920 */
1921 (void) SyncImageSettings(image_info,*image);
1922 (void) ClampImage(*image);
1923 InheritException(exception,&(*image)->exception);
1924 break;
1925 }
1926 if (LocaleCompare("clip",argv[0]+1) == 0)
1927 {
1928 (void) SyncImageSettings(image_info,*image);
1929 if (*argv[0] == '+')
1930 {
1931 (void) SetImageClipMask(*image,(Image *) NULL,exception);
1932 break;
1933 }
1934 (void) ClipImage(*image,exception);
1935 break;
1936 }
1937 if (LocaleCompare("clip-mask",argv[0]+1) == 0)
1938 {
1939 CacheView
1940 *mask_view;
1941
1942 Image
1943 *mask_image;
1944
1945 register Quantum
1946 *restrict q;
1947
1948 register ssize_t
1949 x;
1950
1951 ssize_t
1952 y;
1953
1954 (void) SyncImageSettings(image_info,*image);
1955 if (*argv[0] == '+')
1956 {
1957 /*
1958 Remove a mask.
1959 */
1960 (void) SetImageMask(*image,(Image *) NULL,exception);
1961 break;
1962 }
1963 mask_image=GetImageCache(image_info,argv[1],exception);
1964 if (mask_image == (Image *) NULL)
1965 break;
1966 if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
1967 return(MagickFalse);
1968 mask_view=AcquireCacheView(mask_image);
1969 for (y=0; y < (ssize_t) mask_image->rows; y++)
1970 {
1971 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
1972 exception);
1973 if (q == (Quantum *) NULL)
1974 break;
1975 for (x=0; x < (ssize_t) mask_image->columns; x++)
1976 {
1977 if (mask_image->matte == MagickFalse)
1978 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1979 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1980 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1981 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1982 q+=GetPixelChannels(mask_image);
1983 }
1984 if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
1985 break;
1986 }
1987 mask_view=DestroyCacheView(mask_view);
1988 mask_image->matte=MagickTrue;
1989 (void) SetImageClipMask(*image,mask_image);
1990 mask_image=DestroyImage(mask_image);
1991 InheritException(exception,&(*image)->exception);
1992 break;
1993 }
1994 if (LocaleCompare("clip-path",argv[0]+1) == 0)
1995 {
1996 (void) SyncImageSettings(image_info,*image);
1997 (void) ClipImagePath(*image,argv[1],*argv[0] == '-' ? MagickTrue :
1998 MagickFalse,exception);
1999 break;
2000 }
2001 if (LocaleCompare("colorize",argv[0]+1) == 0)
2002 {
2003 /*
2004 Colorize the image.
2005 */
2006 (void) SyncImageSettings(image_info,*image);
2007 new_image=ColorizeImage(*image,argv[1],draw_info->fill,
2008 exception);
2009 break;
2010 }
2011 if (LocaleCompare("color-matrix",argv[0]+1) == 0)
2012 {
2013 KernelInfo
2014 *kernel;
2015
2016 (void) SyncImageSettings(image_info,*image);
2017 kernel=AcquireKernelInfo(argv[1]);
2018 if (kernel == (KernelInfo *) NULL)
2019 break;
2020 new_image=ColorMatrixImage(*image,kernel,exception);
2021 kernel=DestroyKernelInfo(kernel);
2022 break;
2023 }
2024 if (LocaleCompare("colors",argv[0]+1) == 0)
2025 {
2026 /*
2027 Reduce the number of colors in the image.
2028 */
2029 (void) SyncImageSettings(image_info,*image);
2030 quantize_info->number_colors=StringToUnsignedLong(argv[1]);
2031 if (quantize_info->number_colors == 0)
2032 break;
2033 if (((*image)->storage_class == DirectClass) ||
2034 (*image)->colors > quantize_info->number_colors)
2035 (void) QuantizeImage(quantize_info,*image,exception);
2036 else
2037 (void) CompressImageColormap(*image,exception);
2038 break;
2039 }
2040 if (LocaleCompare("colorspace",argv[0]+1) == 0)
2041 {
2042 ColorspaceType
2043 colorspace;
2044
2045 (void) SyncImageSettings(image_info,*image);
2046 if (*argv[0] == '+')
2047 {
2048 (void) TransformImageColorspace(*image,RGBColorspace);
2049 InheritException(exception,&(*image)->exception);
2050 break;
2051 }
2052 colorspace=(ColorspaceType) ParseCommandOption(
2053 MagickColorspaceOptions,MagickFalse,argv[1]);
2054 (void) TransformImageColorspace(*image,colorspace);
2055 InheritException(exception,&(*image)->exception);
2056 break;
2057 }
2058 if (LocaleCompare("contrast",argv[0]+1) == 0)
2059 {
2060 (void) SyncImageSettings(image_info,*image);
2061 (void) ContrastImage(*image,(*argv[0] == '-') ? MagickTrue :
2062 MagickFalse,exception);
2063 break;
2064 }
2065 if (LocaleCompare("contrast-stretch",argv[0]+1) == 0)
2066 {
2067 double
2068 black_point,
2069 white_point;
2070
2071 MagickStatusType
2072 flags;
2073
2074 /*
2075 Contrast stretch image.
2076 */
2077 (void) SyncImageSettings(image_info,*image);
2078 flags=ParseGeometry(argv[1],&geometry_info);
2079 black_point=geometry_info.rho;
2080 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2081 black_point;
2082 if ((flags & PercentValue) != 0)
2083 {
2084 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2085 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2086 }
2087 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2088 white_point;
2089 (void) ContrastStretchImage(*image,black_point,white_point,
2090 exception);
2091 InheritException(exception,&(*image)->exception);
2092 break;
2093 }
2094 if (LocaleCompare("convolve",argv[0]+1) == 0)
2095 {
2096 KernelInfo
2097 *kernel_info;
2098
2099 (void) SyncImageSettings(image_info,*image);
2100 kernel_info=AcquireKernelInfo(argv[1]);
2101 if (kernel_info == (KernelInfo *) NULL)
2102 break;
2103 kernel_info->bias=(*image)->bias;
2104 new_image=ConvolveImage(*image,kernel_info,exception);
2105 kernel_info=DestroyKernelInfo(kernel_info);
2106 break;
2107 }
2108 if (LocaleCompare("crop",argv[0]+1) == 0)
2109 {
2110 /*
2111 Crop a image to a smaller size
2112 */
2113 (void) SyncImageSettings(image_info,*image);
2114 new_image=CropImageToTiles(*image,argv[1],exception);
2115 break;
2116 }
2117 if (LocaleCompare("cycle",argv[0]+1) == 0)
2118 {
2119 /*
2120 Cycle an image colormap.
2121 */
2122 (void) SyncImageSettings(image_info,*image);
2123 (void) CycleColormapImage(*image,(ssize_t) StringToLong(argv[1]),
2124 exception);
2125 break;
2126 }
2127 break;
2128 }
2129 case 'd':
2130 {
2131 if (LocaleCompare("decipher",argv[0]+1) == 0)
2132 {
2133 StringInfo
2134 *passkey;
2135
2136 /*
2137 Decipher pixels.
2138 */
2139 (void) SyncImageSettings(image_info,*image);
2140 passkey=FileToStringInfo(argv[1],~0,exception);
2141 if (passkey != (StringInfo *) NULL)
2142 {
2143 (void) PasskeyDecipherImage(*image,passkey,exception);
2144 passkey=DestroyStringInfo(passkey);
2145 }
2146 break;
2147 }
2148 if (LocaleCompare("density",argv[0]+1) == 0)
2149 {
2150 /*
2151 Set image density.
2152 */
2153 (void) CloneString(&draw_info->density,argv[1]);
2154 break;
2155 }
2156 if (LocaleCompare("depth",argv[0]+1) == 0)
2157 {
2158 (void) SyncImageSettings(image_info,*image);
2159 if (*argv[0] == '+')
2160 {
2161 (void) SetImageDepth(*image,MAGICKCORE_QUANTUM_DEPTH);
2162 break;
2163 }
2164 (void) SetImageDepth(*image,StringToUnsignedLong(argv[1]));
2165 break;
2166 }
2167 if (LocaleCompare("deskew",argv[0]+1) == 0)
2168 {
2169 double
2170 threshold;
2171
2172 /*
2173 Straighten the image.
2174 */
2175 (void) SyncImageSettings(image_info,*image);
2176 if (*argv[0] == '+')
2177 threshold=40.0*QuantumRange/100.0;
2178 else
2179 threshold=SiPrefixToDouble(argv[1],QuantumRange);
2180 new_image=DeskewImage(*image,threshold,exception);
2181 break;
2182 }
2183 if (LocaleCompare("despeckle",argv[0]+1) == 0)
2184 {
2185 /*
2186 Reduce the speckles within an image.
2187 */
2188 (void) SyncImageSettings(image_info,*image);
2189 new_image=DespeckleImage(*image,exception);
2190 break;
2191 }
2192 if (LocaleCompare("display",argv[0]+1) == 0)
2193 {
2194 (void) CloneString(&draw_info->server_name,argv[1]);
2195 break;
2196 }
2197 if (LocaleCompare("distort",argv[0]+1) == 0)
2198 {
2199 char
2200 *args,
2201 token[MaxTextExtent];
2202
2203 const char
2204 *p;
2205
2206 DistortImageMethod
2207 method;
2208
2209 double
2210 *arguments;
2211
2212 register ssize_t
2213 x;
2214
2215 size_t
2216 number_arguments;
2217
2218 /*
2219 Distort image.
2220 */
2221 (void) SyncImageSettings(image_info,*image);
2222 method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
2223 MagickFalse,argv[1]);
2224 if ( method == ResizeDistortion )
2225 {
2226 /* Special Case - Argument is actually a resize geometry!
2227 ** Convert that to an appropriate distortion argument array.
2228 */
2229 double
2230 resize_args[2];
2231 (void) ParseRegionGeometry(*image,argv[2],&geometry,
2232 exception);
2233 resize_args[0]=(double)geometry.width;
2234 resize_args[1]=(double)geometry.height;
2235 new_image=DistortImage(*image,method,(size_t)2,
2236 resize_args,MagickTrue,exception);
2237 break;
2238 }
2239 args=InterpretImageProperties(image_info,*image,argv[2],
2240 exception);
2241 if (args == (char *) NULL)
2242 break;
2243 p=(char *) args;
2244 for (x=0; *p != '\0'; x++)
2245 {
2246 GetMagickToken(p,&p,token);
2247 if (*token == ',')
2248 GetMagickToken(p,&p,token);
2249 }
2250 number_arguments=(size_t) x;
2251 arguments=(double *) AcquireQuantumMemory(number_arguments,
2252 sizeof(*arguments));
2253 if (arguments == (double *) NULL)
2254 ThrowWandFatalException(ResourceLimitFatalError,
2255 "MemoryAllocationFailed",(*image)->filename);
2256 (void) ResetMagickMemory(arguments,0,number_arguments*
2257 sizeof(*arguments));
2258 p=(char *) args;
2259 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2260 {
2261 GetMagickToken(p,&p,token);
2262 if (*token == ',')
2263 GetMagickToken(p,&p,token);
2264 arguments[x]=InterpretLocaleValue(token,(char **) NULL);
2265 }
2266 args=DestroyString(args);
2267 new_image=DistortImage(*image,method,number_arguments,arguments,
2268 (*argv[0] == '+') ? MagickTrue : MagickFalse,exception);
2269 arguments=(double *) RelinquishMagickMemory(arguments);
2270 break;
2271 }
2272 if (LocaleCompare("dither",argv[0]+1) == 0)
2273 {
2274 if (*argv[0] == '+')
2275 {
2276 quantize_info->dither=MagickFalse;
2277 break;
2278 }
2279 quantize_info->dither=MagickTrue;
2280 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
2281 MagickDitherOptions,MagickFalse,argv[1]);
2282 if (quantize_info->dither_method == NoDitherMethod)
2283 quantize_info->dither=MagickFalse;
2284 break;
2285 }
2286 if (LocaleCompare("draw",argv[0]+1) == 0)
2287 {
2288 /*
2289 Draw image.
2290 */
2291 (void) SyncImageSettings(image_info,*image);
2292 (void) CloneString(&draw_info->primitive,argv[1]);
2293 (void) DrawImage(*image,draw_info,exception);
2294 break;
2295 }
2296 break;
2297 }
2298 case 'e':
2299 {
2300 if (LocaleCompare("edge",argv[0]+1) == 0)
2301 {
2302 /*
2303 Enhance edges in the image.
2304 */
2305 (void) SyncImageSettings(image_info,*image);
2306 flags=ParseGeometry(argv[1],&geometry_info);
2307 if ((flags & SigmaValue) == 0)
2308 geometry_info.sigma=1.0;
2309 new_image=EdgeImage(*image,geometry_info.rho,
2310 geometry_info.sigma,exception);
2311 break;
2312 }
2313 if (LocaleCompare("emboss",argv[0]+1) == 0)
2314 {
2315 /*
2316 Gaussian embossen image.
2317 */
2318 (void) SyncImageSettings(image_info,*image);
2319 flags=ParseGeometry(argv[1],&geometry_info);
2320 if ((flags & SigmaValue) == 0)
2321 geometry_info.sigma=1.0;
2322 new_image=EmbossImage(*image,geometry_info.rho,
2323 geometry_info.sigma,exception);
2324 break;
2325 }
2326 if (LocaleCompare("encipher",argv[0]+1) == 0)
2327 {
2328 StringInfo
2329 *passkey;
2330
2331 /*
2332 Encipher pixels.
2333 */
2334 (void) SyncImageSettings(image_info,*image);
2335 passkey=FileToStringInfo(argv[1],~0,exception);
2336 if (passkey != (StringInfo *) NULL)
2337 {
2338 (void) PasskeyEncipherImage(*image,passkey,exception);
2339 passkey=DestroyStringInfo(passkey);
2340 }
2341 break;
2342 }
2343 if (LocaleCompare("encoding",argv[0]+1) == 0)
2344 {
2345 (void) CloneString(&draw_info->encoding,argv[1]);
2346 break;
2347 }
2348 if (LocaleCompare("enhance",argv[0]+1) == 0)
2349 {
2350 /*
2351 Enhance image.
2352 */
2353 (void) SyncImageSettings(image_info,*image);
2354 new_image=EnhanceImage(*image,exception);
2355 break;
2356 }
2357 if (LocaleCompare("equalize",argv[0]+1) == 0)
2358 {
2359 /*
2360 Equalize image.
2361 */
2362 (void) SyncImageSettings(image_info,*image);
2363 (void) EqualizeImage(*image,exception);
2364 break;
2365 }
2366 if (LocaleCompare("evaluate",argv[0]+1) == 0)
2367 {
2368 double
2369 constant;
2370
2371 MagickEvaluateOperator
2372 op;
2373
2374 (void) SyncImageSettings(image_info,*image);
2375 op=(MagickEvaluateOperator) ParseCommandOption(
2376 MagickEvaluateOptions,MagickFalse,argv[1]);
2377 constant=SiPrefixToDouble(argv[2],QuantumRange);
2378 (void) EvaluateImage(*image,op,constant,exception);
2379 break;
2380 }
2381 if (LocaleCompare("extent",argv[0]+1) == 0)
2382 {
2383 /*
2384 Set the image extent.
2385 */
2386 (void) SyncImageSettings(image_info,*image);
2387 flags=ParseGravityGeometry(*image,argv[1],&geometry,exception);
2388 if (geometry.width == 0)
2389 geometry.width=(*image)->columns;
2390 if (geometry.height == 0)
2391 geometry.height=(*image)->rows;
2392 new_image=ExtentImage(*image,&geometry,exception);
2393 break;
2394 }
2395 break;
2396 }
2397 case 'f':
2398 {
2399 if (LocaleCompare("family",argv[0]+1) == 0)
2400 {
2401 if (*argv[0] == '+')
2402 {
2403 if (draw_info->family != (char *) NULL)
2404 draw_info->family=DestroyString(draw_info->family);
2405 break;
2406 }
2407 (void) CloneString(&draw_info->family,argv[1]);
2408 break;
2409 }
2410 if (LocaleCompare("features",argv[0]+1) == 0)
2411 {
2412 if (*argv[0] == '+')
2413 {
2414 (void) DeleteImageArtifact(*image,"identify:features");
2415 break;
2416 }
2417 (void) SetImageArtifact(*image,"identify:features",argv[1]);
2418 break;
2419 }
2420 if (LocaleCompare("fill",argv[0]+1) == 0)
2421 {
2422 ExceptionInfo
2423 *sans;
2424
2425 GetPixelInfo(*image,&fill);
2426 if (*argv[0] == '+')
2427 {
2428 (void) QueryMagickColor("none",&fill,exception);
2429 (void) QueryColorDatabase("none",&draw_info->fill,exception);
2430 if (draw_info->fill_pattern != (Image *) NULL)
2431 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
2432 break;
2433 }
2434 sans=AcquireExceptionInfo();
2435 (void) QueryMagickColor(argv[1],&fill,sans);
2436 status=QueryColorDatabase(argv[1],&draw_info->fill,sans);
2437 sans=DestroyExceptionInfo(sans);
2438 if (status == MagickFalse)
2439 draw_info->fill_pattern=GetImageCache(image_info,argv[1],
2440 exception);
2441 break;
2442 }
2443 if (LocaleCompare("flip",argv[0]+1) == 0)
2444 {
2445 /*
2446 Flip image scanlines.
2447 */
2448 (void) SyncImageSettings(image_info,*image);
2449 new_image=FlipImage(*image,exception);
2450 break;
2451 }
2452 if (LocaleCompare("flop",argv[0]+1) == 0)
2453 {
2454 /*
2455 Flop image scanlines.
2456 */
2457 (void) SyncImageSettings(image_info,*image);
2458 new_image=FlopImage(*image,exception);
2459 break;
2460 }
2461 if (LocaleCompare("floodfill",argv[0]+1) == 0)
2462 {
2463 PixelInfo
2464 target;
2465
2466 /*
2467 Floodfill image.
2468 */
2469 (void) SyncImageSettings(image_info,*image);
2470 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
2471 (void) QueryMagickColor(argv[2],&target,exception);
2472 (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
2473 geometry.y,*argv[0] == '-' ? MagickFalse : MagickTrue,exception);
2474 break;
2475 }
2476 if (LocaleCompare("font",argv[0]+1) == 0)
2477 {
2478 if (*argv[0] == '+')
2479 {
2480 if (draw_info->font != (char *) NULL)
2481 draw_info->font=DestroyString(draw_info->font);
2482 break;
2483 }
2484 (void) CloneString(&draw_info->font,argv[1]);
2485 break;
2486 }
2487 if (LocaleCompare("format",argv[0]+1) == 0)
2488 {
2489 format=argv[1];
2490 break;
2491 }
2492 if (LocaleCompare("frame",argv[0]+1) == 0)
2493 {
2494 FrameInfo
2495 frame_info;
2496
2497 /*
2498 Surround image with an ornamental border.
2499 */
2500 (void) SyncImageSettings(image_info,*image);
2501 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
2502 frame_info.width=geometry.width;
2503 frame_info.height=geometry.height;
2504 if ((flags & HeightValue) == 0)
2505 frame_info.height=geometry.width;
2506 frame_info.outer_bevel=geometry.x;
2507 frame_info.inner_bevel=geometry.y;
2508 frame_info.x=(ssize_t) frame_info.width;
2509 frame_info.y=(ssize_t) frame_info.height;
2510 frame_info.width=(*image)->columns+2*frame_info.width;
2511 frame_info.height=(*image)->rows+2*frame_info.height;
2512 new_image=FrameImage(*image,&frame_info,exception);
2513 break;
2514 }
2515 if (LocaleCompare("function",argv[0]+1) == 0)
2516 {
2517 char
2518 *arguments,
2519 token[MaxTextExtent];
2520
2521 const char
2522 *p;
2523
2524 double
2525 *parameters;
2526
2527 MagickFunction
2528 function;
2529
2530 register ssize_t
2531 x;
2532
2533 size_t
2534 number_parameters;
2535
2536 /*
2537 Function Modify Image Values
2538 */
2539 (void) SyncImageSettings(image_info,*image);
2540 function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
2541 MagickFalse,argv[1]);
2542 arguments=InterpretImageProperties(image_info,*image,argv[2],
2543 exception);
2544 if (arguments == (char *) NULL)
2545 break;
2546 p=(char *) arguments;
2547 for (x=0; *p != '\0'; x++)
2548 {
2549 GetMagickToken(p,&p,token);
2550 if (*token == ',')
2551 GetMagickToken(p,&p,token);
2552 }
2553 number_parameters=(size_t) x;
2554 parameters=(double *) AcquireQuantumMemory(number_parameters,
2555 sizeof(*parameters));
2556 if (parameters == (double *) NULL)
2557 ThrowWandFatalException(ResourceLimitFatalError,
2558 "MemoryAllocationFailed",(*image)->filename);
2559 (void) ResetMagickMemory(parameters,0,number_parameters*
2560 sizeof(*parameters));
2561 p=(char *) arguments;
2562 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
2563 {
2564 GetMagickToken(p,&p,token);
2565 if (*token == ',')
2566 GetMagickToken(p,&p,token);
2567 parameters[x]=InterpretLocaleValue(token,(char **) NULL);
2568 }
2569 arguments=DestroyString(arguments);
2570 (void) FunctionImage(*image,function,number_parameters,parameters,
2571 exception);
2572 parameters=(double *) RelinquishMagickMemory(parameters);
2573 break;
2574 }
2575 break;
2576 }
2577 case 'g':
2578 {
2579 if (LocaleCompare("gamma",argv[0]+1) == 0)
2580 {
2581 /*
2582 Gamma image.
2583 */
2584 (void) SyncImageSettings(image_info,*image);
2585 if (*argv[0] == '+')
2586 (*image)->gamma=InterpretLocaleValue(argv[1],(char **) NULL);
2587 else
2588 (void) GammaImage(*image,InterpretLocaleValue(argv[1],
2589 (char **) NULL),exception);
2590 break;
2591 }
2592 if ((LocaleCompare("gaussian-blur",argv[0]+1) == 0) ||
2593 (LocaleCompare("gaussian",argv[0]+1) == 0))
2594 {
2595 /*
2596 Gaussian blur image.
2597 */
2598 (void) SyncImageSettings(image_info,*image);
2599 flags=ParseGeometry(argv[1],&geometry_info);
2600 if ((flags & SigmaValue) == 0)
2601 geometry_info.sigma=1.0;
2602 if ((flags & XiValue) == 0)
2603 geometry_info.xi=0.0;
2604 new_image=GaussianBlurImage(*image,geometry_info.rho,
2605 geometry_info.sigma,geometry_info.xi,exception);
2606 break;
2607 }
2608 if (LocaleCompare("geometry",argv[0]+1) == 0)
2609 {
2610 /*
2611 Record Image offset, Resize last image.
2612 */
2613 (void) SyncImageSettings(image_info,*image);
2614 if (*argv[0] == '+')
2615 {
2616 if ((*image)->geometry != (char *) NULL)
2617 (*image)->geometry=DestroyString((*image)->geometry);
2618 break;
2619 }
2620 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2621 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2622 (void) CloneString(&(*image)->geometry,argv[1]);
2623 else
2624 new_image=ResizeImage(*image,geometry.width,geometry.height,
2625 (*image)->filter,(*image)->blur,exception);
2626 break;
2627 }
2628 if (LocaleCompare("gravity",argv[0]+1) == 0)
2629 {
2630 if (*argv[0] == '+')
2631 {
2632 draw_info->gravity=UndefinedGravity;
2633 break;
2634 }
2635 draw_info->gravity=(GravityType) ParseCommandOption(
2636 MagickGravityOptions,MagickFalse,argv[1]);
2637 break;
2638 }
2639 break;
2640 }
2641 case 'h':
2642 {
2643 if (LocaleCompare("highlight-color",argv[0]+1) == 0)
2644 {
2645 (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
2646 break;
2647 }
2648 break;
2649 }
2650 case 'i':
2651 {
2652 if (LocaleCompare("identify",argv[0]+1) == 0)
2653 {
2654 char
2655 *text;
2656
2657 (void) SyncImageSettings(image_info,*image);
2658 if (format == (char *) NULL)
2659 {
2660 (void) IdentifyImage(*image,stdout,image_info->verbose,
2661 exception);
2662 break;
2663 }
2664 text=InterpretImageProperties(image_info,*image,format,
2665 exception);
2666 if (text == (char *) NULL)
2667 break;
2668 (void) fputs(text,stdout);
2669 (void) fputc('\n',stdout);
2670 text=DestroyString(text);
2671 break;
2672 }
2673 if (LocaleCompare("implode",argv[0]+1) == 0)
2674 {
2675 /*
2676 Implode image.
2677 */
2678 (void) SyncImageSettings(image_info,*image);
2679 (void) ParseGeometry(argv[1],&geometry_info);
2680 new_image=ImplodeImage(*image,geometry_info.rho,exception);
2681 break;
2682 }
2683 if (LocaleCompare("interline-spacing",argv[0]+1) == 0)
2684 {
2685 if (*argv[0] == '+')
2686 (void) ParseGeometry("0",&geometry_info);
2687 else
2688 (void) ParseGeometry(argv[1],&geometry_info);
2689 draw_info->interline_spacing=geometry_info.rho;
2690 break;
2691 }
2692 if (LocaleCompare("interword-spacing",argv[0]+1) == 0)
2693 {
2694 if (*argv[0] == '+')
2695 (void) ParseGeometry("0",&geometry_info);
2696 else
2697 (void) ParseGeometry(argv[1],&geometry_info);
2698 draw_info->interword_spacing=geometry_info.rho;
2699 break;
2700 }
2701 break;
2702 }
2703 case 'k':
2704 {
2705 if (LocaleCompare("kerning",argv[0]+1) == 0)
2706 {
2707 if (*argv[0] == '+')
2708 (void) ParseGeometry("0",&geometry_info);
2709 else
2710 (void) ParseGeometry(argv[1],&geometry_info);
2711 draw_info->kerning=geometry_info.rho;
2712 break;
2713 }
2714 break;
2715 }
2716 case 'l':
2717 {
2718 if (LocaleCompare("lat",argv[0]+1) == 0)
2719 {
2720 /*
2721 Local adaptive threshold image.
2722 */
2723 (void) SyncImageSettings(image_info,*image);
2724 flags=ParseGeometry(argv[1],&geometry_info);
2725 if ((flags & PercentValue) != 0)
2726 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2727 new_image=AdaptiveThresholdImage(*image,(size_t)
2728 geometry_info.rho,(size_t) geometry_info.sigma,(double)
2729 geometry_info.xi,exception);
2730 break;
2731 }
2732 if (LocaleCompare("level",argv[0]+1) == 0)
2733 {
2734 MagickRealType
2735 black_point,
2736 gamma,
2737 white_point;
2738
2739 MagickStatusType
2740 flags;
2741
2742 /*
2743 Parse levels.
2744 */
2745 (void) SyncImageSettings(image_info,*image);
2746 flags=ParseGeometry(argv[1],&geometry_info);
2747 black_point=geometry_info.rho;
2748 white_point=(MagickRealType) QuantumRange;
2749 if ((flags & SigmaValue) != 0)
2750 white_point=geometry_info.sigma;
2751 gamma=1.0;
2752 if ((flags & XiValue) != 0)
2753 gamma=geometry_info.xi;
2754 if ((flags & PercentValue) != 0)
2755 {
2756 black_point*=(MagickRealType) (QuantumRange/100.0);
2757 white_point*=(MagickRealType) (QuantumRange/100.0);
2758 }
2759 if ((flags & SigmaValue) == 0)
2760 white_point=(MagickRealType) QuantumRange-black_point;
2761 if ((*argv[0] == '+') || ((flags & AspectValue) != 0))
2762 (void) LevelizeImage(*image,black_point,white_point,gamma,
2763 exception);
2764 else
2765 (void) LevelImage(*image,black_point,white_point,gamma,
2766 exception);
2767 InheritException(exception,&(*image)->exception);
2768 break;
2769 }
2770 if (LocaleCompare("level-colors",argv[0]+1) == 0)
2771 {
2772 char
2773 token[MaxTextExtent];
2774
2775 const char
2776 *p;
2777
2778 PixelInfo
2779 black_point,
2780 white_point;
2781
2782 p=(const char *) argv[1];
2783 GetMagickToken(p,&p,token); /* get black point color */
2784 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2785 (void) QueryMagickColor(token,&black_point,exception);
2786 else
2787 (void) QueryMagickColor("#000000",&black_point,exception);
2788 if (isalpha((int) token[0]) || (token[0] == '#'))
2789 GetMagickToken(p,&p,token);
2790 if (*token == '\0')
2791 white_point=black_point; /* set everything to that color */
2792 else
2793 {
2794 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2795 GetMagickToken(p,&p,token); /* Get white point color. */
2796 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2797 (void) QueryMagickColor(token,&white_point,exception);
2798 else
2799 (void) QueryMagickColor("#ffffff",&white_point,exception);
2800 }
2801 (void) LevelImageColors(*image,&black_point,&white_point,
2802 *argv[0] == '+' ? MagickTrue : MagickFalse,exception);
2803 break;
2804 }
2805 if (LocaleCompare("linear-stretch",argv[0]+1) == 0)
2806 {
2807 double
2808 black_point,
2809 white_point;
2810
2811 MagickStatusType
2812 flags;
2813
2814 (void) SyncImageSettings(image_info,*image);
2815 flags=ParseGeometry(argv[1],&geometry_info);
2816 black_point=geometry_info.rho;
2817 white_point=(MagickRealType) (*image)->columns*(*image)->rows;
2818 if ((flags & SigmaValue) != 0)
2819 white_point=geometry_info.sigma;
2820 if ((flags & PercentValue) != 0)
2821 {
2822 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2823 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2824 }
2825 if ((flags & SigmaValue) == 0)
2826 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2827 black_point;
2828 (void) LinearStretchImage(*image,black_point,white_point,exception);
2829 InheritException(exception,&(*image)->exception);
2830 break;
2831 }
2832 if (LocaleCompare("linewidth",argv[0]+1) == 0)
2833 {
2834 draw_info->stroke_width=InterpretLocaleValue(argv[1],
2835 (char **) NULL);
2836 break;
2837 }
2838 if (LocaleCompare("liquid-rescale",argv[0]+1) == 0)
2839 {
2840 /*
2841 Liquid rescale image.
2842 */
2843 (void) SyncImageSettings(image_info,*image);
2844 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2845 if ((flags & XValue) == 0)
2846 geometry.x=1;
2847 if ((flags & YValue) == 0)
2848 geometry.y=0;
2849 new_image=LiquidRescaleImage(*image,geometry.width,
2850 geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
2851 break;
2852 }
2853 if (LocaleCompare("lowlight-color",argv[0]+1) == 0)
2854 {
2855 (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
2856 break;
2857 }
2858 break;
2859 }
2860 case 'm':
2861 {
2862 if (LocaleCompare("map",argv[0]+1) == 0)
2863 {
2864 Image
2865 *remap_image;
2866
2867 /*
2868 Transform image colors to match this set of colors.
2869 */
2870 (void) SyncImageSettings(image_info,*image);
2871 if (*argv[0] == '+')
2872 break;
2873 remap_image=GetImageCache(image_info,argv[1],exception);
2874 if (remap_image == (Image *) NULL)
2875 break;
2876 (void) RemapImage(quantize_info,*image,remap_image,exception);
2877 remap_image=DestroyImage(remap_image);
2878 break;
2879 }
2880 if (LocaleCompare("mask",argv[0]+1) == 0)
2881 {
2882 Image
2883 *mask;
2884
2885 (void) SyncImageSettings(image_info,*image);
2886 if (*argv[0] == '+')
2887 {
2888 /*
2889 Remove a mask.
2890 */
2891 (void) SetImageMask(*image,(Image *) NULL,exception);
2892 break;
2893 }
2894 /*
2895 Set the image mask.
2896 */
2897 mask=GetImageCache(image_info,argv[1],exception);
2898 if (mask == (Image *) NULL)
2899 break;
2900 (void) SetImageMask(*image,mask,exception);
2901 mask=DestroyImage(mask);
2902 break;
2903 }
2904 if (LocaleCompare("matte",argv[0]+1) == 0)
2905 {
2906 (void) SetImageAlphaChannel(*image,(*argv[0] == '-') ?
2907 SetAlphaChannel : DeactivateAlphaChannel,exception);
2908 break;
2909 }
2910 if (LocaleCompare("median",argv[0]+1) == 0)
2911 {
2912 /*
2913 Median filter image.
2914 */
2915 (void) SyncImageSettings(image_info,*image);
2916 flags=ParseGeometry(argv[1],&geometry_info);
2917 if ((flags & SigmaValue) == 0)
2918 geometry_info.sigma=geometry_info.rho;
2919 new_image=StatisticImage(*image,MedianStatistic,(size_t)
2920 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2921 break;
2922 }
2923 if (LocaleCompare("mode",argv[0]+1) == 0)
2924 {
2925 /*
2926 Mode image.
2927 */
2928 (void) SyncImageSettings(image_info,*image);
2929 flags=ParseGeometry(argv[1],&geometry_info);
2930 if ((flags & SigmaValue) == 0)
2931 geometry_info.sigma=geometry_info.rho;
2932 new_image=StatisticImage(*image,ModeStatistic,(size_t)
2933 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2934 break;
2935 }
2936 if (LocaleCompare("modulate",argv[0]+1) == 0)
2937 {
2938 (void) SyncImageSettings(image_info,*image);
2939 (void) ModulateImage(*image,argv[1],exception);
2940 break;
2941 }
2942 if (LocaleCompare("monitor",argv[0]+1) == 0)
2943 {
2944 if (*argv[0] == '+')
2945 {
2946 (void) SetImageProgressMonitor(*image,
2947 (MagickProgressMonitor) NULL,(void *) NULL);
2948 break;
2949 }
2950 (void) SetImageProgressMonitor(*image,MonitorProgress,
2951 (void *) NULL);
2952 break;
2953 }
2954 if (LocaleCompare("monochrome",argv[0]+1) == 0)
2955 {
2956 (void) SyncImageSettings(image_info,*image);
2957 (void) SetImageType(*image,BilevelType,exception);
2958 break;
2959 }
2960 if (LocaleCompare("morphology",argv[0]+1) == 0)
2961 {
2962 char
2963 token[MaxTextExtent];
2964
2965 const char
2966 *p;
2967
2968 KernelInfo
2969 *kernel;
2970
2971 MorphologyMethod
2972 method;
2973
2974 ssize_t
2975 iterations;
2976
2977 /*
2978 Morphological Image Operation
2979 */
2980 (void) SyncImageSettings(image_info,*image);
2981 p=argv[1];
2982 GetMagickToken(p,&p,token);
2983 method=(MorphologyMethod) ParseCommandOption(
2984 MagickMorphologyOptions,MagickFalse,token);
2985 iterations=1L;
2986 GetMagickToken(p,&p,token);
2987 if ((*p == ':') || (*p == ','))
2988 GetMagickToken(p,&p,token);
2989 if ((*p != '\0'))
2990 iterations=(ssize_t) StringToLong(p);
2991 kernel=AcquireKernelInfo(argv[2]);
2992 if (kernel == (KernelInfo *) NULL)
2993 {
2994 (void) ThrowMagickException(exception,GetMagickModule(),
2995 OptionError,"UnabletoParseKernel","morphology");
2996 status=MagickFalse;
2997 break;
2998 }
2999 new_image=MorphologyImage(*image,method,iterations,kernel,
3000 exception);
3001 kernel=DestroyKernelInfo(kernel);
3002 break;
3003 }
3004 if (LocaleCompare("motion-blur",argv[0]+1) == 0)
3005 {
3006 /*
3007 Motion blur image.
3008 */
3009 (void) SyncImageSettings(image_info,*image);
3010 flags=ParseGeometry(argv[1],&geometry_info);
3011 if ((flags & SigmaValue) == 0)
3012 geometry_info.sigma=1.0;
3013 new_image=MotionBlurImage(*image,geometry_info.rho,
3014 geometry_info.sigma,geometry_info.xi,geometry_info.psi,
3015 exception);
3016 break;
3017 }
3018 break;
3019 }
3020 case 'n':
3021 {
3022 if (LocaleCompare("negate",argv[0]+1) == 0)
3023 {
3024 (void) SyncImageSettings(image_info,*image);
3025 (void) NegateImage(*image,*argv[0] == '+' ? MagickTrue :
3026 MagickFalse,exception);
3027 break;
3028 }
3029 if (LocaleCompare("noise",argv[0]+1) == 0)
3030 {
3031 (void) SyncImageSettings(image_info,*image);
3032 if (*argv[0] == '-')
3033 {
3034 flags=ParseGeometry(argv[1],&geometry_info);
3035 if ((flags & SigmaValue) == 0)
3036 geometry_info.sigma=geometry_info.rho;
3037 new_image=StatisticImage(*image,NonpeakStatistic,(size_t)
3038 geometry_info.rho,(size_t) geometry_info.sigma,exception);
3039 }
3040 else
3041 {
3042 NoiseType
3043 noise;
3044
3045 noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
3046 MagickFalse,argv[1]);
3047 new_image=AddNoiseImage(*image,noise,exception);
3048 }
3049 break;
3050 }
3051 if (LocaleCompare("normalize",argv[0]+1) == 0)
3052 {
3053 (void) SyncImageSettings(image_info,*image);
3054 (void) NormalizeImage(*image,exception);
3055 break;
3056 }
3057 break;
3058 }
3059 case 'o':
3060 {
3061 if (LocaleCompare("opaque",argv[0]+1) == 0)
3062 {
3063 PixelInfo
3064 target;
3065
3066 (void) SyncImageSettings(image_info,*image);
3067 (void) QueryMagickColor(argv[1],&target,exception);
3068 (void) OpaquePaintImage(*image,&target,&fill,*argv[0] == '-' ?
3069 MagickFalse : MagickTrue,exception);
3070 break;
3071 }
3072 if (LocaleCompare("ordered-dither",argv[0]+1) == 0)
3073 {
3074 (void) SyncImageSettings(image_info,*image);
3075 (void) OrderedPosterizeImage(*image,argv[1],exception);
3076 break;
3077 }
3078 break;
3079 }
3080 case 'p':
3081 {
3082 if (LocaleCompare("paint",argv[0]+1) == 0)
3083 {
3084 (void) SyncImageSettings(image_info,*image);
3085 (void) ParseGeometry(argv[1],&geometry_info);
3086 new_image=OilPaintImage(*image,geometry_info.rho,
3087 geometry_info.sigma,exception);
3088 break;
3089 }
3090 if (LocaleCompare("pen",argv[0]+1) == 0)
3091 {
3092 if (*argv[0] == '+')
3093 {
3094 (void) QueryColorDatabase("none",&draw_info->fill,exception);
3095 break;
3096 }
3097 (void) QueryColorDatabase(argv[1],&draw_info->fill,exception);
3098 break;
3099 }
3100 if (LocaleCompare("pointsize",argv[0]+1) == 0)
3101 {
3102 if (*argv[0] == '+')
3103 (void) ParseGeometry("12",&geometry_info);
3104 else
3105 (void) ParseGeometry(argv[1],&geometry_info);
3106 draw_info->pointsize=geometry_info.rho;
3107 break;
3108 }
3109 if (LocaleCompare("polaroid",argv[0]+1) == 0)
3110 {
3111 double
3112 angle;
3113
3114 RandomInfo
3115 *random_info;
3116
3117 /*
3118 Simulate a Polaroid picture.
3119 */
3120 (void) SyncImageSettings(image_info,*image);
3121 random_info=AcquireRandomInfo();
3122 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
3123 random_info=DestroyRandomInfo(random_info);
3124 if (*argv[0] == '-')
3125 {
3126 SetGeometryInfo(&geometry_info);
3127 flags=ParseGeometry(argv[1],&geometry_info);
3128 angle=geometry_info.rho;
3129 }
3130 new_image=PolaroidImage(*image,draw_info,angle,
3131 interpolate_method,exception);
3132 break;
3133 }
3134 if (LocaleCompare("posterize",argv[0]+1) == 0)
3135 {
3136 /*
3137 Posterize image.
3138 */
3139 (void) SyncImageSettings(image_info,*image);
3140 (void) PosterizeImage(*image,StringToUnsignedLong(argv[1]),
3141 quantize_info->dither,exception);
3142 break;
3143 }
3144 if (LocaleCompare("preview",argv[0]+1) == 0)
3145 {
3146 PreviewType
3147 preview_type;
3148
3149 /*
3150 Preview image.
3151 */
3152 (void) SyncImageSettings(image_info,*image);
3153 if (*argv[0] == '+')
3154 preview_type=UndefinedPreview;
3155 else
3156 preview_type=(PreviewType) ParseCommandOption(
3157 MagickPreviewOptions,MagickFalse,argv[1]);
3158 new_image=PreviewImage(*image,preview_type,exception);
3159 break;
3160 }
3161 if (LocaleCompare("profile",argv[0]+1) == 0)
3162 {
3163 const char
3164 *name;
3165
3166 const StringInfo
3167 *profile;
3168
3169 Image
3170 *profile_image;
3171
3172 ImageInfo
3173 *profile_info;
3174
3175 (void) SyncImageSettings(image_info,*image);
3176 if (*argv[0] == '+')
3177 {
3178 /*
3179 Remove a profile from the image.
3180 */
3181 (void) ProfileImage(*image,argv[1],(const unsigned char *)
3182 NULL,0,MagickTrue);
3183 InheritException(exception,&(*image)->exception);
3184 break;
3185 }
3186 /*
3187 Associate a profile with the image.
3188 */
3189 profile_info=CloneImageInfo(image_info);
3190 profile=GetImageProfile(*image,"iptc");
3191 if (profile != (StringInfo *) NULL)
3192 profile_info->profile=(void *) CloneStringInfo(profile);
3193 profile_image=GetImageCache(profile_info,argv[1],exception);
3194 profile_info=DestroyImageInfo(profile_info);
3195 if (profile_image == (Image *) NULL)
3196 {
3197 StringInfo
3198 *profile;
3199
3200 profile_info=CloneImageInfo(image_info);
3201 (void) CopyMagickString(profile_info->filename,argv[1],
3202 MaxTextExtent);
3203 profile=FileToStringInfo(profile_info->filename,~0UL,exception);
3204 if (profile != (StringInfo *) NULL)
3205 {
3206 (void) ProfileImage(*image,profile_info->magick,
3207 GetStringInfoDatum(profile),(size_t)
3208 GetStringInfoLength(profile),MagickFalse);
3209 profile=DestroyStringInfo(profile);
3210 }
3211 profile_info=DestroyImageInfo(profile_info);
3212 break;
3213 }
3214 ResetImageProfileIterator(profile_image);
3215 name=GetNextImageProfile(profile_image);
3216 while (name != (const char *) NULL)
3217 {
3218 profile=GetImageProfile(profile_image,name);
3219 if (profile != (StringInfo *) NULL)
3220 (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
3221 (size_t) GetStringInfoLength(profile),MagickFalse);
3222 name=GetNextImageProfile(profile_image);
3223 }
3224 profile_image=DestroyImage(profile_image);
3225 break;
3226 }
3227 break;
3228 }
3229 case 'q':
3230 {
3231 if (LocaleCompare("quantize",argv[0]+1) == 0)
3232 {
3233 if (*argv[0] == '+')
3234 {
3235 quantize_info->colorspace=UndefinedColorspace;
3236 break;
3237 }
3238 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
3239 MagickColorspaceOptions,MagickFalse,argv[1]);
3240 break;
3241 }
3242 break;
3243 }
3244 case 'r':
3245 {
3246 if (LocaleCompare("radial-blur",argv[0]+1) == 0)
3247 {
3248 /*
3249 Radial blur image.
3250 */
3251 (void) SyncImageSettings(image_info,*image);
3252 flags=ParseGeometry(argv[1],&geometry_info);
3253 new_image=RadialBlurImage(*image,geometry_info.rho,
3254 geometry_info.sigma,exception);
3255 break;
3256 }
3257 if (LocaleCompare("raise",argv[0]+1) == 0)
3258 {
3259 /*
3260 Surround image with a raise of solid color.
3261 */
3262 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3263 if ((flags & SigmaValue) == 0)
3264 geometry.height=geometry.width;
3265 (void) RaiseImage(*image,&geometry,*argv[0] == '-' ? MagickTrue :
3266 MagickFalse,exception);
3267 break;
3268 }
3269 if (LocaleCompare("random-threshold",argv[0]+1) == 0)
3270 {
3271 /*
3272 Threshold image.
3273 */
3274 (void) SyncImageSettings(image_info,*image);
3275 (void) RandomThresholdImage(*image,argv[1],exception);
3276 break;
3277 }
3278 if (LocaleCompare("recolor",argv[0]+1) == 0)
3279 {
3280 KernelInfo
3281 *kernel;
3282
3283 (void) SyncImageSettings(image_info,*image);
3284 kernel=AcquireKernelInfo(argv[1]);
3285 if (kernel == (KernelInfo *) NULL)
3286 break;
3287 new_image=ColorMatrixImage(*image,kernel,exception);
3288 kernel=DestroyKernelInfo(kernel);
3289 break;
3290 }
3291 if (LocaleCompare("render",argv[0]+1) == 0)
3292 {
3293 (void) SyncImageSettings(image_info,*image);
3294 draw_info->render=(*argv[0] == '+') ? MagickTrue : MagickFalse;
3295 break;
3296 }
3297 if (LocaleCompare("remap",argv[0]+1) == 0)
3298 {
3299 Image
3300 *remap_image;
3301
3302 /*
3303 Transform image colors to match this set of colors.
3304 */
3305 (void) SyncImageSettings(image_info,*image);
3306 if (*argv[0] == '+')
3307 break;
3308 remap_image=GetImageCache(image_info,argv[1],exception);
3309 if (remap_image == (Image *) NULL)
3310 break;
3311 (void) RemapImage(quantize_info,*image,remap_image,exception);
3312 remap_image=DestroyImage(remap_image);
3313 break;
3314 }
3315 if (LocaleCompare("repage",argv[0]+1) == 0)
3316 {
3317 if (*argv[0] == '+')
3318 {
3319 (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
3320 break;
3321 }
3322 (void) ResetImagePage(*image,argv[1]);
3323 InheritException(exception,&(*image)->exception);
3324 break;
3325 }
3326 if (LocaleCompare("resample",argv[0]+1) == 0)
3327 {
3328 /*
3329 Resample image.
3330 */
3331 (void) SyncImageSettings(image_info,*image);
3332 flags=ParseGeometry(argv[1],&geometry_info);
3333 if ((flags & SigmaValue) == 0)
3334 geometry_info.sigma=geometry_info.rho;
3335 new_image=ResampleImage(*image,geometry_info.rho,
3336 geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
3337 break;
3338 }
3339 if (LocaleCompare("resize",argv[0]+1) == 0)
3340 {
3341 /*
3342 Resize image.
3343 */
3344 (void) SyncImageSettings(image_info,*image);
3345 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3346 new_image=ResizeImage(*image,geometry.width,geometry.height,
3347 (*image)->filter,(*image)->blur,exception);
3348 break;
3349 }
3350 if (LocaleCompare("roll",argv[0]+1) == 0)
3351 {
3352 /*
3353 Roll image.
3354 */
3355 (void) SyncImageSettings(image_info,*image);
3356 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
3357 new_image=RollImage(*image,geometry.x,geometry.y,exception);
3358 break;
3359 }
3360 if (LocaleCompare("rotate",argv[0]+1) == 0)
3361 {
3362 char
3363 *geometry;
3364
3365 /*
3366 Check for conditional image rotation.
3367 */
3368 (void) SyncImageSettings(image_info,*image);
3369 if (strchr(argv[1],'>') != (char *) NULL)
3370 if ((*image)->columns <= (*image)->rows)
3371 break;
3372 if (strchr(argv[1],'<') != (char *) NULL)
3373 if ((*image)->columns >= (*image)->rows)
3374 break;
3375 /*
3376 Rotate image.
3377 */
3378 geometry=ConstantString(argv[1]);
3379 (void) SubstituteString(&geometry,">","");
3380 (void) SubstituteString(&geometry,"<","");
3381 (void) ParseGeometry(geometry,&geometry_info);
3382 geometry=DestroyString(geometry);
3383 new_image=RotateImage(*image,geometry_info.rho,exception);
3384 break;
3385 }
3386 break;
3387 }
3388 case 's':
3389 {
3390 if (LocaleCompare("sample",argv[0]+1) == 0)
3391 {
3392 /*
3393 Sample image with pixel replication.
3394 */
3395 (void) SyncImageSettings(image_info,*image);
3396 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3397 new_image=SampleImage(*image,geometry.width,geometry.height,
3398 exception);
3399 break;
3400 }
3401 if (LocaleCompare("scale",argv[0]+1) == 0)
3402 {
3403 /*
3404 Resize image.
3405 */
3406 (void) SyncImageSettings(image_info,*image);
3407 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3408 new_image=ScaleImage(*image,geometry.width,geometry.height,
3409 exception);
3410 break;
3411 }
3412 if (LocaleCompare("selective-blur",argv[0]+1) == 0)
3413 {
3414 /*
3415 Selectively blur pixels within a contrast threshold.
3416 */
3417 (void) SyncImageSettings(image_info,*image);
3418 flags=ParseGeometry(argv[1],&geometry_info);
3419 if ((flags & PercentValue) != 0)
3420 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3421 new_image=SelectiveBlurImage(*image,geometry_info.rho,
3422 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3423 break;
3424 }
3425 if (LocaleCompare("separate",argv[0]+1) == 0)
3426 {
3427 /*
3428 Break channels into separate images.
3429 WARNING: This can generate multiple images!
3430 */
3431 (void) SyncImageSettings(image_info,*image);
3432 new_image=SeparateImages(*image,exception);
3433 break;
3434 }
3435 if (LocaleCompare("sepia-tone",argv[0]+1) == 0)
3436 {
3437 double
3438 threshold;
3439
3440 /*
3441 Sepia-tone image.
3442 */
3443 (void) SyncImageSettings(image_info,*image);
3444 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3445 new_image=SepiaToneImage(*image,threshold,exception);
3446 break;
3447 }
3448 if (LocaleCompare("segment",argv[0]+1) == 0)
3449 {
3450 /*
3451 Segment image.
3452 */
3453 (void) SyncImageSettings(image_info,*image);
3454 flags=ParseGeometry(argv[1],&geometry_info);
3455 if ((flags & SigmaValue) == 0)
3456 geometry_info.sigma=1.0;
3457 (void) SegmentImage(*image,(*image)->colorspace,
3458 image_info->verbose,geometry_info.rho,geometry_info.sigma,
3459 exception);
3460 break;
3461 }
3462 if (LocaleCompare("set",argv[0]+1) == 0)
3463 {
3464 char
3465 *value;
3466
3467 /*
3468 Set image argv[0].
3469 */
3470 if (*argv[0] == '+')
3471 {
3472 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3473 (void) DeleteImageRegistry(argv[1]+9);
3474 else
3475 if (LocaleNCompare(argv[1],"argv[0]:",7) == 0)
3476 {
3477 (void) DeleteImageOption(image_info,argv[1]+7);
3478 (void) DeleteImageArtifact(*image,argv[1]+7);
3479 }
3480 else
3481 (void) DeleteImageProperty(*image,argv[1]);
3482 break;
3483 }
3484 value=InterpretImageProperties(image_info,*image,argv[2],
3485 exception);
3486 if (value == (char *) NULL)
3487 break;
3488 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3489 (void) SetImageRegistry(StringRegistryType,argv[1]+9,value,
3490 exception);
3491 else
3492 if (LocaleNCompare(argv[1],"argv[0]:",7) == 0)
3493 {
3494 (void) SetImageOption(image_info,argv[1]+7,value);
3495 (void) SetImageOption(image_info,argv[1]+7,value);
3496 (void) SetImageArtifact(*image,argv[1]+7,value);
3497 }
3498 else
3499 (void) SetImageProperty(*image,argv[1],value);
3500 value=DestroyString(value);
3501 break;
3502 }
3503 if (LocaleCompare("shade",argv[0]+1) == 0)
3504 {
3505 /*
3506 Shade image.
3507 */
3508 (void) SyncImageSettings(image_info,*image);
3509 flags=ParseGeometry(argv[1],&geometry_info);
3510 if ((flags & SigmaValue) == 0)
3511 geometry_info.sigma=1.0;
3512 new_image=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue :
3513 MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
3514 break;
3515 }
3516 if (LocaleCompare("shadow",argv[0]+1) == 0)
3517 {
3518 /*
3519 Shadow image.
3520 */
3521 (void) SyncImageSettings(image_info,*image);
3522 flags=ParseGeometry(argv[1],&geometry_info);
3523 if ((flags & SigmaValue) == 0)
3524 geometry_info.sigma=1.0;
3525 if ((flags & XiValue) == 0)
3526 geometry_info.xi=4.0;
3527 if ((flags & PsiValue) == 0)
3528 geometry_info.psi=4.0;
3529 new_image=ShadowImage(*image,geometry_info.rho,
3530 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3531 ceil(geometry_info.psi-0.5),exception);
3532 break;
3533 }
3534 if (LocaleCompare("sharpen",argv[0]+1) == 0)
3535 {
3536 /*
3537 Sharpen image.
3538 */
3539 (void) SyncImageSettings(image_info,*image);
3540 flags=ParseGeometry(argv[1],&geometry_info);
3541 if ((flags & SigmaValue) == 0)
3542 geometry_info.sigma=1.0;
3543 if ((flags & XiValue) == 0)
3544 geometry_info.xi=0.0;
3545 new_image=SharpenImage(*image,geometry_info.rho,
3546 geometry_info.sigma,geometry_info.xi,exception);
3547 break;
3548 }
3549 if (LocaleCompare("shave",argv[0]+1) == 0)
3550 {
3551 /*
3552 Shave the image edges.
3553 */
3554 (void) SyncImageSettings(image_info,*image);
3555 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3556 new_image=ShaveImage(*image,&geometry,exception);
3557 break;
3558 }
3559 if (LocaleCompare("shear",argv[0]+1) == 0)
3560 {
3561 /*
3562 Shear image.
3563 */
3564 (void) SyncImageSettings(image_info,*image);
3565 flags=ParseGeometry(argv[1],&geometry_info);
3566 if ((flags & SigmaValue) == 0)
3567 geometry_info.sigma=geometry_info.rho;
3568 new_image=ShearImage(*image,geometry_info.rho,
3569 geometry_info.sigma,exception);
3570 break;
3571 }
3572 if (LocaleCompare("sigmoidal-contrast",argv[0]+1) == 0)
3573 {
3574 /*
3575 Sigmoidal non-linearity contrast control.
3576 */
3577 (void) SyncImageSettings(image_info,*image);
3578 flags=ParseGeometry(argv[1],&geometry_info);
3579 if ((flags & SigmaValue) == 0)
3580 geometry_info.sigma=(double) QuantumRange/2.0;
3581 if ((flags & PercentValue) != 0)
3582 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3583 100.0;
3584 (void) SigmoidalContrastImage(*image,(*argv[0] == '-') ?
3585 MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
3586 exception);
3587 break;
3588 }
3589 if (LocaleCompare("sketch",argv[0]+1) == 0)
3590 {
3591 /*
3592 Sketch image.
3593 */
3594 (void) SyncImageSettings(image_info,*image);
3595 flags=ParseGeometry(argv[1],&geometry_info);
3596 if ((flags & SigmaValue) == 0)
3597 geometry_info.sigma=1.0;
3598 new_image=SketchImage(*image,geometry_info.rho,
3599 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3600 break;
3601 }
3602 if (LocaleCompare("solarize",argv[0]+1) == 0)
3603 {
3604 double
3605 threshold;
3606
3607 (void) SyncImageSettings(image_info,*image);
3608 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3609 (void) SolarizeImage(*image,threshold,exception);
3610 break;
3611 }
3612 if (LocaleCompare("sparse-color",argv[0]+1) == 0)
3613 {
3614 SparseColorMethod
3615 method;
3616
3617 char
3618 *arguments;
3619
3620 /*
3621 Sparse Color Interpolated Gradient
3622 */
3623 (void) SyncImageSettings(image_info,*image);
3624 method=(SparseColorMethod) ParseCommandOption(
3625 MagickSparseColorOptions,MagickFalse,argv[1]);
3626 arguments=InterpretImageProperties(image_info,*image,argv[2],
3627 exception);
3628 if (arguments == (char *) NULL)
3629 break;
3630 new_image=SparseColorOption(*image,method,arguments,
3631 argv[0][0] == '+' ? MagickTrue : MagickFalse,exception);
3632 arguments=DestroyString(arguments);
3633 break;
3634 }
3635 if (LocaleCompare("splice",argv[0]+1) == 0)
3636 {
3637 /*
3638 Splice a solid color into the image.
3639 */
3640 (void) SyncImageSettings(image_info,*image);
3641 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
3642 new_image=SpliceImage(*image,&geometry,exception);
3643 break;
3644 }
3645 if (LocaleCompare("spread",argv[0]+1) == 0)
3646 {
3647 /*
3648 Spread an image.
3649 */
3650 (void) SyncImageSettings(image_info,*image);
3651 (void) ParseGeometry(argv[1],&geometry_info);
3652 new_image=SpreadImage(*image,geometry_info.rho,
3653 interpolate_method,exception);
3654 break;
3655 }
3656 if (LocaleCompare("statistic",argv[0]+1) == 0)
3657 {
3658 StatisticType
3659 type;
3660
3661 (void) SyncImageSettings(image_info,*image);
3662 type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
3663 MagickFalse,argv[1]);
3664 (void) ParseGeometry(argv[2],&geometry_info);
3665 new_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
3666 (size_t) geometry_info.sigma,exception);
3667 break;
3668 }
3669 if (LocaleCompare("stretch",argv[0]+1) == 0)
3670 {
3671 if (*argv[0] == '+')
3672 {
3673 draw_info->stretch=UndefinedStretch;
3674 break;
3675 }
3676 draw_info->stretch=(StretchType) ParseCommandOption(
3677 MagickStretchOptions,MagickFalse,argv[1]);
3678 break;
3679 }
3680 if (LocaleCompare("strip",argv[0]+1) == 0)
3681 {
3682 /*
3683 Strip image of profiles and comments.
3684 */
3685 (void) SyncImageSettings(image_info,*image);
3686 (void) StripImage(*image);
3687 InheritException(exception,&(*image)->exception);
3688 break;
3689 }
3690 if (LocaleCompare("stroke",argv[0]+1) == 0)
3691 {
3692 ExceptionInfo
3693 *sans;
3694
3695 if (*argv[0] == '+')
3696 {
3697 (void) QueryColorDatabase("none",&draw_info->stroke,exception);
3698 if (draw_info->stroke_pattern != (Image *) NULL)
3699 draw_info->stroke_pattern=DestroyImage(
3700 draw_info->stroke_pattern);
3701 break;
3702 }
3703 sans=AcquireExceptionInfo();
3704 status=QueryColorDatabase(argv[1],&draw_info->stroke,sans);
3705 sans=DestroyExceptionInfo(sans);
3706 if (status == MagickFalse)
3707 draw_info->stroke_pattern=GetImageCache(image_info,argv[1],
3708 exception);
3709 break;
3710 }
3711 if (LocaleCompare("strokewidth",argv[0]+1) == 0)
3712 {
3713 draw_info->stroke_width=InterpretLocaleValue(argv[1],
3714 (char **) NULL);
3715 break;
3716 }
3717 if (LocaleCompare("style",argv[0]+1) == 0)
3718 {
3719 if (*argv[0] == '+')
3720 {
3721 draw_info->style=UndefinedStyle;
3722 break;
3723 }
3724 draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
3725 MagickFalse,argv[1]);
3726 break;
3727 }
3728 if (LocaleCompare("swirl",argv[0]+1) == 0)
3729 {
3730 /*
3731 Swirl image.
3732 */
3733 (void) SyncImageSettings(image_info,*image);
3734 (void) ParseGeometry(argv[1],&geometry_info);
3735 new_image=SwirlImage(*image,geometry_info.rho,
3736 interpolate_method,exception);
3737 break;
3738 }
3739 break;
3740 }
3741 case 't':
3742 {
3743 if (LocaleCompare("threshold",argv[0]+1) == 0)
3744 {
3745 double
3746 threshold;
3747
3748 /*
3749 Threshold image.
3750 */
3751 (void) SyncImageSettings(image_info,*image);
3752 if (*argv[0] == '+')
3753 threshold=(double) QuantumRange/2;
3754 else
3755 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3756 (void) BilevelImage(*image,threshold);
3757 InheritException(exception,&(*image)->exception);
3758 break;
3759 }
3760 if (LocaleCompare("thumbnail",argv[0]+1) == 0)
3761 {
3762 /*
3763 Thumbnail image.
3764 */
3765 (void) SyncImageSettings(image_info,*image);
3766 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3767 new_image=ThumbnailImage(*image,geometry.width,geometry.height,
3768 exception);
3769 break;
3770 }
3771 if (LocaleCompare("tile",argv[0]+1) == 0)
3772 {
3773 if (*argv[0] == '+')
3774 {
3775 if (draw_info->fill_pattern != (Image *) NULL)
3776 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
3777 break;
3778 }
3779 draw_info->fill_pattern=GetImageCache(image_info,argv[1],
3780 exception);
3781 break;
3782 }
3783 if (LocaleCompare("tint",argv[0]+1) == 0)
3784 {
3785 /*
3786 Tint the image.
3787 */
3788 (void) SyncImageSettings(image_info,*image);
3789 new_image=TintImage(*image,argv[1],&fill,exception);
3790 break;
3791 }
3792 if (LocaleCompare("transform",argv[0]+1) == 0)
3793 {
3794 /*
3795 Affine transform image.
3796 */
3797 (void) SyncImageSettings(image_info,*image);
3798 new_image=AffineTransformImage(*image,&draw_info->affine,
3799 exception);
3800 break;
3801 }
3802 if (LocaleCompare("transparent",argv[0]+1) == 0)
3803 {
3804 PixelInfo
3805 target;
3806
3807 (void) SyncImageSettings(image_info,*image);
3808 (void) QueryMagickColor(argv[1],&target,exception);
3809 (void) TransparentPaintImage(*image,&target,(Quantum)
3810 TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue,
3811 &(*image)->exception);
3812 break;
3813 }
3814 if (LocaleCompare("transpose",argv[0]+1) == 0)
3815 {
3816 /*
3817 Transpose image scanlines.
3818 */
3819 (void) SyncImageSettings(image_info,*image);
3820 new_image=TransposeImage(*image,exception);
3821 break;
3822 }
3823 if (LocaleCompare("transverse",argv[0]+1) == 0)
3824 {
3825 /*
3826 Transverse image scanlines.
3827 */
3828 (void) SyncImageSettings(image_info,*image);
3829 new_image=TransverseImage(*image,exception);
3830 break;
3831 }
3832 if (LocaleCompare("treedepth",argv[0]+1) == 0)
3833 {
3834 quantize_info->tree_depth=StringToUnsignedLong(argv[1]);
3835 break;
3836 }
3837 if (LocaleCompare("trim",argv[0]+1) == 0)
3838 {
3839 /*
3840 Trim image.
3841 */
3842 (void) SyncImageSettings(image_info,*image);
3843 new_image=TrimImage(*image,exception);
3844 break;
3845 }
3846 if (LocaleCompare("type",argv[0]+1) == 0)
3847 {
3848 ImageType
3849 type;
3850
3851 (void) SyncImageSettings(image_info,*image);
3852 if (*argv[0] == '+')
3853 type=UndefinedType;
3854 else
3855 type=(ImageType) ParseCommandOption(MagickTypeOptions,MagickFalse,
3856 argv[1]);
3857 (*image)->type=UndefinedType;
3858 (void) SetImageType(*image,type,exception);
3859 break;
3860 }
3861 break;
3862 }
3863 case 'u':
3864 {
3865 if (LocaleCompare("undercolor",argv[0]+1) == 0)
3866 {
3867 (void) QueryColorDatabase(argv[1],&draw_info->undercolor,
3868 exception);
3869 break;
3870 }
3871 if (LocaleCompare("unique",argv[0]+1) == 0)
3872 {
3873 if (*argv[0] == '+')
3874 {
3875 (void) DeleteImageArtifact(*image,"identify:unique-colors");
3876 break;
3877 }
3878 (void) SetImageArtifact(*image,"identify:unique-colors","true");
3879 (void) SetImageArtifact(*image,"verbose","true");
3880 break;
3881 }
3882 if (LocaleCompare("unique-colors",argv[0]+1) == 0)
3883 {
3884 /*
3885 Unique image colors.
3886 */
3887 (void) SyncImageSettings(image_info,*image);
3888 new_image=UniqueImageColors(*image,exception);
3889 break;
3890 }
3891 if (LocaleCompare("unsharp",argv[0]+1) == 0)
3892 {
3893 /*
3894 Unsharp mask image.
3895 */
3896 (void) SyncImageSettings(image_info,*image);
3897 flags=ParseGeometry(argv[1],&geometry_info);
3898 if ((flags & SigmaValue) == 0)
3899 geometry_info.sigma=1.0;
3900 if ((flags & XiValue) == 0)
3901 geometry_info.xi=1.0;
3902 if ((flags & PsiValue) == 0)
3903 geometry_info.psi=0.05;
3904 new_image=UnsharpMaskImage(*image,geometry_info.rho,
3905 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3906 break;
3907 }
3908 break;
3909 }
3910 case 'v':
3911 {
3912 if (LocaleCompare("verbose",argv[0]+1) == 0)
3913 {
3914 (void) SetImageArtifact(*image,argv[0]+1,
3915 *argv[0] == '+' ? "false" : "true");
3916 break;
3917 }
3918 if (LocaleCompare("vignette",argv[0]+1) == 0)
3919 {
3920 /*
3921 Vignette image.
3922 */
3923 (void) SyncImageSettings(image_info,*image);
3924 flags=ParseGeometry(argv[1],&geometry_info);
3925 if ((flags & SigmaValue) == 0)
3926 geometry_info.sigma=1.0;
3927 if ((flags & XiValue) == 0)
3928 geometry_info.xi=0.1*(*image)->columns;
3929 if ((flags & PsiValue) == 0)
3930 geometry_info.psi=0.1*(*image)->rows;
3931 new_image=VignetteImage(*image,geometry_info.rho,
3932 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3933 ceil(geometry_info.psi-0.5),exception);
3934 break;
3935 }
3936 if (LocaleCompare("virtual-pixel",argv[0]+1) == 0)
3937 {
3938 if (*argv[0] == '+')
3939 {
3940 (void) SetImageVirtualPixelMethod(*image,
3941 UndefinedVirtualPixelMethod);
3942 break;
3943 }
3944 (void) SetImageVirtualPixelMethod(*image,(VirtualPixelMethod)
3945 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
3946 argv[1]));
3947 break;
3948 }
3949 break;
3950 }
3951 case 'w':
3952 {
3953 if (LocaleCompare("wave",argv[0]+1) == 0)
3954 {
3955 /*
3956 Wave image.
3957 */
3958 (void) SyncImageSettings(image_info,*image);
3959 flags=ParseGeometry(argv[1],&geometry_info);
3960 if ((flags & SigmaValue) == 0)
3961 geometry_info.sigma=1.0;
3962 new_image=WaveImage(*image,geometry_info.rho,
3963 geometry_info.sigma,exception);
3964 break;
3965 }
3966 if (LocaleCompare("weight",argv[0]+1) == 0)
3967 {
3968 draw_info->weight=StringToUnsignedLong(argv[1]);
3969 if (LocaleCompare(argv[1],"all") == 0)
3970 draw_info->weight=0;
3971 if (LocaleCompare(argv[1],"bold") == 0)
3972 draw_info->weight=700;
3973 if (LocaleCompare(argv[1],"bolder") == 0)
3974 if (draw_info->weight <= 800)
3975 draw_info->weight+=100;
3976 if (LocaleCompare(argv[1],"lighter") == 0)
3977 if (draw_info->weight >= 100)
3978 draw_info->weight-=100;
3979 if (LocaleCompare(argv[1],"normal") == 0)
3980 draw_info->weight=400;
3981 break;
3982 }
3983 if (LocaleCompare("white-threshold",argv[0]+1) == 0)
3984 {
3985 /*
3986 White threshold image.
3987 */
3988 (void) SyncImageSettings(image_info,*image);
3989 (void) WhiteThresholdImage(*image,argv[1],exception);
3990 InheritException(exception,&(*image)->exception);
3991 break;
3992 }
3993 break;
3994 }
3995 default:
3996 break;
3997 }
3998 /*
3999 Replace current image with any image that was generated
4000 */
4001 if (new_image != (Image *) NULL)
4002 ReplaceImageInListReturnLast(image,new_image);
4003
4004 /*
4005 Free resources.
4006 */
4007 quantize_info=DestroyQuantizeInfo(quantize_info);
4008 draw_info=DestroyDrawInfo(draw_info);
4009 status=(*image)->exception.severity == UndefinedException ? 1 : 0;
4010
4011 return(status);
4012}
4013
4014/*
4015%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4016% %
4017% %
4018% %
4019+ S e q u e n c e O p e r a t i o n I m a g e s %
4020% %
4021% %
4022% %
4023%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4024%
4025% SequenceOperationImages() applies a single operation that apply to the
4026% entire image list (e.g. -append, -layers, -coalesce, etc.).
4027%
4028% The format of the MogrifyImage method is:
4029%
4030% MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
4031% const int argc, const char **argv,Image **images,
4032% ExceptionInfo *exception)
4033%
4034% A description of each parameter follows:
4035%
4036% o image_info: the image info..
4037%
4038% o argc: Specifies a pointer to an integer describing the number of
4039% elements in the argument vector.
4040%
4041% o argv: Specifies a pointer to a text array containing the command line
4042% arguments.
4043%
4044% o images: pointer to pointer of the first image in image list.
4045%
4046% o exception: return any errors or warnings in this structure.
4047%
4048*/
4049WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
4050 const int argc,const char **argv,Image **images,ExceptionInfo *exception)
4051{
4052
4053 MagickStatusType
4054 status;
4055
4056 QuantizeInfo
4057 *quantize_info;
4058
4059 assert(image_info != (ImageInfo *) NULL);
4060 assert(image_info->signature == MagickSignature);
4061 assert(images != (Image **) NULL);
4062 assert((*images)->previous == (Image *) NULL);
4063 assert((*images)->signature == MagickSignature);
4064 if ((*images)->debug != MagickFalse)
4065 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
4066 (*images)->filename);
4067
4068 quantize_info=AcquireQuantizeInfo(image_info);
4069 channel=image_info->channel;
4070
4071 status=MagickTrue;
4072
4073 switch (*(argv[0]+1))
4074 {
4075 case 'a':
4076 {
4077 if (LocaleCompare("affinity",argv[0]+1) == 0)
4078 {
4079 (void) SyncImagesSettings(image_info,*images);
4080 if (*argv[0] == '+')
4081 {
4082 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4083 exception);
4084 break;
4085 }
4086 break;
4087 }
4088 if (LocaleCompare("append",argv[0]+1) == 0)
4089 {
4090 Image
4091 *append_image;
4092
4093 (void) SyncImagesSettings(image_info,*images);
4094 append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue :
4095 MagickFalse,exception);
4096 if (append_image == (Image *) NULL)
4097 {
4098 status=MagickFalse;
4099 break;
4100 }
4101 *images=DestroyImageList(*images);
4102 *images=append_image;
4103 break;
4104 }
4105 if (LocaleCompare("average",argv[0]+1) == 0)
4106 {
4107 Image
4108 *average_image;
4109
4110 /*
4111 Average an image sequence (deprecated).
4112 */
4113 (void) SyncImagesSettings(image_info,*images);
4114 average_image=EvaluateImages(*images,MeanEvaluateOperator,
4115 exception);
4116 if (average_image == (Image *) NULL)
4117 {
4118 status=MagickFalse;
4119 break;
4120 }
4121 *images=DestroyImageList(*images);
4122 *images=average_image;
4123 break;
4124 }
4125 break;
4126 }
4127 case 'c':
4128 {
4129 if (LocaleCompare("channel",argv[0]+1) == 0)
4130 {
4131 ChannelType
4132 channel;
4133
4134 if (*argv[0] == '+')
4135 {
4136 channel=DefaultChannels;
4137 break;
4138 }
4139 channel=(ChannelType) ParseChannelOption(argv[1]);
4140 SetPixelChannelMap(*images,channel);
4141 break;
4142 }
4143 if (LocaleCompare("clut",argv[0]+1) == 0)
4144 {
4145 Image
4146 *clut_image,
4147 *image;
4148
4149 (void) SyncImagesSettings(image_info,*images);
4150 image=RemoveFirstImageFromList(images);
4151 clut_image=RemoveFirstImageFromList(images);
4152 if (clut_image == (Image *) NULL)
4153 {
4154 status=MagickFalse;
4155 break;
4156 }
4157 (void) ClutImageChannel(image,channel,clut_image);
4158 clut_image=DestroyImage(clut_image);
4159 *images=DestroyImageList(*images);
4160 *images=image;
4161 break;
4162 }
4163 if (LocaleCompare("coalesce",argv[0]+1) == 0)
4164 {
4165 Image
4166 *coalesce_image;
4167
4168 (void) SyncImagesSettings(image_info,*images);
4169 coalesce_image=CoalesceImages(*images,exception);
4170 if (coalesce_image == (Image *) NULL)
4171 {
4172 status=MagickFalse;
4173 break;
4174 }
4175 *images=DestroyImageList(*images);
4176 *images=coalesce_image;
4177 break;
4178 }
4179 if (LocaleCompare("combine",argv[0]+1) == 0)
4180 {
4181 Image
4182 *combine_image;
4183
4184 (void) SyncImagesSettings(image_info,*images);
4185 combine_image=CombineImages(*images,exception);
4186 if (combine_image == (Image *) NULL)
4187 {
4188 status=MagickFalse;
4189 break;
4190 }
4191 *images=DestroyImageList(*images);
4192 *images=combine_image;
4193 break;
4194 }
4195 if (LocaleCompare("composite",argv[0]+1) == 0)
4196 {
4197 Image
4198 *mask_image,
4199 *composite_image,
4200 *image;
4201
4202 RectangleInfo
4203 geometry;
4204
4205 (void) SyncImagesSettings(image_info,*images);
4206 image=RemoveFirstImageFromList(images);
4207 composite_image=RemoveFirstImageFromList(images);
4208 if (composite_image == (Image *) NULL)
4209 {
4210 status=MagickFalse;
4211 break;
4212 }
4213 (void) TransformImage(&composite_image,(char *) NULL,
4214 composite_image->geometry);
4215 SetGeometry(composite_image,&geometry);
4216 (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
4217 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
4218 &geometry);
4219 mask_image=RemoveFirstImageFromList(images);
4220 if (mask_image != (Image *) NULL)
4221 {
4222 if ((image->compose == DisplaceCompositeOp) ||
4223 (image->compose == DistortCompositeOp))
4224 {
4225 /*
4226 Merge Y displacement into X displacement image.
4227 */
4228 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
4229 mask_image,0,0);
4230 mask_image=DestroyImage(mask_image);
4231 }
4232 else
4233 {
4234 /*
4235 Set a blending mask for the composition.
4236 Posible error, what if image->mask already set.
4237 */
4238 image->mask=mask_image;
4239 (void) NegateImage(image->mask,MagickFalse,exception);
4240 }
4241 }
4242 (void) CompositeImage(image,image->compose,composite_image,
4243 geometry.x,geometry.y);
4244 if (mask_image != (Image *) NULL)
4245 mask_image=image->mask=DestroyImage(image->mask);
4246 composite_image=DestroyImage(composite_image);
4247 InheritException(exception,&image->exception);
4248 *images=DestroyImageList(*images);
4249 *images=image;
4250 break;
4251 }
4252 break;
4253 }
4254 case 'd':
4255 {
4256 if (LocaleCompare("deconstruct",argv[0]+1) == 0)
4257 {
4258 Image
4259 *deconstruct_image;
4260
4261 (void) SyncImagesSettings(image_info,*images);
4262 deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
4263 exception);
4264 if (deconstruct_image == (Image *) NULL)
4265 {
4266 status=MagickFalse;
4267 break;
4268 }
4269 *images=DestroyImageList(*images);
4270 *images=deconstruct_image;
4271 break;
4272 }
4273 if (LocaleCompare("delete",argv[0]+1) == 0)
4274 {
4275 if (*argv[0] == '+')
4276 DeleteImages(images,"-1",exception);
4277 else
4278 DeleteImages(images,argv[1],exception);
4279 break;
4280 }
4281 if (LocaleCompare("dither",argv[0]+1) == 0)
4282 {
4283 if (*argv[0] == '+')
4284 {
4285 quantize_info->dither=MagickFalse;
4286 break;
4287 }
4288 quantize_info->dither=MagickTrue;
4289 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
4290 MagickDitherOptions,MagickFalse,argv[1]);
4291 break;
4292 }
4293 if (LocaleCompare("duplicate",argv[0]+1) == 0)
4294 {
4295 Image
4296 *duplicate_images;
4297
4298 if (*argv[0] == '+')
4299 duplicate_images=DuplicateImages(*images,1,"-1",exception);
4300 else
4301 {
4302 const char
4303 *p;
4304
4305 size_t
4306 number_duplicates;
4307
4308 number_duplicates=(size_t) StringToLong(argv[1]);
4309 p=strchr(argv[1],',');
4310 if (p == (const char *) NULL)
4311 duplicate_images=DuplicateImages(*images,number_duplicates,
4312 "-1",exception);
4313 else
4314 duplicate_images=DuplicateImages(*images,number_duplicates,p,
4315 exception);
4316 }
4317 AppendImageToList(images, duplicate_images);
4318 (void) SyncImagesSettings(image_info,*images);
4319 break;
4320 }
4321 break;
4322 }
4323 case 'e':
4324 {
4325 if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0)
4326 {
4327 Image
4328 *evaluate_image;
4329
4330 MagickEvaluateOperator
4331 op;
4332
4333 (void) SyncImageSettings(image_info,*images);
4334 op=(MagickEvaluateOperator) ParseCommandOption(
4335 MagickEvaluateOptions,MagickFalse,argv[1]);
4336 evaluate_image=EvaluateImages(*images,op,exception);
4337 if (evaluate_image == (Image *) NULL)
4338 {
4339 status=MagickFalse;
4340 break;
4341 }
4342 *images=DestroyImageList(*images);
4343 *images=evaluate_image;
4344 break;
4345 }
4346 break;
4347 }
4348 case 'f':
4349 {
4350 if (LocaleCompare("fft",argv[0]+1) == 0)
4351 {
4352 Image
4353 *fourier_image;
4354
4355 /*
4356 Implements the discrete Fourier transform (DFT).
4357 */
4358 (void) SyncImageSettings(image_info,*images);
4359 fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ?
4360 MagickTrue : MagickFalse,exception);
4361 if (fourier_image == (Image *) NULL)
4362 break;
4363 *images=DestroyImage(*images);
4364 *images=fourier_image;
4365 break;
4366 }
4367 if (LocaleCompare("flatten",argv[0]+1) == 0)
4368 {
4369 Image
4370 *flatten_image;
4371
4372 (void) SyncImagesSettings(image_info,*images);
4373 flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
4374 if (flatten_image == (Image *) NULL)
4375 break;
4376 *images=DestroyImageList(*images);
4377 *images=flatten_image;
4378 break;
4379 }
4380 if (LocaleCompare("fx",argv[0]+1) == 0)
4381 {
4382 Image
4383 *fx_image;
4384
4385 (void) SyncImagesSettings(image_info,*images);
4386 fx_image=FxImage(*images,argv[1],exception);
4387 if (fx_image == (Image *) NULL)
4388 {
4389 status=MagickFalse;
4390 break;
4391 }
4392 *images=DestroyImageList(*images);
4393 *images=fx_image;
4394 break;
4395 }
4396 break;
4397 }
4398 case 'h':
4399 {
4400 if (LocaleCompare("hald-clut",argv[0]+1) == 0)
4401 {
4402 Image
4403 *hald_image,
4404 *image;
4405
4406 (void) SyncImagesSettings(image_info,*images);
4407 image=RemoveFirstImageFromList(images);
4408 hald_image=RemoveFirstImageFromList(images);
4409 if (hald_image == (Image *) NULL)
4410 {
4411 status=MagickFalse;
4412 break;
4413 }
4414 (void) HaldClutImage(image,hald_image,exception);
4415 hald_image=DestroyImage(hald_image);
4416 if (*images != (Image *) NULL)
4417 *images=DestroyImageList(*images);
4418 *images=image;
4419 break;
4420 }
4421 break;
4422 }
4423 case 'i':
4424 {
4425 if (LocaleCompare("ift",argv[0]+1) == 0)
4426 {
4427 Image
4428 *fourier_image,
4429 *magnitude_image,
4430 *phase_image;
4431
4432 /*
4433 Implements the inverse fourier discrete Fourier transform (DFT).
4434 */
4435 (void) SyncImagesSettings(image_info,*images);
4436 magnitude_image=RemoveFirstImageFromList(images);
4437 phase_image=RemoveFirstImageFromList(images);
4438 if (phase_image == (Image *) NULL)
4439 {
4440 status=MagickFalse;
4441 break;
4442 }
4443 fourier_image=InverseFourierTransformImage(magnitude_image,
4444 phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception);
4445 if (fourier_image == (Image *) NULL)
4446 break;
4447 if (*images != (Image *) NULL)
4448 *images=DestroyImage(*images);
4449 *images=fourier_image;
4450 break;
4451 }
4452 if (LocaleCompare("insert",argv[0]+1) == 0)
4453 {
4454 Image
4455 *p,
4456 *q;
4457
4458 index=0;
4459 if (*argv[0] != '+')
4460 index=(ssize_t) StringToLong(argv[1]);
4461 p=RemoveLastImageFromList(images);
4462 if (p == (Image *) NULL)
4463 {
4464 (void) ThrowMagickException(exception,GetMagickModule(),
4465 OptionError,"NoSuchImage","`%s'",argv[1]);
4466 status=MagickFalse;
4467 break;
4468 }
4469 q=p;
4470 if (index == 0)
4471 PrependImageToList(images,q);
4472 else
4473 if (index == (ssize_t) GetImageListLength(*images))
4474 AppendImageToList(images,q);
4475 else
4476 {
4477 q=GetImageFromList(*images,index-1);
4478 if (q == (Image *) NULL)
4479 {
4480 (void) ThrowMagickException(exception,GetMagickModule(),
4481 OptionError,"NoSuchImage","`%s'",argv[1]);
4482 status=MagickFalse;
4483 break;
4484 }
4485 InsertImageInList(&q,p);
4486 }
4487 *images=GetFirstImageInList(q);
4488 break;
4489 }
4490 if (LocaleCompare("interpolate",argv[0]+1) == 0)
4491 {
4492 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
4493 MagickInterpolateOptions,MagickFalse,argv[1]);
4494 break;
4495 }
4496 break;
4497 }
4498 case 'l':
4499 {
4500 if (LocaleCompare("layers",argv[0]+1) == 0)
4501 {
4502 Image
4503 *layers;
4504
4505 ImageLayerMethod
4506 method;
4507
4508 (void) SyncImagesSettings(image_info,*images);
4509 layers=(Image *) NULL;
4510 method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
4511 MagickFalse,argv[1]);
4512 switch (method)
4513 {
4514 case CoalesceLayer:
4515 {
4516 layers=CoalesceImages(*images,exception);
4517 break;
4518 }
4519 case CompareAnyLayer:
4520 case CompareClearLayer:
4521 case CompareOverlayLayer:
4522 default:
4523 {
4524 layers=CompareImagesLayers(*images,method,exception);
4525 break;
4526 }
4527 case MergeLayer:
4528 case FlattenLayer:
4529 case MosaicLayer:
4530 case TrimBoundsLayer:
4531 {
4532 layers=MergeImageLayers(*images,method,exception);
4533 break;
4534 }
4535 case DisposeLayer:
4536 {
4537 layers=DisposeImages(*images,exception);
4538 break;
4539 }
4540 case OptimizeImageLayer:
4541 {
4542 layers=OptimizeImageLayers(*images,exception);
4543 break;
4544 }
4545 case OptimizePlusLayer:
4546 {
4547 layers=OptimizePlusImageLayers(*images,exception);
4548 break;
4549 }
4550 case OptimizeTransLayer:
4551 {
4552 OptimizeImageTransparency(*images,exception);
4553 break;
4554 }
4555 case RemoveDupsLayer:
4556 {
4557 RemoveDuplicateLayers(images,exception);
4558 break;
4559 }
4560 case RemoveZeroLayer:
4561 {
4562 RemoveZeroDelayLayers(images,exception);
4563 break;
4564 }
4565 case OptimizeLayer:
4566 {
4567 /*
4568 General Purpose, GIF Animation Optimizer.
4569 */
4570 layers=CoalesceImages(*images,exception);
4571 if (layers == (Image *) NULL)
4572 {
4573 status=MagickFalse;
4574 break;
4575 }
4576 *images=DestroyImageList(*images);
4577 *images=layers;
4578 layers=OptimizeImageLayers(*images,exception);
4579 if (layers == (Image *) NULL)
4580 {
4581 status=MagickFalse;
4582 break;
4583 }
4584 *images=DestroyImageList(*images);
4585 *images=layers;
4586 layers=(Image *) NULL;
4587 OptimizeImageTransparency(*images,exception);
4588 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4589 exception);
4590 break;
4591 }
4592 case CompositeLayer:
4593 {
4594 CompositeOperator
4595 compose;
4596
4597 Image
4598 *source;
4599
4600 RectangleInfo
4601 geometry;
4602
4603 /*
4604 Split image sequence at the first 'NULL:' image.
4605 */
4606 source=(*images);
4607 while (source != (Image *) NULL)
4608 {
4609 source=GetNextImageInList(source);
4610 if ((source != (Image *) NULL) &&
4611 (LocaleCompare(source->magick,"NULL") == 0))
4612 break;
4613 }
4614 if (source != (Image *) NULL)
4615 {
4616 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4617 (GetNextImageInList(source) == (Image *) NULL))
4618 source=(Image *) NULL;
4619 else
4620 {
4621 /*
4622 Separate the two lists, junk the null: image.
4623 */
4624 source=SplitImageList(source->previous);
4625 DeleteImageFromList(&source);
4626 }
4627 }
4628 if (source == (Image *) NULL)
4629 {
4630 (void) ThrowMagickException(exception,GetMagickModule(),
4631 OptionError,"MissingNullSeparator","layers Composite");
4632 status=MagickFalse;
4633 break;
4634 }
4635 /*
4636 Adjust offset with gravity and virtual canvas.
4637 */
4638 SetGeometry(*images,&geometry);
4639 (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
4640 geometry.width=source->page.width != 0 ?
4641 source->page.width : source->columns;
4642 geometry.height=source->page.height != 0 ?
4643 source->page.height : source->rows;
4644 GravityAdjustGeometry((*images)->page.width != 0 ?
4645 (*images)->page.width : (*images)->columns,
4646 (*images)->page.height != 0 ? (*images)->page.height :
4647 (*images)->rows,(*images)->gravity,&geometry);
4648 compose=OverCompositeOp;
4649 argv[0]=GetImageOption(image_info,"compose");
4650 if (argv[0] != (const char *) NULL)
4651 compose=(CompositeOperator) ParseCommandOption(
4652 MagickComposeOptions,MagickFalse,argv[0]);
4653 CompositeLayers(*images,compose,source,geometry.x,geometry.y,
4654 exception);
4655 source=DestroyImageList(source);
4656 break;
4657 }
4658 }
4659 if (layers == (Image *) NULL)
4660 break;
4661 InheritException(exception,&layers->exception);
4662 *images=DestroyImageList(*images);
4663 *images=layers;
4664 break;
4665 }
4666 break;
4667 }
4668 case 'm':
4669 {
4670 if (LocaleCompare("map",argv[0]+1) == 0)
4671 {
4672 (void) SyncImagesSettings(image_info,*images);
4673 if (*argv[0] == '+')
4674 {
4675 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4676 exception);
4677 break;
4678 }
4679 break;
4680 }
4681 if (LocaleCompare("maximum",argv[0]+1) == 0)
4682 {
4683 Image
4684 *maximum_image;
4685
4686 /*
4687 Maximum image sequence (deprecated).
4688 */
4689 (void) SyncImagesSettings(image_info,*images);
4690 maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
4691 if (maximum_image == (Image *) NULL)
4692 {
4693 status=MagickFalse;
4694 break;
4695 }
4696 *images=DestroyImageList(*images);
4697 *images=maximum_image;
4698 break;
4699 }
4700 if (LocaleCompare("minimum",argv[0]+1) == 0)
4701 {
4702 Image
4703 *minimum_image;
4704
4705 /*
4706 Minimum image sequence (deprecated).
4707 */
4708 (void) SyncImagesSettings(image_info,*images);
4709 minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
4710 if (minimum_image == (Image *) NULL)
4711 {
4712 status=MagickFalse;
4713 break;
4714 }
4715 *images=DestroyImageList(*images);
4716 *images=minimum_image;
4717 break;
4718 }
4719 if (LocaleCompare("morph",argv[0]+1) == 0)
4720 {
4721 Image
4722 *morph_image;
4723
4724 (void) SyncImagesSettings(image_info,*images);
4725 morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]),
4726 exception);
4727 if (morph_image == (Image *) NULL)
4728 {
4729 status=MagickFalse;
4730 break;
4731 }
4732 *images=DestroyImageList(*images);
4733 *images=morph_image;
4734 break;
4735 }
4736 if (LocaleCompare("mosaic",argv[0]+1) == 0)
4737 {
4738 Image
4739 *mosaic_image;
4740
4741 (void) SyncImagesSettings(image_info,*images);
4742 mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
4743 if (mosaic_image == (Image *) NULL)
4744 {
4745 status=MagickFalse;
4746 break;
4747 }
4748 *images=DestroyImageList(*images);
4749 *images=mosaic_image;
4750 break;
4751 }
4752 break;
4753 }
4754 case 'p':
4755 {
4756 if (LocaleCompare("print",argv[0]+1) == 0)
4757 {
4758 char
4759 *string;
4760
4761 (void) SyncImagesSettings(image_info,*images);
4762 string=InterpretImageProperties(image_info,*images,argv[1],
4763 exception);
4764 if (string == (char *) NULL)
4765 break;
4766 (void) FormatLocaleFile(stdout,"%s",string);
4767 string=DestroyString(string);
4768 }
4769 if (LocaleCompare("process",argv[0]+1) == 0)
4770 {
4771 char
4772 **arguments;
4773
4774 int
4775 j,
4776 number_arguments;
4777
4778 (void) SyncImagesSettings(image_info,*images);
4779 arguments=StringToArgv(argv[1],&number_arguments);
4780 if (arguments == (char **) NULL)
4781 break;
4782 if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
4783 {
4784 char
4785 breaker,
4786 quote,
4787 *token;
4788
4789 const char
4790 *arguments;
4791
4792 int
4793 next,
4794 status;
4795
4796 size_t
4797 length;
4798
4799 TokenInfo
4800 *token_info;
4801
4802 /*
4803 Support old style syntax, filter="-option arg".
4804 */
4805 length=strlen(argv[1]);
4806 token=(char *) NULL;
4807 if (~length >= (MaxTextExtent-1))
4808 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4809 sizeof(*token));
4810 if (token == (char *) NULL)
4811 break;
4812 next=0;
4813 arguments=argv[1];
4814 token_info=AcquireTokenInfo();
4815 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4816 "\"",'\0',&breaker,&next,&quote);
4817 token_info=DestroyTokenInfo(token_info);
4818 if (status == 0)
4819 {
4820 const char
4821 *argv;
4822
4823 argv=(&(arguments[next]));
4824 (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
4825 exception);
4826 }
4827 token=DestroyString(token);
4828 break;
4829 }
4830 (void) SubstituteString(&arguments[1],"-","");
4831 (void) InvokeDynamicImageFilter(arguments[1],&(*images),
4832 number_arguments-2,(const char **) arguments+2,exception);
4833 for (j=0; j < number_arguments; j++)
4834 arguments[j]=DestroyString(arguments[j]);
4835 arguments=(char **) RelinquishMagickMemory(arguments);
4836 break;
4837 }
4838 break;
4839 }
4840 case 'r':
4841 {
4842 if (LocaleCompare("reverse",argv[0]+1) == 0)
4843 {
4844 ReverseImageList(images);
4845 InheritException(exception,&(*images)->exception);
4846 break;
4847 }
4848 break;
4849 }
4850 case 's':
4851 {
4852 if (LocaleCompare("smush",argv[0]+1) == 0)
4853 {
4854 Image
4855 *smush_image;
4856
4857 ssize_t
4858 offset;
4859
4860 (void) SyncImagesSettings(image_info,*images);
4861 offset=(ssize_t) StringToLong(argv[1]);
4862 smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue :
4863 MagickFalse,offset,exception);
4864 if (smush_image == (Image *) NULL)
4865 {
4866 status=MagickFalse;
4867 break;
4868 }
4869 *images=DestroyImageList(*images);
4870 *images=smush_image;
4871 break;
4872 }
4873 if (LocaleCompare("swap",argv[0]+1) == 0)
4874 {
4875 Image
4876 *p,
4877 *q,
4878 *swap;
4879
4880 ssize_t
4881 swap_index;
4882
4883 index=(-1);
4884 swap_index=(-2);
4885 if (*argv[0] != '+')
4886 {
4887 GeometryInfo
4888 geometry_info;
4889
4890 MagickStatusType
4891 flags;
4892
4893 swap_index=(-1);
4894 flags=ParseGeometry(argv[1],&geometry_info);
4895 index=(ssize_t) geometry_info.rho;
4896 if ((flags & SigmaValue) != 0)
4897 swap_index=(ssize_t) geometry_info.sigma;
4898 }
4899 p=GetImageFromList(*images,index);
4900 q=GetImageFromList(*images,swap_index);
4901 if ((p == (Image *) NULL) || (q == (Image *) NULL))
4902 {
4903 (void) ThrowMagickException(exception,GetMagickModule(),
4904 OptionError,"NoSuchImage","`%s'",(*images)->filename);
4905 status=MagickFalse;
4906 break;
4907 }
4908 if (p == q)
4909 break;
4910 swap=CloneImage(p,0,0,MagickTrue,exception);
4911 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
4912 ReplaceImageInList(&q,swap);
4913 *images=GetFirstImageInList(q);
4914 break;
4915 }
4916 break;
4917 }
4918 case 'w':
4919 {
4920 if (LocaleCompare("write",argv[0]+1) == 0)
4921 {
4922 char
4923 key[MaxTextExtent];
4924
4925 Image
4926 *write_images;
4927
4928 ImageInfo
4929 *write_info;
4930
4931 (void) SyncImagesSettings(image_info,*images);
4932 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]);
4933 (void) DeleteImageRegistry(key);
4934 write_images=(*images);
4935 if (*argv[0] == '+')
4936 write_images=CloneImageList(*images,exception);
4937 write_info=CloneImageInfo(image_info);
4938 status&=WriteImages(write_info,write_images,argv[1],exception);
4939 write_info=DestroyImageInfo(write_info);
4940 if (*argv[0] == '+')
4941 write_images=DestroyImageList(write_images);
4942 break;
4943 }
4944 break;
4945 }
4946 default:
4947 break;
4948 }
4949 quantize_info=DestroyQuantizeInfo(quantize_info);
4950
4951 return(status != 0 ? MagickTrue : MagickFalse);
4952}
cristy0a0ca4f2011-09-28 01:15:28 +00004953#endif