2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % OOO PPPP EEEE RRRR AA TTTTT III OOO N N %
7 % O O P P E R R A A T I O O NN N %
8 % O O PPPP EEE RRRR AAAA T I O O N N N %
9 % O O P E R R A A T I O O N NN %
10 % OOO P EEEE R RR A A T III OOO N N %
13 % CLI Magick Option Methods %
20 % Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % https://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 % Apply the given options (settings, and simple, or sequence operations) to
37 % the given image(s) according to the current "image_info", "draw_info", and
38 % "quantize_info" settings, stored in a special CLI Image Wand.
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
44 % Anthony Thyssen, September 2011
50 #include "MagickWand/studio.h"
51 #include "MagickWand/MagickWand.h"
52 #include "MagickWand/magick-wand-private.h"
53 #include "MagickWand/mogrify.h"
54 #include "MagickWand/operation.h"
55 #include "MagickWand/wand.h"
56 #include "MagickWand/wandcli.h"
57 #include "MagickWand/wandcli-private.h"
58 #include "MagickCore/composite-private.h"
59 #include "MagickCore/image-private.h"
60 #include "MagickCore/monitor-private.h"
61 #include "MagickCore/pixel-private.h"
62 #include "MagickCore/string-private.h"
63 #include "MagickCore/thread-private.h"
69 MogrifyAlphaColor[] = "#bdbdbd", /* slightly darker gray */
70 MogrifyBackgroundColor[] = "#fff", /* white */
71 MogrifyBorderColor[] = "#dfdfdf"; /* sRGB gray */
76 #define USE_WAND_METHODS 1
77 #define MAX_STACK_DEPTH 32
78 #define UNDEFINED_COMPRESSION_QUALITY 0UL
80 /* FUTURE: why is this default so specific? */
81 #define DEFAULT_DISSIMILARITY_THRESHOLD "0.31830988618379067154"
83 /* For Debugging Geometry Input */
84 #define ReportGeometry(flags,info) \
85 (void) FormatLocaleFile(stderr, "Geometry = 0x%04X : %lg x %lg %+lg %+lg\n", \
86 flags, info.rho, info.sigma, info.xi, info.psi )
89 ** Function to report on the progress of image operations
91 static MagickBooleanType MonitorProgress(const char *text,
92 const MagickOffsetType offset,const MagickSizeType extent,
93 void *wand_unused(client_data))
96 message[MagickPathExtent],
97 tag[MagickPathExtent];
105 magick_unreferenced(client_data);
107 if ((extent <= 1) || (offset < 0) || (offset >= (MagickOffsetType) extent))
109 if ((offset != (MagickOffsetType) (extent-1)) && ((offset % 50) != 0))
111 (void) CopyMagickString(tag,text,MagickPathExtent);
113 if (p != (char *) NULL)
115 (void) FormatLocaleString(message,MagickPathExtent,"Monitor/%s",tag);
116 locale_message=GetLocaleMessage(message);
117 if (locale_message == message)
119 if (p == (char *) NULL)
120 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
121 locale_message,(long) offset,(unsigned long) extent,(long)
122 (100L*offset/(extent-1)));
124 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
125 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
126 (100L*offset/(extent-1)));
127 if (offset == (MagickOffsetType) (extent-1))
128 (void) FormatLocaleFile(stderr,"\n");
129 (void) fflush(stderr);
134 ** GetImageCache() will read an image into a image cache if not already
135 ** present then return the image that is in the cache under that filename.
137 static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
138 ExceptionInfo *exception)
141 key[MagickPathExtent];
152 (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",path);
153 sans_exception=AcquireExceptionInfo();
154 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
155 sans_exception=DestroyExceptionInfo(sans_exception);
156 if (image != (Image *) NULL)
158 read_info=CloneImageInfo(image_info);
159 if (path != (const char *) NULL)
160 (void) CopyMagickString(read_info->filename,path,MagickPathExtent);
161 image=ReadImage(read_info,exception);
162 read_info=DestroyImageInfo(read_info);
163 if (image != (Image *) NULL)
164 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
169 SparseColorOption() parse the complex -sparse-color argument into an
170 an array of floating point values than call SparseColorImage().
171 Argument is a complex mix of floating-point pixel coodinates, and color
172 specifications (or direct floating point numbers). The number of floats
173 needed to represent a color varies depending on the current channel
176 This really should be in MagickCore, so that other API's can make use of it.
178 static Image *SparseColorOption(const Image *image,
179 const SparseColorMethod method,const char *arguments,ExceptionInfo *exception)
182 token[MagickPathExtent];
206 assert(image != (Image *) NULL);
207 assert(image->signature == MagickCoreSignature);
208 if (image->debug != MagickFalse)
209 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
210 assert(exception != (ExceptionInfo *) NULL);
211 assert(exception->signature == MagickCoreSignature);
213 Limit channels according to image
214 add up number of values needed per color.
217 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
219 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
221 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
223 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
224 (image->colorspace == CMYKColorspace))
226 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
227 image->alpha_trait != UndefinedPixelTrait)
231 Read string, to determine number of arguments needed,
237 GetNextToken(p,&p,MagickPathExtent,token);
238 if ( token[0] == ',' ) continue;
239 if ( isalpha((int) token[0]) || token[0] == '#' )
240 x += number_colors; /* color argument found */
242 x++; /* floating point argument */
244 /* control points and color values */
245 if ((x % (2+number_colors)) != 0)
247 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
248 "InvalidArgument","'%s': %s", "sparse-color",
249 "Invalid number of Arguments");
250 return( (Image *) NULL);
255 /* Allocate and fill in the floating point arguments */
256 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
257 sizeof(*sparse_arguments));
258 if (sparse_arguments == (double *) NULL) {
259 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
260 "MemoryAllocationFailed","%s","SparseColorOption");
261 return( (Image *) NULL);
263 (void) memset(sparse_arguments,0,number_arguments*
264 sizeof(*sparse_arguments));
267 while( *p != '\0' && x < number_arguments ) {
269 token[0]=','; while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
270 if ( token[0] == '\0' ) break;
271 if ( isalpha((int) token[0]) || token[0] == '#' ) {
272 (void) ThrowMagickException(exception,GetMagickModule(),
273 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
274 "Color found, instead of X-coord");
278 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
280 token[0]=','; while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
281 if ( token[0] == '\0' ) break;
282 if ( isalpha((int) token[0]) || token[0] == '#' ) {
283 (void) ThrowMagickException(exception,GetMagickModule(),
284 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
285 "Color found, instead of Y-coord");
289 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
290 /* color name or function given in string argument */
291 token[0]=','; while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
292 if ( token[0] == '\0' ) break;
293 if ( isalpha((int) token[0]) || token[0] == '#' ) {
294 /* Color string given */
295 (void) QueryColorCompliance(token,AllCompliance,&color,
297 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
298 sparse_arguments[x++] = QuantumScale*color.red;
299 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
300 sparse_arguments[x++] = QuantumScale*color.green;
301 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
302 sparse_arguments[x++] = QuantumScale*color.blue;
303 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
304 (image->colorspace == CMYKColorspace))
305 sparse_arguments[x++] = QuantumScale*color.black;
306 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
307 image->alpha_trait != UndefinedPixelTrait)
308 sparse_arguments[x++] = QuantumScale*color.alpha;
311 /* Colors given as a set of floating point values - experimental */
312 /* NB: token contains the first floating point value to use! */
313 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
315 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
316 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
318 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
319 token[0] = ','; /* used this token - get another */
321 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
323 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
324 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
326 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
327 token[0] = ','; /* used this token - get another */
329 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
331 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
332 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
334 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
335 token[0] = ','; /* used this token - get another */
337 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
338 (image->colorspace == CMYKColorspace))
340 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
341 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
343 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
344 token[0] = ','; /* used this token - get another */
346 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
347 image->alpha_trait != UndefinedPixelTrait)
349 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
350 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
352 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
353 token[0] = ','; /* used this token - get another */
357 if (error != MagickFalse)
359 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
360 return((Image *) NULL);
362 if (number_arguments != x)
364 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
365 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
366 "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
367 return((Image *) NULL);
369 /* Call the Sparse Color Interpolation function with the parsed arguments */
370 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
372 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
373 return( sparse_image );
377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381 % C L I S e t t i n g O p t i o n I n f o %
385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387 % CLISettingOptionInfo() applies a single settings option into a CLI wand
388 % holding the image_info, draw_info, quantize_info structures that will be
389 % used when processing the images.
391 % These options do no require images to be present in the CLI wand for them
392 % to be able to be set, in which case they will generally be applied to image
393 % that are read in later
395 % Options handled by this function are listed in CommandOptions[] of
396 % "option.c" that is one of "SettingOptionFlags" option flags.
398 % The format of the CLISettingOptionInfo method is:
400 % void CLISettingOptionInfo(MagickCLI *cli_wand,
401 % const char *option, const char *arg1, const char *arg2)
403 % A description of each parameter follows:
405 % o cli_wand: structure holding settings to be applied
407 % o option: The option string to be set
409 % o arg1, arg2: optional argument strings to the operation
410 % arg2 is currently only used by "-limit"
413 WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
414 const char *option,const char *arg1n, const char *arg2n)
417 parse; /* option argument parsing (string to value table lookup) */
419 const char /* percent escaped versions of the args */
423 #define _image_info (cli_wand->wand.image_info)
424 #define _image (cli_wand->wand.images)
425 #define _exception (cli_wand->wand.exception)
426 #define _draw_info (cli_wand->draw_info)
427 #define _quantize_info (cli_wand->quantize_info)
428 #define IfSetOption (*option=='-')
429 #define ArgBoolean IfSetOption ? MagickTrue : MagickFalse
430 #define ArgBooleanNot IfSetOption ? MagickFalse : MagickTrue
431 #define ArgBooleanString (IfSetOption?"true":"false")
432 #define ArgOption(def) (IfSetOption?arg1:(const char *)(def))
434 assert(cli_wand != (MagickCLI *) NULL);
435 assert(cli_wand->signature == MagickWandSignature);
436 assert(cli_wand->wand.signature == MagickWandSignature);
438 if (cli_wand->wand.debug != MagickFalse)
439 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
440 "- Setting Option: %s \"%s\" \"%s\"", option,arg1n,arg2n);
446 #define _process_flags (cli_wand->process_flags)
447 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
448 /* Interpret Percent Escapes in Arguments - using first image */
449 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
450 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
451 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
452 /* Interpret Percent escapes in argument 1 */
453 if (arg1n != (char *) NULL) {
454 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
455 if (arg1 == (char *) NULL) {
456 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
457 arg1=arg1n; /* use the given argument as is */
460 if (arg2n != (char *) NULL) {
461 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
462 if (arg2 == (char *) NULL) {
463 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
464 arg2=arg2n; /* use the given argument as is */
468 #undef _process_flags
476 if (LocaleCompare("adjoin",option+1) == 0)
478 _image_info->adjoin = ArgBoolean;
481 if (LocaleCompare("affine",option+1) == 0)
483 CLIWandWarnReplaced("-draw 'affine ...'");
485 (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
487 GetAffineMatrix(&_draw_info->affine);
490 if (LocaleCompare("antialias",option+1) == 0)
492 _image_info->antialias =
493 _draw_info->stroke_antialias =
494 _draw_info->text_antialias = ArgBoolean;
497 if (LocaleCompare("attenuate",option+1) == 0)
499 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
500 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
501 (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
504 if (LocaleCompare("authenticate",option+1) == 0)
506 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
509 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
513 if (LocaleCompare("background",option+1) == 0)
515 /* FUTURE: both _image_info attribute & ImageOption in use!
516 _image_info only used directly for generating new images.
517 SyncImageSettings() used to set per-image attribute.
519 FUTURE: if _image_info->background_color is not set then
520 we should fall back to per-image background_color
522 At this time -background will 'wipe out' the per-image
525 Better error handling of QueryColorCompliance() needed.
527 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
528 (void) QueryColorCompliance(ArgOption(MogrifyBackgroundColor),AllCompliance,
529 &_image_info->background_color,_exception);
532 if (LocaleCompare("bias",option+1) == 0)
534 /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
535 as it is actually rarely used except in direct convolve operations
536 Usage outside a direct convolve operation is actally non-sensible!
538 SyncImageSettings() used to set per-image attribute.
540 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
541 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
542 (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
545 if (LocaleCompare("black-point-compensation",option+1) == 0)
547 /* Used as a image chromaticity setting
548 SyncImageSettings() used to set per-image attribute.
550 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
553 if (LocaleCompare("blue-primary",option+1) == 0)
555 /* Image chromaticity X,Y NB: Y=X if Y not defined
556 Used by many coders including PNG
557 SyncImageSettings() used to set per-image attribute.
559 arg1=ArgOption("0.0");
560 if (IsGeometry(arg1) == MagickFalse)
561 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
562 (void) SetImageOption(_image_info,option+1,arg1);
565 if (LocaleCompare("bordercolor",option+1) == 0)
567 /* FUTURE: both _image_info attribute & ImageOption in use!
568 SyncImageSettings() used to set per-image attribute.
569 Better error checking of QueryColorCompliance().
573 (void) SetImageOption(_image_info,option+1,arg1);
574 (void) QueryColorCompliance(arg1,AllCompliance,
575 &_image_info->border_color,_exception);
576 (void) QueryColorCompliance(arg1,AllCompliance,
577 &_draw_info->border_color,_exception);
580 (void) DeleteImageOption(_image_info,option+1);
581 (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
582 &_image_info->border_color,_exception);
583 (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
584 &_draw_info->border_color,_exception);
587 if (LocaleCompare("box",option+1) == 0)
589 CLIWandWarnReplaced("-undercolor");
590 CLISettingOptionInfo(cli_wand,"-undercolor",arg1, arg2);
593 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
597 if (LocaleCompare("cache",option+1) == 0)
602 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
603 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
604 limit=MagickResourceInfinity;
605 if (LocaleCompare("unlimited",arg1) != 0)
606 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
607 (void) SetMagickResourceLimit(MemoryResource,limit);
608 (void) SetMagickResourceLimit(MapResource,2*limit);
611 if (LocaleCompare("caption",option+1) == 0)
613 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
616 if (LocaleCompare("colorspace",option+1) == 0)
618 /* Setting used for new images via AquireImage()
619 But also used as a SimpleImageOperator
620 Undefined colorspace means don't modify images on
621 read or as a operation */
622 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
623 ArgOption("undefined"));
625 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
627 _image_info->colorspace=(ColorspaceType) parse;
630 if (LocaleCompare("comment",option+1) == 0)
632 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
635 if (LocaleCompare("compose",option+1) == 0)
637 /* FUTURE: _image_info should be used,
638 SyncImageSettings() used to set per-image attribute. - REMOVE
640 This setting should NOT be used to set image 'compose'
641 "-layer" operators shoud use _image_info if defined otherwise
642 they should use a per-image compose setting.
644 parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
645 ArgOption("undefined"));
647 CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
649 _image_info->compose=(CompositeOperator) parse;
650 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
653 if (LocaleCompare("compress",option+1) == 0)
655 /* FUTURE: What should be used? _image_info or ImageOption ???
656 The former is more efficent, but Crisy prefers the latter!
657 SyncImageSettings() used to set per-image attribute.
659 The coders appears to use _image_info, not Image_Option
660 however the image attribute (for save) is set from the
663 Note that "undefined" is a different setting to "none".
665 parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
666 ArgOption("undefined"));
668 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
670 _image_info->compression=(CompressionType) parse;
671 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
674 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
678 if (LocaleCompare("debug",option+1) == 0)
680 /* SyncImageSettings() used to set per-image attribute. */
681 arg1=ArgOption("none");
682 parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
684 CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
686 (void) SetLogEventMask(arg1);
687 _image_info->debug=IsEventLogging(); /* extract logging*/
688 cli_wand->wand.debug=IsEventLogging();
691 if (LocaleCompare("define",option+1) == 0)
693 if (LocaleNCompare(arg1,"registry:",9) == 0)
696 (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
698 (void) DeleteImageRegistry(arg1+9);
701 /* DefineImageOption() equals SetImageOption() but with '=' */
703 (void) DefineImageOption(_image_info,arg1);
704 else if (DeleteImageOption(_image_info,arg1) == MagickFalse)
705 CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
708 if (LocaleCompare("delay",option+1) == 0)
710 /* Only used for new images via AcquireImage()
711 FUTURE: Option should also be used for "-morph" (color morphing)
714 if (IsGeometry(arg1) == MagickFalse)
715 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
716 (void) SetImageOption(_image_info,option+1,arg1);
719 if (LocaleCompare("density",option+1) == 0)
721 /* FUTURE: strings used in _image_info attr and _draw_info!
722 Basically as density can be in a XxY form!
724 SyncImageSettings() used to set per-image attribute.
726 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
727 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
728 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
729 (void) CloneString(&_image_info->density,ArgOption(NULL));
730 (void) CloneString(&_draw_info->density,_image_info->density);
733 if (LocaleCompare("depth",option+1) == 0)
735 /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
736 SyncImageSettings() used to set per-image attribute.
738 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
739 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
740 _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
741 :MAGICKCORE_QUANTUM_DEPTH;
744 if (LocaleCompare("direction",option+1) == 0)
746 /* Image Option is only used to set _draw_info */
747 arg1=ArgOption("undefined");
748 parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
750 CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
752 _draw_info->direction=(DirectionType) parse;
753 (void) SetImageOption(_image_info,option+1,arg1);
756 if (LocaleCompare("display",option+1) == 0)
758 (void) CloneString(&_image_info->server_name,ArgOption(NULL));
759 (void) CloneString(&_draw_info->server_name,_image_info->server_name);
762 if (LocaleCompare("dispose",option+1) == 0)
764 /* only used in setting new images */
765 arg1=ArgOption("undefined");
766 parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
768 CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
770 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
773 if (LocaleCompare("dissimilarity-threshold",option+1) == 0)
775 /* FUTURE: this is only used by CompareImages() which is used
776 only by the "compare" CLI program at this time. */
777 arg1=ArgOption(DEFAULT_DISSIMILARITY_THRESHOLD);
778 if (IsGeometry(arg1) == MagickFalse)
779 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
780 (void) SetImageOption(_image_info,option+1,arg1);
783 if (LocaleCompare("dither",option+1) == 0)
785 /* _image_info attr (on/off), _quantize_info attr (on/off)
786 but also ImageInfo and _quantize_info method!
787 FUTURE: merge the duality of the dithering options
789 _image_info->dither = ArgBoolean;
790 (void) SetImageOption(_image_info,option+1,ArgOption("none"));
791 _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
792 MagickDitherOptions,MagickFalse,ArgOption("none"));
793 if (_quantize_info->dither_method == NoDitherMethod)
794 _image_info->dither = MagickFalse;
797 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
801 if (LocaleCompare("encoding",option+1) == 0)
803 (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
804 (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
807 if (LocaleCompare("endian",option+1) == 0)
809 /* Both _image_info attr and ImageInfo */
810 arg1 = ArgOption("undefined");
811 parse = ParseCommandOption(MagickEndianOptions,MagickFalse,arg1);
813 CLIWandExceptArgBreak(OptionError,"UnrecognizedEndianType",
815 /* FUTURE: check alloc/free of endian string! - remove? */
816 _image_info->endian=(EndianType) (*arg1);
817 (void) SetImageOption(_image_info,option+1,arg1);
820 if (LocaleCompare("extract",option+1) == 0)
822 (void) CloneString(&_image_info->extract,ArgOption(NULL));
825 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
829 if (LocaleCompare("family",option+1) == 0)
831 (void) CloneString(&_draw_info->family,ArgOption(NULL));
834 if (LocaleCompare("features",option+1) == 0)
836 (void) SetImageOption(_image_info,"identify:features",
839 (void) SetImageArtifact(_image,"verbose","true");
842 if (LocaleCompare("fill",option+1) == 0)
844 /* Set "fill" OR "fill-pattern" in _draw_info
845 The original fill color is preserved if a fill-pattern is given.
846 That way it does not effect other operations that directly using
847 the fill color and, can be retored using "+tile".
858 arg1 = ArgOption("none"); /* +fill turns it off! */
859 (void) SetImageOption(_image_info,option+1,arg1);
860 if (_draw_info->fill_pattern != (Image *) NULL)
861 _draw_info->fill_pattern=DestroyImage(_draw_info->fill_pattern);
863 /* is it a color or a image? -- ignore exceptions */
864 sans=AcquireExceptionInfo();
865 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
866 sans=DestroyExceptionInfo(sans);
868 if (status == MagickFalse)
869 _draw_info->fill_pattern=GetImageCache(_image_info,arg1,_exception);
871 _draw_info->fill=color;
874 if (LocaleCompare("filter",option+1) == 0)
876 /* SyncImageSettings() used to set per-image attribute. */
877 arg1 = ArgOption("undefined");
878 parse = ParseCommandOption(MagickFilterOptions,MagickFalse,arg1);
880 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageFilter",
882 (void) SetImageOption(_image_info,option+1,arg1);
885 if (LocaleCompare("font",option+1) == 0)
887 (void) CloneString(&_draw_info->font,ArgOption(NULL));
888 (void) CloneString(&_image_info->font,_draw_info->font);
891 if (LocaleCompare("format",option+1) == 0)
893 /* FUTURE: why the ping test, you could set ping after this! */
898 for (q=strchr(arg1,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
899 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
900 _image_info->ping=MagickFalse;
902 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
905 if (LocaleCompare("fuzz",option+1) == 0)
907 /* Option used to set image fuzz! unless blank canvas (from color)
908 Image attribute used for color compare operations
909 SyncImageSettings() used to set per-image attribute.
911 FUTURE: Can't find anything else using _image_info->fuzz directly!
912 convert structure attribute to 'option' string
915 if (IsGeometry(arg1) == MagickFalse)
916 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
917 _image_info->fuzz=StringToDoubleInterval(arg1,(double)
919 (void) SetImageOption(_image_info,option+1,arg1);
922 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
926 if (LocaleCompare("gravity",option+1) == 0)
928 /* SyncImageSettings() used to set per-image attribute. */
929 arg1 = ArgOption("none");
930 parse = ParseCommandOption(MagickGravityOptions,MagickFalse,arg1);
932 CLIWandExceptArgBreak(OptionError,"UnrecognizedGravityType",
934 _draw_info->gravity=(GravityType) parse;
935 (void) SetImageOption(_image_info,option+1,arg1);
938 if (LocaleCompare("green-primary",option+1) == 0)
940 /* Image chromaticity X,Y NB: Y=X if Y not defined
941 SyncImageSettings() used to set per-image attribute.
942 Used directly by many coders
944 arg1=ArgOption("0.0");
945 if (IsGeometry(arg1) == MagickFalse)
946 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
947 (void) SetImageOption(_image_info,option+1,arg1);
950 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
954 if (LocaleCompare("highlight-color",option+1) == 0)
956 /* FUTURE: this is only used by CompareImages() which is used
957 only by the "compare" CLI program at this time. */
958 (void) SetImageOption(_image_info,"compare:highlight-color",
962 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
966 if (LocaleCompare("intensity",option+1) == 0)
968 arg1 = ArgOption("undefined");
969 parse = ParseCommandOption(MagickPixelIntensityOptions,MagickFalse,
972 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityType",
974 (void) SetImageOption(_image_info,option+1,arg1);
977 if (LocaleCompare("intent",option+1) == 0)
979 /* Only used by coders: MIFF, MPC, BMP, PNG
980 and for image profile call to AcquireTransformThreadSet()
981 SyncImageSettings() used to set per-image attribute.
983 arg1 = ArgOption("undefined");
984 parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
986 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
988 (void) SetImageOption(_image_info,option+1,arg1);
991 if (LocaleCompare("interlace",option+1) == 0)
993 /* _image_info is directly used by coders (so why an image setting?)
994 SyncImageSettings() used to set per-image attribute.
996 arg1 = ArgOption("undefined");
997 parse = ParseCommandOption(MagickInterlaceOptions,MagickFalse,arg1);
999 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterlaceType",
1001 _image_info->interlace=(InterlaceType) parse;
1002 (void) SetImageOption(_image_info,option+1,arg1);
1005 if (LocaleCompare("interline-spacing",option+1) == 0)
1007 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1008 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1009 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1010 _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
1014 if (LocaleCompare("interpolate",option+1) == 0)
1016 /* SyncImageSettings() used to set per-image attribute. */
1017 arg1 = ArgOption("undefined");
1018 parse = ParseCommandOption(MagickInterpolateOptions,MagickFalse,arg1);
1020 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterpolateMethod",
1022 (void) SetImageOption(_image_info,option+1,arg1);
1025 if (LocaleCompare("interword-spacing",option+1) == 0)
1027 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1028 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1029 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1030 _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
1033 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1037 if (LocaleCompare("kerning",option+1) == 0)
1039 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1040 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1041 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1042 _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
1045 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1049 if (LocaleCompare("label",option+1) == 0)
1051 /* only used for new images - not in SyncImageOptions() */
1052 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1055 if (LocaleCompare("limit",option+1) == 0)
1060 limit=MagickResourceInfinity;
1061 parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1);
1063 CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType",
1065 if (LocaleCompare("unlimited",arg2) != 0)
1066 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
1067 (void) SetMagickResourceLimit((ResourceType)parse,limit);
1070 if (LocaleCompare("log",option+1) == 0)
1073 if ((strchr(arg1,'%') == (char *) NULL))
1074 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1075 (void) SetLogFormat(arg1);
1079 if (LocaleCompare("lowlight-color",option+1) == 0)
1081 /* FUTURE: this is only used by CompareImages() which is used
1082 only by the "compare" CLI program at this time. */
1083 (void) SetImageOption(_image_info,"compare:lowlight-color",
1087 if (LocaleCompare("loop",option+1) == 0)
1089 /* SyncImageSettings() used to set per-image attribute. */
1090 arg1=ArgOption("0");
1091 if (IsGeometry(arg1) == MagickFalse)
1092 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1093 (void) SetImageOption(_image_info,option+1,arg1);
1096 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1100 if (LocaleCompare("mattecolor",option+1) == 0)
1102 /* SyncImageSettings() used to set per-image attribute. */
1103 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1104 (void) QueryColorCompliance(ArgOption(MogrifyAlphaColor),
1105 AllCompliance,&_image_info->matte_color,_exception);
1108 if (LocaleCompare("metric",option+1) == 0)
1110 /* FUTURE: this is only used by CompareImages() which is used
1111 only by the "compare" CLI program at this time. */
1112 parse=ParseCommandOption(MagickMetricOptions,MagickFalse,arg1);
1114 CLIWandExceptArgBreak(OptionError,"UnrecognizedMetricType",
1116 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1119 if (LocaleCompare("moments",option+1) == 0)
1121 (void) SetImageOption(_image_info,"identify:moments",
1124 (void) SetImageArtifact(_image,"verbose","true");
1127 if (LocaleCompare("monitor",option+1) == 0)
1129 (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
1130 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
1133 if (LocaleCompare("monochrome",option+1) == 0)
1135 /* Setting (used by some input coders!) -- why?
1136 Warning: This is also Special '-type' SimpleOperator
1138 _image_info->monochrome= ArgBoolean;
1141 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1145 if (LocaleCompare("orient",option+1) == 0)
1147 /* Is not used when defining for new images.
1148 This makes it more of a 'operation' than a setting
1149 FUTURE: make set meta-data operator instead.
1150 SyncImageSettings() used to set per-image attribute.
1152 parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
1153 ArgOption("undefined"));
1155 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
1157 _image_info->orientation=(OrientationType)parse;
1158 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1161 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1165 if (LocaleCompare("page",option+1) == 0)
1167 /* Only used for new images and image generators.
1168 SyncImageSettings() used to set per-image attribute. ?????
1169 That last is WRONG!!!!
1170 FUTURE: adjust named 'page' sizes according density
1174 page[MagickPathExtent];
1187 (void) DeleteImageOption(_image_info,option+1);
1188 (void) CloneString(&_image_info->page,(char *) NULL);
1191 (void) memset(&geometry,0,sizeof(geometry));
1192 image_option=GetImageOption(_image_info,"page");
1193 if (image_option != (const char *) NULL)
1194 flags=ParseAbsoluteGeometry(image_option,&geometry);
1195 canonical_page=GetPageGeometry(arg1);
1196 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1197 canonical_page=DestroyString(canonical_page);
1198 (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu",
1199 (unsigned long) geometry.width,(unsigned long) geometry.height);
1200 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1201 (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu%+ld%+ld",
1202 (unsigned long) geometry.width,(unsigned long) geometry.height,
1203 (long) geometry.x,(long) geometry.y);
1204 (void) SetImageOption(_image_info,option+1,page);
1205 (void) CloneString(&_image_info->page,page);
1208 if (LocaleCompare("ping",option+1) == 0)
1210 _image_info->ping = ArgBoolean;
1213 if (LocaleCompare("pointsize",option+1) == 0)
1216 if (IsGeometry(arg1) == MagickFalse)
1217 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1218 _image_info->pointsize =
1219 _draw_info->pointsize =
1220 StringToDouble(arg1,(char **) NULL);
1223 _image_info->pointsize=0.0; /* unset pointsize */
1224 _draw_info->pointsize=12.0;
1228 if (LocaleCompare("precision",option+1) == 0)
1230 arg1=ArgOption("-1");
1231 if (IsGeometry(arg1) == MagickFalse)
1232 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1233 (void) SetMagickPrecision(StringToInteger(arg1));
1236 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1240 if (LocaleCompare("quality",option+1) == 0)
1242 if (IsGeometry(arg1) == MagickFalse)
1243 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1244 _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
1245 : UNDEFINED_COMPRESSION_QUALITY;
1246 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1249 if (LocaleCompare("quantize",option+1) == 0)
1251 /* Just a set direct in _quantize_info */
1252 arg1=ArgOption("undefined");
1253 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
1255 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
1257 _quantize_info->colorspace=(ColorspaceType)parse;
1260 if (LocaleCompare("quiet",option+1) == 0)
1262 /* FUTURE: if two -quiet is performed you can not do +quiet!
1263 This needs to be checked over thoughly.
1265 static WarningHandler
1266 warning_handler = (WarningHandler) NULL;
1269 tmp = SetWarningHandler((WarningHandler) NULL);
1271 if ( tmp != (WarningHandler) NULL)
1272 warning_handler = tmp; /* remember the old handler */
1273 if (!IfSetOption) /* set the old handler */
1274 warning_handler=SetWarningHandler(warning_handler);
1277 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1281 if (LocaleCompare("red-primary",option+1) == 0)
1283 /* Image chromaticity X,Y NB: Y=X if Y not defined
1285 SyncImageSettings() used to set per-image attribute.
1287 arg1=ArgOption("0.0");
1288 if (IsGeometry(arg1) == MagickFalse)
1289 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1290 (void) SetImageOption(_image_info,option+1,arg1);
1293 if (LocaleCompare("regard-warnings",option+1) == 0)
1294 /* FUTURE: to be replaced by a 'fatal-level' type setting */
1296 if (LocaleCompare("render",option+1) == 0)
1298 /* _draw_info only setting */
1299 _draw_info->render= ArgBooleanNot;
1302 if (LocaleCompare("respect-parenthesis",option+1) == 0)
1304 /* link image and setting stacks - option is itself saved on stack! */
1305 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1308 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1312 if (LocaleCompare("sampling-factor",option+1) == 0)
1314 /* FUTURE: should be converted to jpeg:sampling_factor */
1315 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1316 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1317 (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
1320 if (LocaleCompare("scene",option+1) == 0)
1322 /* SyncImageSettings() used to set this as a per-image attribute.
1325 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1326 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1327 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1328 _image_info->scene=StringToUnsignedLong(ArgOption("0"));
1331 if (LocaleCompare("seed",option+1) == 0)
1333 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1334 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1336 IfSetOption ? (unsigned long) StringToUnsignedLong(arg1)
1337 : (unsigned long) time((time_t *) NULL) );
1340 if (LocaleCompare("size",option+1) == 0)
1342 /* FUTURE: string in _image_info -- convert to Option ???
1343 Look at the special handling for "size" in SetImageOption()
1345 (void) CloneString(&_image_info->size,ArgOption(NULL));
1348 if (LocaleCompare("stretch",option+1) == 0)
1350 arg1=ArgOption("undefined");
1351 parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
1353 CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
1355 _draw_info->stretch=(StretchType) parse;
1358 if (LocaleCompare("stroke",option+1) == 0)
1360 /* set stroke color OR stroke-pattern
1361 UPDATE: ensure stroke color is not destroyed is a pattern
1362 is given. Just in case the color is also used for other purposes.
1373 arg1 = ArgOption("none"); /* +fill turns it off! */
1374 (void) SetImageOption(_image_info,option+1,arg1);
1375 if (_draw_info->stroke_pattern != (Image *) NULL)
1376 _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
1378 /* is it a color or a image? -- ignore exceptions */
1379 sans=AcquireExceptionInfo();
1380 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
1381 sans=DestroyExceptionInfo(sans);
1383 if (status == MagickFalse)
1384 _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
1386 _draw_info->stroke=color;
1389 if (LocaleCompare("strokewidth",option+1) == 0)
1391 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1392 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1393 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1394 _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
1398 if (LocaleCompare("style",option+1) == 0)
1400 arg1=ArgOption("undefined");
1401 parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
1403 CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
1405 _draw_info->style=(StyleType) parse;
1409 if (LocaleCompare("subimage-search",option+1) == 0)
1411 /* FUTURE: this is only used by CompareImages() which is used
1412 only by the "compare" CLI program at this time. */
1413 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1417 if (LocaleCompare("synchronize",option+1) == 0)
1419 /* FUTURE: syncronize to storage - but what does that mean? */
1420 _image_info->synchronize = ArgBoolean;
1423 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1427 if (LocaleCompare("taint",option+1) == 0)
1429 /* SyncImageSettings() used to set per-image attribute. */
1430 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1433 if (LocaleCompare("texture",option+1) == 0)
1435 /* Note: arguments do not have percent escapes expanded */
1436 /* FUTURE: move _image_info string to option splay-tree
1437 Other than "montage" what uses "texture" ????
1439 (void) CloneString(&_image_info->texture,ArgOption(NULL));
1442 if (LocaleCompare("tile",option+1) == 0)
1444 /* Note: arguments do not have percent escapes expanded */
1445 _draw_info->fill_pattern=IfSetOption
1446 ?GetImageCache(_image_info,arg1,_exception)
1447 :DestroyImage(_draw_info->fill_pattern);
1450 if (LocaleCompare("tile-offset",option+1) == 0)
1452 /* SyncImageSettings() used to set per-image attribute. ??? */
1453 arg1=ArgOption("0");
1454 if (IsGeometry(arg1) == MagickFalse)
1455 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1456 (void) SetImageOption(_image_info,option+1,arg1);
1459 if (LocaleCompare("transparent-color",option+1) == 0)
1461 /* FUTURE: both _image_info attribute & ImageOption in use!
1462 _image_info only used for generating new images.
1463 SyncImageSettings() used to set per-image attribute.
1465 Note that +transparent-color, means fall-back to image
1466 attribute so ImageOption is deleted, not set to a default.
1468 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1469 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1470 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1471 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
1472 &_image_info->transparent_color,_exception);
1475 if (LocaleCompare("treedepth",option+1) == 0)
1477 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1478 _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
1481 if (LocaleCompare("type",option+1) == 0)
1483 /* SyncImageSettings() used to set per-image attribute. */
1484 parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
1485 ArgOption("undefined"));
1487 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
1489 _image_info->type=(ImageType) parse;
1490 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1493 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1497 if (LocaleCompare("undercolor",option+1) == 0)
1499 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1500 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
1501 &_draw_info->undercolor,_exception);
1504 if (LocaleCompare("units",option+1) == 0)
1506 /* SyncImageSettings() used to set per-image attribute.
1507 Should this effect _draw_info X and Y resolution?
1508 FUTURE: this probably should be part of the density setting
1510 parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1511 ArgOption("undefined"));
1513 CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
1515 _image_info->units=(ResolutionType) parse;
1516 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1519 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1523 if (LocaleCompare("verbose",option+1) == 0)
1525 /* FUTURE: Remember all options become image artifacts
1526 _image_info->verbose is only used by coders.
1528 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1529 _image_info->verbose= ArgBoolean;
1530 _image_info->ping=MagickFalse; /* verbose can't be a ping */
1533 if (LocaleCompare("virtual-pixel",option+1) == 0)
1535 /* SyncImageSettings() used to set per-image attribute.
1536 This is VERY deep in the image caching structure.
1538 parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1539 ArgOption("undefined"));
1541 CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
1543 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1546 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1550 if (LocaleCompare("weight",option+1) == 0)
1555 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,arg1);
1557 weight=(ssize_t) StringToUnsignedLong(arg1);
1558 _draw_info->weight=(size_t) weight;
1561 if (LocaleCompare("white-point",option+1) == 0)
1563 /* Used as a image chromaticity setting
1564 SyncImageSettings() used to set per-image attribute.
1566 arg1=ArgOption("0.0");
1567 if (IsGeometry(arg1) == MagickFalse)
1568 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1569 (void) SetImageOption(_image_info,option+1,arg1);
1572 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1575 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1578 /* clean up percent escape interpreted strings */
1579 if ((arg1 && arg1n) && (arg1 != arg1n ))
1580 arg1=DestroyString((char *) arg1);
1581 if ((arg2 && arg2n) && (arg2 != arg2n ))
1582 arg2=DestroyString((char *) arg2);
1587 #undef _quantize_info
1590 #undef ArgBooleanNot
1591 #undef ArgBooleanString
1598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1602 + C L I S i m p l e O p e r a t o r I m a g e s %
1606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1608 % CLISimpleOperatorImages() applys one simple image operation given to all
1609 % the images in the CLI wand, using any per-image or global settings that was
1610 % previously saved in the CLI wand.
1612 % It is assumed that any such settings are up-to-date.
1614 % The format of the WandSimpleOperatorImages method is:
1616 % MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,const char *option,
1617 % const char *arg1, const char *arg2,ExceptionInfo *exception)
1619 % A description of each parameter follows:
1621 % o cli_wand: structure holding settings and images to be operated on
1623 % o option: The option string for the operation
1625 % o arg1, arg2: optional argument strings to the operation
1630 CLISimpleOperatorImage() is an Internal subrountine to apply one simple
1631 image operation to the current image pointed to by the CLI wand.
1633 The image in the list may be modified in three different ways...
1634 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1635 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1636 * one image replace by a list of images (-separate and -crop only!)
1638 In each case the result replaces the single original image in the list, as
1639 well as the pointer to the modified image (last image added if replaced by a
1640 list of images) is returned.
1642 As the image pointed to may be replaced, the first image in the list may
1643 also change. GetFirstImageInList() should be used by caller if they wish
1644 return the Image pointer to the first image in list.
1646 static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
1647 const char *option, const char *arg1n, const char *arg2n,
1648 ExceptionInfo *exception)
1665 const char /* percent escaped versions of the args */
1669 #define _image_info (cli_wand->wand.image_info)
1670 #define _image (cli_wand->wand.images)
1671 #define _exception (cli_wand->wand.exception)
1672 #define _draw_info (cli_wand->draw_info)
1673 #define _quantize_info (cli_wand->quantize_info)
1674 #define _process_flags (cli_wand->process_flags)
1675 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
1676 #define IfNormalOp (*option=='-')
1677 #define IfPlusOp (*option!='-')
1678 #define IsNormalOp IfNormalOp ? MagickTrue : MagickFalse
1679 #define IsPlusOp IfNormalOp ? MagickFalse : MagickTrue
1681 assert(cli_wand != (MagickCLI *) NULL);
1682 assert(cli_wand->signature == MagickWandSignature);
1683 assert(cli_wand->wand.signature == MagickWandSignature);
1684 assert(_image != (Image *) NULL); /* an image must be present */
1685 if (cli_wand->wand.debug != MagickFalse)
1686 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
1691 /* Interpret Percent Escapes in Arguments - using first image */
1692 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
1693 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
1694 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
1695 /* Interpret Percent escapes in argument 1 */
1696 if (arg1n != (char *) NULL) {
1697 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
1698 if (arg1 == (char *) NULL) {
1699 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1700 arg1=arg1n; /* use the given argument as is */
1703 if (arg2n != (char *) NULL) {
1704 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
1705 if (arg2 == (char *) NULL) {
1706 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1707 arg2=arg2n; /* use the given argument as is */
1711 #undef _process_flags
1715 (void) FormatLocaleFile(stderr,
1716 "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
1719 new_image = (Image *) NULL; /* the replacement image, if not null at end */
1720 SetGeometryInfo(&geometry_info);
1722 switch (*(option+1))
1726 if (LocaleCompare("adaptive-blur",option+1) == 0)
1728 flags=ParseGeometry(arg1,&geometry_info);
1729 if ((flags & (RhoValue|SigmaValue)) == 0)
1730 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1731 if ((flags & SigmaValue) == 0)
1732 geometry_info.sigma=1.0;
1733 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
1734 geometry_info.sigma,_exception);
1737 if (LocaleCompare("adaptive-resize",option+1) == 0)
1739 /* FUTURE: Roll into a resize special operator */
1740 if (IsGeometry(arg1) == MagickFalse)
1741 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1742 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1743 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
1747 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
1749 flags=ParseGeometry(arg1,&geometry_info);
1750 if ((flags & (RhoValue|SigmaValue)) == 0)
1751 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1752 if ((flags & SigmaValue) == 0)
1753 geometry_info.sigma=1.0;
1754 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
1755 geometry_info.sigma,_exception);
1758 if (LocaleCompare("alpha",option+1) == 0)
1760 parse=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,arg1);
1762 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelOption",
1764 (void) SetImageAlphaChannel(_image,(AlphaChannelOption) parse,
1768 if (LocaleCompare("annotate",option+1) == 0)
1771 geometry[MagickPathExtent];
1773 SetGeometryInfo(&geometry_info);
1774 flags=ParseGeometry(arg1,&geometry_info);
1776 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1777 if ((flags & SigmaValue) == 0)
1778 geometry_info.sigma=geometry_info.rho;
1779 (void) CloneString(&_draw_info->text,arg2);
1780 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
1781 geometry_info.xi,geometry_info.psi);
1782 (void) CloneString(&_draw_info->geometry,geometry);
1783 _draw_info->affine.sx=cos(DegreesToRadians(
1784 fmod(geometry_info.rho,360.0)));
1785 _draw_info->affine.rx=sin(DegreesToRadians(
1786 fmod(geometry_info.rho,360.0)));
1787 _draw_info->affine.ry=(-sin(DegreesToRadians(
1788 fmod(geometry_info.sigma,360.0))));
1789 _draw_info->affine.sy=cos(DegreesToRadians(
1790 fmod(geometry_info.sigma,360.0)));
1791 (void) AnnotateImage(_image,_draw_info,_exception);
1792 GetAffineMatrix(&_draw_info->affine);
1795 if (LocaleCompare("auto-gamma",option+1) == 0)
1797 (void) AutoGammaImage(_image,_exception);
1800 if (LocaleCompare("auto-level",option+1) == 0)
1802 (void) AutoLevelImage(_image,_exception);
1805 if (LocaleCompare("auto-orient",option+1) == 0)
1807 new_image=AutoOrientImage(_image,_image->orientation,_exception);
1810 if (LocaleCompare("auto-threshold",option+1) == 0)
1815 method=(AutoThresholdMethod) ParseCommandOption(
1816 MagickAutoThresholdOptions,MagickFalse,arg1);
1817 (void) AutoThresholdImage(_image,method,_exception);
1820 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1824 if (LocaleCompare("black-threshold",option+1) == 0)
1826 if (IsGeometry(arg1) == MagickFalse)
1827 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1828 (void) BlackThresholdImage(_image,arg1,_exception);
1831 if (LocaleCompare("blue-shift",option+1) == 0)
1833 geometry_info.rho=1.5;
1835 flags=ParseGeometry(arg1,&geometry_info);
1836 if ((flags & RhoValue) == 0)
1837 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1839 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
1842 if (LocaleCompare("blur",option+1) == 0)
1844 flags=ParseGeometry(arg1,&geometry_info);
1845 if ((flags & (RhoValue|SigmaValue)) == 0)
1846 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1847 if ((flags & SigmaValue) == 0)
1848 geometry_info.sigma=1.0;
1849 new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
1853 if (LocaleCompare("border",option+1) == 0)
1861 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
1862 if ((flags & (WidthValue | HeightValue)) == 0)
1863 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1864 compose=OverCompositeOp;
1865 value=GetImageOption(_image_info,"compose");
1866 if (value != (const char *) NULL)
1867 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
1869 new_image=BorderImage(_image,&geometry,compose,_exception);
1872 if (LocaleCompare("brightness-contrast",option+1) == 0)
1884 flags=ParseGeometry(arg1,&geometry_info);
1885 if ((flags & RhoValue) == 0)
1886 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1887 brightness=geometry_info.rho;
1889 if ((flags & SigmaValue) != 0)
1890 contrast=geometry_info.sigma;
1891 (void) BrightnessContrastImage(_image,brightness,contrast,
1895 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1899 if (LocaleCompare("canny",option+1) == 0)
1901 flags=ParseGeometry(arg1,&geometry_info);
1902 if ((flags & (RhoValue|SigmaValue)) == 0)
1903 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1904 if ((flags & SigmaValue) == 0)
1905 geometry_info.sigma=1.0;
1906 if ((flags & XiValue) == 0)
1907 geometry_info.xi=10;
1908 if ((flags & PsiValue) == 0)
1909 geometry_info.psi=30;
1910 if ((flags & PercentValue) != 0)
1912 geometry_info.xi/=100.0;
1913 geometry_info.psi/=100.0;
1915 new_image=CannyEdgeImage(_image,geometry_info.rho,geometry_info.sigma,
1916 geometry_info.xi,geometry_info.psi,_exception);
1919 if (LocaleCompare("cdl",option+1) == 0)
1922 *color_correction_collection; /* Note: arguments do not have percent escapes expanded */
1925 Color correct with a color decision list.
1927 color_correction_collection=FileToString(arg1,~0UL,_exception);
1928 if (color_correction_collection == (char *) NULL)
1930 (void) ColorDecisionListImage(_image,color_correction_collection,
1934 if (LocaleCompare("channel",option+1) == 0)
1938 (void) SetPixelChannelMask(_image,DefaultChannels);
1941 parse=ParseChannelOption(arg1);
1943 CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",option,
1945 (void) SetPixelChannelMask(_image,(ChannelType) parse);
1948 if (LocaleCompare("charcoal",option+1) == 0)
1950 flags=ParseGeometry(arg1,&geometry_info);
1951 if ((flags & (RhoValue|SigmaValue)) == 0)
1952 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1953 if ((flags & SigmaValue) == 0)
1954 geometry_info.sigma=1.0;
1955 if ((flags & XiValue) == 0)
1956 geometry_info.xi=1.0;
1957 new_image=CharcoalImage(_image,geometry_info.rho,geometry_info.sigma,
1961 if (LocaleCompare("chop",option+1) == 0)
1963 if (IsGeometry(arg1) == MagickFalse)
1964 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1965 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1966 new_image=ChopImage(_image,&geometry,_exception);
1969 if (LocaleCompare("clamp",option+1) == 0)
1971 (void) ClampImage(_image,_exception);
1974 if (LocaleCompare("clip",option+1) == 0)
1977 (void) ClipImage(_image,_exception);
1978 else /* "+mask" remove the write mask */
1979 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,_exception);
1982 if (LocaleCompare("clip-mask",option+1) == 0)
1988 /* use "+clip-mask" Remove the write mask for -clip-path */
1989 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,_exception);
1992 clip_mask=GetImageCache(_image_info,arg1,_exception);
1993 if (clip_mask == (Image *) NULL)
1995 (void) SetImageMask(_image,WritePixelMask,clip_mask,_exception);
1996 clip_mask=DestroyImage(clip_mask);
1999 if (LocaleCompare("clip-path",option+1) == 0)
2001 (void) ClipImagePath(_image,arg1,IsNormalOp,_exception);
2002 /* Note: Use "+clip-mask" remove the write mask added */
2005 if (LocaleCompare("colorize",option+1) == 0)
2007 if (IsGeometry(arg1) == MagickFalse)
2008 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2009 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
2012 if (LocaleCompare("color-matrix",option+1) == 0)
2017 kernel=AcquireKernelInfo(arg1,exception);
2018 if (kernel == (KernelInfo *) NULL)
2019 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2020 new_image=ColorMatrixImage(_image,kernel,_exception);
2021 kernel=DestroyKernelInfo(kernel);
2024 if (LocaleCompare("colors",option+1) == 0)
2026 /* Reduce the number of colors in the image.
2027 FUTURE: also provide 'plus version with image 'color counts'
2029 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2030 if (_quantize_info->number_colors == 0)
2031 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2032 if ((_image->storage_class == DirectClass) ||
2033 _image->colors > _quantize_info->number_colors)
2034 (void) QuantizeImage(_quantize_info,_image,_exception);
2036 (void) CompressImageColormap(_image,_exception);
2039 if (LocaleCompare("colorspace",option+1) == 0)
2041 /* WARNING: this is both a image_info setting (already done)
2042 and a operator to change image colorspace.
2044 FUTURE: default colorspace should be sRGB!
2045 Unless some type of 'linear colorspace' mode is set.
2047 Note that +colorspace sets "undefined" or no effect on
2048 new images, but forces images already in memory back to RGB!
2049 That seems to be a little strange!
2051 (void) TransformImageColorspace(_image,
2052 IfNormalOp ? _image_info->colorspace : sRGBColorspace,
2056 if (LocaleCompare("connected-components",option+1) == 0)
2058 if (IsGeometry(arg1) == MagickFalse)
2059 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2060 new_image=ConnectedComponentsImage(_image,(size_t)
2061 StringToInteger(arg1),(CCObjectInfo **) NULL,_exception);
2064 if (LocaleCompare("contrast",option+1) == 0)
2066 CLIWandWarnReplaced(IfNormalOp?"-level":"+level");
2067 (void) ContrastImage(_image,IsNormalOp,_exception);
2070 if (LocaleCompare("contrast-stretch",option+1) == 0)
2079 flags=ParseGeometry(arg1,&geometry_info);
2080 if ((flags & RhoValue) == 0)
2081 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2082 black_point=geometry_info.rho;
2083 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2085 if ((flags & PercentValue) != 0) {
2086 black_point*=(double) _image->columns*_image->rows/100.0;
2087 white_point*=(double) _image->columns*_image->rows/100.0;
2089 white_point=(double) _image->columns*_image->rows-white_point;
2090 (void) ContrastStretchImage(_image,black_point,white_point,
2094 if (LocaleCompare("convolve",option+1) == 0)
2105 kernel_info=AcquireKernelInfo(arg1,exception);
2106 if (kernel_info == (KernelInfo *) NULL)
2107 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2109 for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
2110 gamma+=kernel_info->values[j];
2111 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
2112 for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
2113 kernel_info->values[j]*=gamma;
2114 new_image=MorphologyImage(_image,CorrelateMorphology,1,kernel_info,
2116 kernel_info=DestroyKernelInfo(kernel_info);
2119 if (LocaleCompare("crop",option+1) == 0)
2121 /* WARNING: This can generate multiple images! */
2122 if (IsGeometry(arg1) == MagickFalse)
2123 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2124 new_image=CropImageToTiles(_image,arg1,_exception);
2127 if (LocaleCompare("cycle",option+1) == 0)
2129 if (IsGeometry(arg1) == MagickFalse)
2130 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2131 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2135 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2139 if (LocaleCompare("decipher",option+1) == 0)
2141 /* Note: arguments do not have percent escapes expanded */
2145 passkey=FileToStringInfo(arg1,~0UL,_exception);
2146 if (passkey == (StringInfo *) NULL)
2147 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2149 (void) PasskeyDecipherImage(_image,passkey,_exception);
2150 passkey=DestroyStringInfo(passkey);
2153 if (LocaleCompare("depth",option+1) == 0)
2155 /* The _image_info->depth setting has already been set
2156 We just need to apply it to all images in current sequence
2158 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2159 That is it really is an operation, not a setting! Arrgghhh
2161 FUTURE: this should not be an operator!!!
2163 (void) SetImageDepth(_image,_image_info->depth,_exception);
2166 if (LocaleCompare("deskew",option+1) == 0)
2172 if (IsGeometry(arg1) == MagickFalse)
2173 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2174 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
2177 threshold=40.0*QuantumRange/100.0;
2178 new_image=DeskewImage(_image,threshold,_exception);
2181 if (LocaleCompare("despeckle",option+1) == 0)
2183 new_image=DespeckleImage(_image,_exception);
2186 if (LocaleCompare("distort",option+1) == 0)
2194 parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2196 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2198 if ((DistortMethod) parse == ResizeDistortion)
2202 /* Special Case - Argument is actually a resize geometry!
2203 ** Convert that to an appropriate distortion argument array.
2204 ** FUTURE: make a separate special resize operator
2205 Roll into a resize special operator */
2206 if (IsGeometry(arg2) == MagickFalse)
2207 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2209 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
2210 resize_args[0]=(double) geometry.width;
2211 resize_args[1]=(double) geometry.height;
2212 new_image=DistortImage(_image,(DistortMethod) parse,
2213 (size_t)2,resize_args,MagickTrue,_exception);
2216 /* convert argument string into an array of doubles */
2217 args = StringToArrayOfDoubles(arg2,&count,_exception);
2218 if (args == (double *) NULL )
2219 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2221 new_image=DistortImage(_image,(DistortMethod) parse,(size_t)
2222 count,args,IsPlusOp,_exception);
2223 args=(double *) RelinquishMagickMemory(args);
2226 if (LocaleCompare("draw",option+1) == 0)
2228 (void) CloneString(&_draw_info->primitive,arg1);
2229 (void) DrawImage(_image,_draw_info,_exception);
2230 (void) CloneString(&_draw_info->primitive,(char *) NULL);
2233 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2237 if (LocaleCompare("edge",option+1) == 0)
2239 flags=ParseGeometry(arg1,&geometry_info);
2240 if ((flags & (RhoValue|SigmaValue)) == 0)
2241 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2242 new_image=EdgeImage(_image,geometry_info.rho,_exception);
2245 if (LocaleCompare("emboss",option+1) == 0)
2247 flags=ParseGeometry(arg1,&geometry_info);
2248 if ((flags & (RhoValue|SigmaValue)) == 0)
2249 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2250 if ((flags & SigmaValue) == 0)
2251 geometry_info.sigma=1.0;
2252 new_image=EmbossImage(_image,geometry_info.rho,
2253 geometry_info.sigma,_exception);
2256 if (LocaleCompare("encipher",option+1) == 0)
2258 /* Note: arguments do not have percent escapes expanded */
2262 passkey=FileToStringInfo(arg1,~0UL,_exception);
2263 if (passkey != (StringInfo *) NULL)
2265 (void) PasskeyEncipherImage(_image,passkey,_exception);
2266 passkey=DestroyStringInfo(passkey);
2270 if (LocaleCompare("enhance",option+1) == 0)
2272 new_image=EnhanceImage(_image,_exception);
2275 if (LocaleCompare("equalize",option+1) == 0)
2277 (void) EqualizeImage(_image,_exception);
2280 if (LocaleCompare("evaluate",option+1) == 0)
2285 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
2287 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
2289 if (IsGeometry(arg2) == MagickFalse)
2290 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
2291 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
2292 (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
2296 if (LocaleCompare("extent",option+1) == 0)
2298 if (IsGeometry(arg1) == MagickFalse)
2299 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2300 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
2301 if (geometry.width == 0)
2302 geometry.width=_image->columns;
2303 if (geometry.height == 0)
2304 geometry.height=_image->rows;
2305 new_image=ExtentImage(_image,&geometry,_exception);
2308 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2312 if (LocaleCompare("flip",option+1) == 0)
2314 new_image=FlipImage(_image,_exception);
2317 if (LocaleCompare("flop",option+1) == 0)
2319 new_image=FlopImage(_image,_exception);
2322 if (LocaleCompare("floodfill",option+1) == 0)
2327 if (IsGeometry(arg1) == MagickFalse)
2328 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2329 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2330 (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
2331 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2332 geometry.y,IsPlusOp,_exception);
2335 if (LocaleCompare("frame",option+1) == 0)
2346 value=GetImageOption(_image_info,"compose");
2347 compose=OverCompositeOp; /* use Over not _image->compose */
2348 if (value != (const char *) NULL)
2349 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
2351 if (IsGeometry(arg1) == MagickFalse)
2352 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2353 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
2354 frame_info.width=geometry.width;
2355 frame_info.height=geometry.height;
2356 frame_info.outer_bevel=geometry.x;
2357 frame_info.inner_bevel=geometry.y;
2358 frame_info.x=(ssize_t) frame_info.width;
2359 frame_info.y=(ssize_t) frame_info.height;
2360 frame_info.width=_image->columns+2*frame_info.width;
2361 frame_info.height=_image->rows+2*frame_info.height;
2362 new_image=FrameImage(_image,&frame_info,compose,_exception);
2365 if (LocaleCompare("function",option+1) == 0)
2373 parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
2375 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2377 /* convert argument string into an array of doubles */
2378 args = StringToArrayOfDoubles(arg2,&count,_exception);
2379 if (args == (double *) NULL )
2380 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2382 (void) FunctionImage(_image,(MagickFunction)parse,(size_t) count,args,
2384 args=(double *) RelinquishMagickMemory(args);
2387 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2391 if (LocaleCompare("gamma",option+1) == 0)
2396 if (IsGeometry(arg1) == MagickFalse)
2397 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2398 constant=StringToDouble(arg1,(char **) NULL);
2400 /* Using Gamma, via a cache */
2402 constant=PerceptibleReciprocal(constant);
2403 (void) GammaImage(_image,constant,_exception);
2405 /* Using Evaluate POW, direct update of values - more accurite */
2407 constant=PerceptibleReciprocal(constant);
2408 (void) EvaluateImage(_image,PowEvaluateOperator,constant,_exception);
2409 _image->gamma*=StringToDouble(arg1,(char **) NULL);
2411 /* Set gamma setting -- Old meaning of "+gamma"
2412 * _image->gamma=StringToDouble(arg1,(char **) NULL);
2416 if (LocaleCompare("gaussian-blur",option+1) == 0)
2418 flags=ParseGeometry(arg1,&geometry_info);
2419 if ((flags & (RhoValue|SigmaValue)) == 0)
2420 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2421 if ((flags & SigmaValue) == 0)
2422 geometry_info.sigma=1.0;
2423 new_image=GaussianBlurImage(_image,geometry_info.rho,
2424 geometry_info.sigma,_exception);
2427 if (LocaleCompare("gaussian",option+1) == 0)
2429 CLIWandWarnReplaced("-gaussian-blur");
2430 (void) CLISimpleOperatorImage(cli_wand,"-gaussian-blur",arg1,NULL,exception);
2432 if (LocaleCompare("geometry",option+1) == 0)
2435 Record Image offset for composition. (A Setting)
2436 Resize last _image. (ListOperator) -- DEPRECIATE
2437 FUTURE: Why if no 'offset' does this resize ALL images?
2438 Also why is the setting recorded in the IMAGE non-sense!
2441 { /* remove the previous composition geometry offset! */
2442 if (_image->geometry != (char *) NULL)
2443 _image->geometry=DestroyString(_image->geometry);
2446 if (IsGeometry(arg1) == MagickFalse)
2447 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2448 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
2449 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2450 (void) CloneString(&_image->geometry,arg1);
2452 new_image=ResizeImage(_image,geometry.width,geometry.height,
2453 _image->filter,_exception);
2456 if (LocaleCompare("grayscale",option+1) == 0)
2458 parse=ParseCommandOption(MagickPixelIntensityOptions,
2461 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
2463 (void) GrayscaleImage(_image,(PixelIntensityMethod) parse,_exception);
2466 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2470 if (LocaleCompare("hough-lines",option+1) == 0)
2472 flags=ParseGeometry(arg1,&geometry_info);
2473 if ((flags & (RhoValue|SigmaValue)) == 0)
2474 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2475 if ((flags & SigmaValue) == 0)
2476 geometry_info.sigma=geometry_info.rho;
2477 if ((flags & XiValue) == 0)
2478 geometry_info.xi=40;
2479 new_image=HoughLineImage(_image,(size_t) geometry_info.rho,
2480 (size_t) geometry_info.sigma,(size_t) geometry_info.xi,_exception);
2483 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2487 if (LocaleCompare("identify",option+1) == 0)
2493 format=GetImageOption(_image_info,"format");
2494 if (format == (char *) NULL)
2496 (void) IdentifyImage(_image,stdout,_image_info->verbose,
2500 text=InterpretImageProperties(_image_info,_image,format,_exception);
2501 if (text == (char *) NULL)
2502 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
2504 (void) fputs(text,stdout);
2505 text=DestroyString((char *)text);
2508 if (LocaleCompare("implode",option+1) == 0)
2510 flags=ParseGeometry(arg1,&geometry_info);
2511 if ((flags & RhoValue) == 0)
2512 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2513 new_image=ImplodeImage(_image,geometry_info.rho,_image->interpolate,
2517 if (LocaleCompare("interpolative-resize",option+1) == 0)
2519 /* FUTURE: New to IMv7
2520 Roll into a resize special operator */
2521 if (IsGeometry(arg1) == MagickFalse)
2522 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2523 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2524 new_image=InterpolativeResizeImage(_image,geometry.width,
2525 geometry.height,_image->interpolate,_exception);
2528 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2532 if (LocaleCompare("kuwahara",option+1) == 0)
2535 Edge preserving blur.
2537 flags=ParseGeometry(arg1,&geometry_info);
2538 if ((flags & (RhoValue|SigmaValue)) == 0)
2539 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2540 if ((flags & SigmaValue) == 0)
2541 geometry_info.sigma=geometry_info.rho-0.5;
2542 new_image=KuwaharaImage(_image,geometry_info.rho,geometry_info.sigma,
2546 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2550 if (LocaleCompare("lat",option+1) == 0)
2552 flags=ParseGeometry(arg1,&geometry_info);
2553 if ((flags & (RhoValue|SigmaValue)) == 0)
2554 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2555 if ((flags & SigmaValue) == 0)
2556 geometry_info.sigma=1.0;
2557 if ((flags & PercentValue) != 0)
2558 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2559 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
2560 (size_t) geometry_info.sigma,(double) geometry_info.xi,
2564 if (LocaleCompare("level",option+1) == 0)
2574 flags=ParseGeometry(arg1,&geometry_info);
2575 if ((flags & RhoValue) == 0)
2576 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2577 black_point=geometry_info.rho;
2578 white_point=(double) QuantumRange;
2579 if ((flags & SigmaValue) != 0)
2580 white_point=geometry_info.sigma;
2582 if ((flags & XiValue) != 0)
2583 gamma=geometry_info.xi;
2584 if ((flags & PercentValue) != 0)
2586 black_point*=(double) (QuantumRange/100.0);
2587 white_point*=(double) (QuantumRange/100.0);
2589 if ((flags & SigmaValue) == 0)
2590 white_point=(double) QuantumRange-black_point;
2591 if (IfPlusOp || ((flags & AspectValue) != 0))
2592 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
2594 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
2597 if (LocaleCompare("level-colors",option+1) == 0)
2600 token[MagickPathExtent];
2609 p=(const char *) arg1;
2610 GetNextToken(p,&p,MagickPathExtent,token); /* get black point color */
2611 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2612 (void) QueryColorCompliance(token,AllCompliance,
2613 &black_point,_exception);
2615 (void) QueryColorCompliance("#000000",AllCompliance,
2616 &black_point,_exception);
2617 if (isalpha((int) token[0]) || (token[0] == '#'))
2618 GetNextToken(p,&p,MagickPathExtent,token);
2620 white_point=black_point; /* set everything to that color */
2623 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2624 GetNextToken(p,&p,MagickPathExtent,token); /* Get white point color. */
2625 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2626 (void) QueryColorCompliance(token,AllCompliance,
2627 &white_point,_exception);
2629 (void) QueryColorCompliance("#ffffff",AllCompliance,
2630 &white_point,_exception);
2632 (void) LevelImageColors(_image,&black_point,&white_point,
2633 IsPlusOp,_exception);
2636 if (LocaleCompare("linear-stretch",option+1) == 0)
2645 flags=ParseGeometry(arg1,&geometry_info);
2646 if ((flags & RhoValue) == 0)
2647 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2648 black_point=geometry_info.rho;
2649 white_point=(double) _image->columns*_image->rows;
2650 if ((flags & SigmaValue) != 0)
2651 white_point=geometry_info.sigma;
2652 if ((flags & PercentValue) != 0)
2654 black_point*=(double) _image->columns*_image->rows/100.0;
2655 white_point*=(double) _image->columns*_image->rows/100.0;
2657 if ((flags & SigmaValue) == 0)
2658 white_point=(double) _image->columns*_image->rows-
2660 (void) LinearStretchImage(_image,black_point,white_point,_exception);
2663 if (LocaleCompare("liquid-rescale",option+1) == 0)
2665 /* FUTURE: Roll into a resize special operator */
2666 if (IsGeometry(arg1) == MagickFalse)
2667 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2668 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
2669 if ((flags & XValue) == 0)
2671 if ((flags & YValue) == 0)
2673 new_image=LiquidRescaleImage(_image,geometry.width,
2674 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
2677 if (LocaleCompare("local-contrast",option+1) == 0)
2682 flags=ParseGeometry(arg1,&geometry_info);
2683 if ((flags & RhoValue) == 0)
2684 geometry_info.rho=10;
2685 if ((flags & SigmaValue) == 0)
2686 geometry_info.sigma=12.5;
2687 new_image=LocalContrastImage(_image,geometry_info.rho,
2688 geometry_info.sigma,exception);
2691 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2695 if (LocaleCompare("magnify",option+1) == 0)
2697 new_image=MagnifyImage(_image,_exception);
2700 if (LocaleCompare("map",option+1) == 0)
2702 CLIWandWarnReplaced("-remap");
2703 (void) CLISimpleOperatorImage(cli_wand,"-remap",NULL,NULL,exception);
2706 if (LocaleCompare("mask",option+1) == 0)
2716 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,
2723 mask=GetImageCache(_image_info,arg1,_exception);
2724 if (mask == (Image *) NULL)
2726 (void) SetImageMask(_image,WritePixelMask,mask,_exception);
2727 mask=DestroyImage(mask);
2730 if (LocaleCompare("matte",option+1) == 0)
2732 CLIWandWarnReplaced(IfNormalOp?"-alpha Set":"-alpha Off");
2733 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2734 DeactivateAlphaChannel, _exception);
2737 if (LocaleCompare("mean-shift",option+1) == 0)
2739 flags=ParseGeometry(arg1,&geometry_info);
2740 if ((flags & (RhoValue|SigmaValue)) == 0)
2741 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2742 if ((flags & SigmaValue) == 0)
2743 geometry_info.sigma=1.0;
2744 if ((flags & XiValue) == 0)
2745 geometry_info.xi=0.10*QuantumRange;
2746 if ((flags & PercentValue) != 0)
2747 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2748 new_image=MeanShiftImage(_image,(size_t) geometry_info.rho,
2749 (size_t) geometry_info.sigma,geometry_info.xi,_exception);
2752 if (LocaleCompare("median",option+1) == 0)
2754 CLIWandWarnReplaced("-statistic Median");
2755 (void) CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1,exception);
2758 if (LocaleCompare("mode",option+1) == 0)
2760 /* FUTURE: note this is also a special "montage" option */
2761 CLIWandWarnReplaced("-statistic Mode");
2762 (void) CLISimpleOperatorImage(cli_wand,"-statistic","Mode",arg1,exception);
2765 if (LocaleCompare("modulate",option+1) == 0)
2767 if (IsGeometry(arg1) == MagickFalse)
2768 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2769 (void) ModulateImage(_image,arg1,_exception);
2772 if (LocaleCompare("monitor",option+1) == 0)
2774 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
2775 (MagickProgressMonitor) NULL,(void *) NULL);
2778 if (LocaleCompare("monochrome",option+1) == 0)
2780 (void) SetImageType(_image,BilevelType,_exception);
2783 if (LocaleCompare("morphology",option+1) == 0)
2786 token[MagickPathExtent];
2798 GetNextToken(p,&p,MagickPathExtent,token);
2799 parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
2801 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",option,
2804 GetNextToken(p,&p,MagickPathExtent,token);
2805 if ((*p == ':') || (*p == ','))
2806 GetNextToken(p,&p,MagickPathExtent,token);
2808 iterations=(ssize_t) StringToLong(p);
2809 kernel=AcquireKernelInfo(arg2,exception);
2810 if (kernel == (KernelInfo *) NULL)
2811 CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",option,arg2);
2812 new_image=MorphologyImage(_image,(MorphologyMethod)parse,iterations,
2814 kernel=DestroyKernelInfo(kernel);
2817 if (LocaleCompare("motion-blur",option+1) == 0)
2819 flags=ParseGeometry(arg1,&geometry_info);
2820 if ((flags & (RhoValue|SigmaValue)) == 0)
2821 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2822 if ((flags & SigmaValue) == 0)
2823 geometry_info.sigma=1.0;
2824 new_image=MotionBlurImage(_image,geometry_info.rho,geometry_info.sigma,
2825 geometry_info.xi,_exception);
2828 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2832 if (LocaleCompare("negate",option+1) == 0)
2834 (void) NegateImage(_image, IsPlusOp, _exception);
2837 if (LocaleCompare("noise",option+1) == 0)
2847 CLIWandWarnReplaced("-statistic NonPeak");
2848 (void) CLISimpleOperatorImage(cli_wand,"-statistic","NonPeak",arg1,exception);
2851 parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
2853 CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
2856 value=GetImageOption(_image_info,"attenuate");
2857 if (value != (const char *) NULL)
2858 attenuate=StringToDouble(value,(char **) NULL);
2859 new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
2863 if (LocaleCompare("normalize",option+1) == 0)
2865 (void) NormalizeImage(_image,_exception);
2868 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2872 if (LocaleCompare("opaque",option+1) == 0)
2877 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2878 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,IsPlusOp,
2882 if (LocaleCompare("ordered-dither",option+1) == 0)
2884 (void) OrderedDitherImage(_image,arg1,_exception);
2887 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2891 if (LocaleCompare("paint",option+1) == 0)
2893 flags=ParseGeometry(arg1,&geometry_info);
2894 if ((flags & (RhoValue|SigmaValue)) == 0)
2895 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2896 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2900 if (LocaleCompare("perceptible",option+1) == 0)
2902 (void) PerceptibleImage(_image,StringToDouble(arg1,(char **) NULL),
2906 if (LocaleCompare("polaroid",option+1) == 0)
2918 random_info=AcquireRandomInfo();
2919 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2920 random_info=DestroyRandomInfo(random_info);
2923 flags=ParseGeometry(arg1,&geometry_info);
2924 if ((flags & RhoValue) == 0)
2925 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2926 angle=geometry_info.rho;
2928 caption=GetImageProperty(_image,"caption",_exception);
2929 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2930 _image->interpolate,_exception);
2933 if (LocaleCompare("posterize",option+1) == 0)
2935 flags=ParseGeometry(arg1,&geometry_info);
2936 if ((flags & RhoValue) == 0)
2937 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2938 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
2939 _quantize_info->dither_method,_exception);
2942 if (LocaleCompare("preview",option+1) == 0)
2944 /* FUTURE: should be a 'Genesis' option?
2945 Option however is also in WandSettingOptionInfo()
2948 parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
2950 CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
2952 new_image=PreviewImage(_image,(PreviewType)parse,_exception);
2955 if (LocaleCompare("profile",option+1) == 0)
2969 /* Note: arguments do not have percent escapes expanded */
2971 { /* Remove a profile from the _image. */
2972 (void) ProfileImage(_image,arg1,(const unsigned char *)
2976 /* Associate a profile with the _image. */
2977 profile_info=CloneImageInfo(_image_info);
2978 profile=GetImageProfile(_image,"iptc");
2979 if (profile != (StringInfo *) NULL)
2980 profile_info->profile=(void *) CloneStringInfo(profile);
2981 profile_image=GetImageCache(profile_info,arg1,_exception);
2982 profile_info=DestroyImageInfo(profile_info);
2983 if (profile_image == (Image *) NULL)
2988 profile_info=CloneImageInfo(_image_info);
2989 (void) CopyMagickString(profile_info->filename,arg1,
2991 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
2992 if (profile != (StringInfo *) NULL)
2994 (void) SetImageInfo(profile_info,0,_exception);
2995 (void) ProfileImage(_image,profile_info->magick,
2996 GetStringInfoDatum(profile),(size_t)
2997 GetStringInfoLength(profile),_exception);
2998 profile=DestroyStringInfo(profile);
3000 profile_info=DestroyImageInfo(profile_info);
3003 ResetImageProfileIterator(profile_image);
3004 name=GetNextImageProfile(profile_image);
3005 while (name != (const char *) NULL)
3007 profile=GetImageProfile(profile_image,name);
3008 if (profile != (StringInfo *) NULL)
3009 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
3010 (size_t) GetStringInfoLength(profile),_exception);
3011 name=GetNextImageProfile(profile_image);
3013 profile_image=DestroyImage(profile_image);
3016 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3020 if (LocaleCompare("raise",option+1) == 0)
3022 if (IsGeometry(arg1) == MagickFalse)
3023 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3024 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3025 (void) RaiseImage(_image,&geometry,IsNormalOp,_exception);
3028 if (LocaleCompare("random-threshold",option+1) == 0)
3034 if (IsGeometry(arg1) == MagickFalse)
3035 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3037 max_threshold=(double) QuantumRange;
3038 flags=ParseGeometry(arg1,&geometry_info);
3039 min_threshold=geometry_info.rho;
3040 max_threshold=geometry_info.sigma;
3041 if ((flags & SigmaValue) == 0)
3042 max_threshold=min_threshold;
3043 if (strchr(arg1,'%') != (char *) NULL)
3045 max_threshold*=(double) (0.01*QuantumRange);
3046 min_threshold*=(double) (0.01*QuantumRange);
3048 (void) RandomThresholdImage(_image,min_threshold,max_threshold,
3052 if (LocaleCompare("range-threshold",option+1) == 0)
3055 Range threshold image.
3057 if (IsGeometry(arg1) == MagickFalse)
3058 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3059 flags=ParseGeometry(arg1,&geometry_info);
3060 if ((flags & SigmaValue) == 0)
3061 geometry_info.sigma=geometry_info.rho;
3062 if ((flags & XiValue) == 0)
3063 geometry_info.xi=geometry_info.sigma;
3064 if ((flags & PsiValue) == 0)
3065 geometry_info.psi=geometry_info.xi;
3066 if (strchr(arg1,'%') != (char *) NULL)
3068 geometry_info.rho*=(double) (0.01*QuantumRange);
3069 geometry_info.sigma*=(double) (0.01*QuantumRange);
3070 geometry_info.xi*=(double) (0.01*QuantumRange);
3071 geometry_info.psi*=(double) (0.01*QuantumRange);
3073 (void) RangeThresholdImage(_image,geometry_info.rho,
3074 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3077 if (LocaleCompare("read-mask",option+1) == 0)
3079 /* Note: arguments do not have percent escapes expanded */
3084 { /* Remove a mask. */
3085 (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,
3089 /* Set the image mask. */
3090 mask=GetImageCache(_image_info,arg1,_exception);
3091 if (mask == (Image *) NULL)
3093 (void) SetImageMask(_image,ReadPixelMask,mask,_exception);
3094 mask=DestroyImage(mask);
3097 if (LocaleCompare("recolor",option+1) == 0)
3099 CLIWandWarnReplaced("-color-matrix");
3100 (void) CLISimpleOperatorImage(cli_wand,"-color-matrix",arg1,NULL,
3103 if (LocaleCompare("region",option+1) == 0)
3107 (void) SetImageRegionMask(_image,WritePixelMask,
3108 (const RectangleInfo *) NULL,_exception);
3111 if (IsGeometry(arg1) == MagickFalse)
3112 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3113 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
3114 (void) SetImageRegionMask(_image,WritePixelMask,&geometry,_exception);
3117 if (LocaleCompare("remap",option+1) == 0)
3119 /* Note: arguments do not have percent escapes expanded */
3123 remap_image=GetImageCache(_image_info,arg1,_exception);
3124 if (remap_image == (Image *) NULL)
3126 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
3127 remap_image=DestroyImage(remap_image);
3130 if (LocaleCompare("repage",option+1) == 0)
3134 if (IsGeometry(arg1) == MagickFalse)
3135 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3137 (void) ResetImagePage(_image,arg1);
3140 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
3143 if (LocaleCompare("resample",option+1) == 0)
3145 /* FUTURE: Roll into a resize special operation */
3146 flags=ParseGeometry(arg1,&geometry_info);
3147 if ((flags & (RhoValue|SigmaValue)) == 0)
3148 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3149 if ((flags & SigmaValue) == 0)
3150 geometry_info.sigma=geometry_info.rho;
3151 new_image=ResampleImage(_image,geometry_info.rho,
3152 geometry_info.sigma,_image->filter,_exception);
3155 if (LocaleCompare("resize",option+1) == 0)
3157 if (IsGeometry(arg1) == MagickFalse)
3158 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3159 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3160 new_image=ResizeImage(_image,geometry.width,geometry.height,
3161 _image->filter,_exception);
3164 if (LocaleCompare("roll",option+1) == 0)
3166 if (IsGeometry(arg1) == MagickFalse)
3167 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3168 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3169 if ((flags & PercentValue) != 0)
3171 geometry.x*=(double) _image->columns/100.0;
3172 geometry.y*=(double) _image->rows/100.0;
3174 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
3177 if (LocaleCompare("rotate",option+1) == 0)
3179 flags=ParseGeometry(arg1,&geometry_info);
3180 if ((flags & RhoValue) == 0)
3181 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3182 if ((flags & GreaterValue) != 0 && (_image->columns <= _image->rows))
3184 if ((flags & LessValue) != 0 && (_image->columns >= _image->rows))
3186 new_image=RotateImage(_image,geometry_info.rho,_exception);
3189 if (LocaleCompare("rotational-blur",option+1) == 0)
3191 flags=ParseGeometry(arg1,&geometry_info);
3192 if ((flags & RhoValue) == 0)
3193 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3194 new_image=RotationalBlurImage(_image,geometry_info.rho,_exception);
3197 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3201 if (LocaleCompare("sample",option+1) == 0)
3203 /* FUTURE: Roll into a resize special operator */
3204 if (IsGeometry(arg1) == MagickFalse)
3205 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3206 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3207 new_image=SampleImage(_image,geometry.width,geometry.height,
3211 if (LocaleCompare("scale",option+1) == 0)
3213 /* FUTURE: Roll into a resize special operator */
3214 if (IsGeometry(arg1) == MagickFalse)
3215 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3216 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3217 new_image=ScaleImage(_image,geometry.width,geometry.height,
3221 if (LocaleCompare("segment",option+1) == 0)
3223 flags=ParseGeometry(arg1,&geometry_info);
3224 if ((flags & (RhoValue|SigmaValue)) == 0)
3225 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3226 if ((flags & SigmaValue) == 0)
3227 geometry_info.sigma=1.0;
3228 (void) SegmentImage(_image,_image->colorspace,
3229 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3233 if (LocaleCompare("selective-blur",option+1) == 0)
3235 flags=ParseGeometry(arg1,&geometry_info);
3236 if ((flags & (RhoValue|SigmaValue)) == 0)
3237 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3238 if ((flags & SigmaValue) == 0)
3239 geometry_info.sigma=1.0;
3240 if ((flags & PercentValue) != 0)
3241 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3242 new_image=SelectiveBlurImage(_image,geometry_info.rho,
3243 geometry_info.sigma,geometry_info.xi,_exception);
3246 if (LocaleCompare("separate",option+1) == 0)
3248 /* WARNING: This can generate multiple images! */
3249 /* FUTURE - this may be replaced by a "-channel" method */
3250 new_image=SeparateImages(_image,_exception);
3253 if (LocaleCompare("sepia-tone",option+1) == 0)
3255 if (IsGeometry(arg1) == MagickFalse)
3256 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3257 new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
3258 (double) QuantumRange+1.0),_exception);
3261 if (LocaleCompare("shade",option+1) == 0)
3263 flags=ParseGeometry(arg1,&geometry_info);
3264 if (((flags & RhoValue) == 0) || ((flags & SigmaValue) == 0))
3265 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3266 new_image=ShadeImage(_image,IsNormalOp,geometry_info.rho,
3267 geometry_info.sigma,_exception);
3270 if (LocaleCompare("shadow",option+1) == 0)
3272 flags=ParseGeometry(arg1,&geometry_info);
3273 if ((flags & (RhoValue|SigmaValue)) == 0)
3274 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3275 if ((flags & SigmaValue) == 0)
3276 geometry_info.sigma=1.0;
3277 if ((flags & XiValue) == 0)
3278 geometry_info.xi=4.0;
3279 if ((flags & PsiValue) == 0)
3280 geometry_info.psi=4.0;
3281 new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
3282 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3283 ceil(geometry_info.psi-0.5),_exception);
3286 if (LocaleCompare("sharpen",option+1) == 0)
3288 flags=ParseGeometry(arg1,&geometry_info);
3289 if ((flags & (RhoValue|SigmaValue)) == 0)
3290 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3291 if ((flags & SigmaValue) == 0)
3292 geometry_info.sigma=1.0;
3293 if ((flags & XiValue) == 0)
3294 geometry_info.xi=0.0;
3295 new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
3299 if (LocaleCompare("shave",option+1) == 0)
3301 if (IsGeometry(arg1) == MagickFalse)
3302 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3303 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3304 new_image=ShaveImage(_image,&geometry,_exception);
3307 if (LocaleCompare("shear",option+1) == 0)
3309 flags=ParseGeometry(arg1,&geometry_info);
3310 if ((flags & RhoValue) == 0)
3311 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3312 if ((flags & SigmaValue) == 0)
3313 geometry_info.sigma=geometry_info.rho;
3314 new_image=ShearImage(_image,geometry_info.rho,geometry_info.sigma,
3318 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
3320 flags=ParseGeometry(arg1,&geometry_info);
3321 if ((flags & RhoValue) == 0)
3322 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3323 if ((flags & SigmaValue) == 0)
3324 geometry_info.sigma=(double) QuantumRange/2.0;
3325 if ((flags & PercentValue) != 0)
3326 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3328 (void) SigmoidalContrastImage(_image,IsNormalOp,geometry_info.rho,
3329 geometry_info.sigma,_exception);
3332 if (LocaleCompare("sketch",option+1) == 0)
3334 flags=ParseGeometry(arg1,&geometry_info);
3335 if ((flags & (RhoValue|SigmaValue)) == 0)
3336 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3337 if ((flags & SigmaValue) == 0)
3338 geometry_info.sigma=1.0;
3339 new_image=SketchImage(_image,geometry_info.rho,
3340 geometry_info.sigma,geometry_info.xi,_exception);
3343 if (LocaleCompare("solarize",option+1) == 0)
3345 if (IsGeometry(arg1) == MagickFalse)
3346 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3347 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3348 QuantumRange+1.0),_exception);
3351 if (LocaleCompare("sparse-color",option+1) == 0)
3353 parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
3355 CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
3357 new_image=SparseColorOption(_image,(SparseColorMethod)parse,arg2,
3361 if (LocaleCompare("splice",option+1) == 0)
3363 if (IsGeometry(arg1) == MagickFalse)
3364 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3365 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
3366 new_image=SpliceImage(_image,&geometry,_exception);
3369 if (LocaleCompare("spread",option+1) == 0)
3371 flags=ParseGeometry(arg1,&geometry_info);
3372 if ((flags & RhoValue) == 0)
3373 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3374 new_image=SpreadImage(_image,_image->interpolate,geometry_info.rho,
3378 if (LocaleCompare("statistic",option+1) == 0)
3380 parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
3382 CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
3384 flags=ParseGeometry(arg2,&geometry_info);
3385 if ((flags & RhoValue) == 0)
3386 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3387 if ((flags & SigmaValue) == 0)
3388 geometry_info.sigma=geometry_info.rho;
3389 new_image=StatisticImage(_image,(StatisticType)parse,
3390 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3394 if (LocaleCompare("strip",option+1) == 0)
3396 (void) StripImage(_image,_exception);
3399 if (LocaleCompare("swirl",option+1) == 0)
3401 flags=ParseGeometry(arg1,&geometry_info);
3402 if ((flags & RhoValue) == 0)
3403 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3404 new_image=SwirlImage(_image,geometry_info.rho,
3405 _image->interpolate,_exception);
3408 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3412 if (LocaleCompare("threshold",option+1) == 0)
3417 threshold=(double) QuantumRange/2;
3419 if (IsGeometry(arg1) == MagickFalse)
3420 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3421 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
3423 (void) BilevelImage(_image,threshold,_exception);
3426 if (LocaleCompare("thumbnail",option+1) == 0)
3428 if (IsGeometry(arg1) == MagickFalse)
3429 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3430 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3431 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3435 if (LocaleCompare("tint",option+1) == 0)
3437 if (IsGeometry(arg1) == MagickFalse)
3438 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3439 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
3442 if (LocaleCompare("transform",option+1) == 0)
3444 CLIWandWarnReplaced("+distort AffineProjection");
3445 new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
3448 if (LocaleCompare("transparent",option+1) == 0)
3453 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3454 (void) TransparentPaintImage(_image,&target,(Quantum)
3455 TransparentAlpha,IsPlusOp,_exception);
3458 if (LocaleCompare("transpose",option+1) == 0)
3460 new_image=TransposeImage(_image,_exception);
3463 if (LocaleCompare("transverse",option+1) == 0)
3465 new_image=TransverseImage(_image,_exception);
3468 if (LocaleCompare("trim",option+1) == 0)
3470 new_image=TrimImage(_image,_exception);
3473 if (LocaleCompare("type",option+1) == 0)
3475 /* Note that "type" setting should have already been defined */
3476 (void) SetImageType(_image,_image_info->type,_exception);
3479 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3483 if (LocaleCompare("unique",option+1) == 0)
3485 /* FUTURE: move to SyncImageSettings() and AcqireImage()???
3486 Option is not documented, bt appears to be for "identify".
3487 We may need a identify specific verbose!
3490 (void) DeleteImageArtifact(_image,"identify:unique-colors");
3493 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3494 (void) SetImageArtifact(_image,"verbose","true");
3497 if (LocaleCompare("unique-colors",option+1) == 0)
3499 new_image=UniqueImageColors(_image,_exception);
3502 if (LocaleCompare("unsharp",option+1) == 0)
3504 flags=ParseGeometry(arg1,&geometry_info);
3505 if ((flags & (RhoValue|SigmaValue)) == 0)
3506 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3507 if ((flags & SigmaValue) == 0)
3508 geometry_info.sigma=1.0;
3509 if ((flags & XiValue) == 0)
3510 geometry_info.xi=1.0;
3511 if ((flags & PsiValue) == 0)
3512 geometry_info.psi=0.05;
3513 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3514 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
3517 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3521 if (LocaleCompare("verbose",option+1) == 0)
3523 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
3524 three places! ImageArtifact ImageOption _image_info->verbose
3525 Some how new images also get this artifact!
3527 (void) SetImageArtifact(_image,option+1,
3528 IfNormalOp ? "true" : "false" );
3531 if (LocaleCompare("vignette",option+1) == 0)
3533 flags=ParseGeometry(arg1,&geometry_info);
3534 if ((flags & (RhoValue|SigmaValue)) == 0)
3535 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3536 if ((flags & SigmaValue) == 0)
3537 geometry_info.sigma=1.0;
3538 if ((flags & XiValue) == 0)
3539 geometry_info.xi=0.1*_image->columns;
3540 if ((flags & PsiValue) == 0)
3541 geometry_info.psi=0.1*_image->rows;
3542 if ((flags & PercentValue) != 0)
3544 geometry_info.xi*=(double) _image->columns/100.0;
3545 geometry_info.psi*=(double) _image->rows/100.0;
3547 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
3548 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3549 ceil(geometry_info.psi-0.5),_exception);
3552 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3556 if (LocaleCompare("wave",option+1) == 0)
3558 flags=ParseGeometry(arg1,&geometry_info);
3559 if ((flags & (RhoValue|SigmaValue)) == 0)
3560 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3561 if ((flags & SigmaValue) == 0)
3562 geometry_info.sigma=1.0;
3563 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3564 _image->interpolate,_exception);
3567 if (LocaleCompare("wavelet-denoise",option+1) == 0)
3569 flags=ParseGeometry(arg1,&geometry_info);
3570 if ((flags & RhoValue) == 0)
3571 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3572 if ((flags & PercentValue) != 0)
3574 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
3575 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
3577 if ((flags & SigmaValue) == 0)
3578 geometry_info.sigma=0.0;
3579 new_image=WaveletDenoiseImage(_image,geometry_info.rho,
3580 geometry_info.sigma,_exception);
3583 if (LocaleCompare("white-threshold",option+1) == 0)
3585 if (IsGeometry(arg1) == MagickFalse)
3586 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3587 (void) WhiteThresholdImage(_image,arg1,_exception);
3590 if (LocaleCompare("write-mask",option+1) == 0)
3592 /* Note: arguments do not have percent escapes expanded */
3597 { /* Remove a mask. */
3598 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,
3602 /* Set the image mask. */
3603 mask=GetImageCache(_image_info,arg1,_exception);
3604 if (mask == (Image *) NULL)
3606 (void) SetImageMask(_image,WritePixelMask,mask,_exception);
3607 mask=DestroyImage(mask);
3610 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3613 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3615 /* clean up percent escape interpreted strings */
3617 arg1=DestroyString((char *)arg1);
3619 arg2=DestroyString((char *)arg2);
3621 /* Replace current image with any image that was generated
3622 and set image point to last image (so image->next is correct) */
3623 if (new_image != (Image *) NULL)
3624 ReplaceImageInListReturnLast(&_image,new_image);
3629 #undef _quantize_info
3638 WandPrivate MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,
3639 const char *option,const char *arg1,const char *arg2,ExceptionInfo *exception)
3641 #if !USE_WAND_METHODS
3647 assert(cli_wand != (MagickCLI *) NULL);
3648 assert(cli_wand->signature == MagickWandSignature);
3649 assert(cli_wand->wand.signature == MagickWandSignature);
3650 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
3652 if (cli_wand->wand.debug != MagickFalse)
3653 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
3654 "- Simple Operator: %s \"%s\" \"%s\"", option,arg1,arg2);
3656 #if !USE_WAND_METHODS
3657 /* FUTURE add appropriate tracing */
3659 n=GetImageListLength(cli_wand->wand.images);
3660 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
3663 CLISimpleOperatorImage(cli_wand, option, arg1, arg2,exception);
3664 if ( cli_wand->wand.images->next == (Image *) NULL )
3666 cli_wand->wand.images=cli_wand->wand.images->next;
3669 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
3671 MagickResetIterator(&cli_wand->wand);
3672 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
3673 (void) CLISimpleOperatorImage(cli_wand, option, arg1, arg2,exception);
3674 MagickResetIterator(&cli_wand->wand);
3680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3684 + C L I L i s t O p e r a t o r I m a g e s %
3688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3690 % CLIListOperatorImages() applies a single operation that is apply to the
3691 % entire image list as a whole. The result is often a complete replacment
3692 % of the image list with a completely new list, or with just a single image
3695 % The format of the MogrifyImage method is:
3697 % MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
3698 % const char *option,const char *arg1,const char *arg2)
3700 % A description of each parameter follows:
3702 % o cli_wand: structure holding settings to be applied
3704 % o option: The option string for the operation
3706 % o arg1, arg2: optional argument strings to the operation
3707 % arg2 is currently not used
3710 WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
3711 const char *option,const char *arg1n,const char *arg2n)
3713 const char /* percent escaped versions of the args */
3726 #define _image_info (cli_wand->wand.image_info)
3727 #define _images (cli_wand->wand.images)
3728 #define _exception (cli_wand->wand.exception)
3729 #define _draw_info (cli_wand->draw_info)
3730 #define _quantize_info (cli_wand->quantize_info)
3731 #define _process_flags (cli_wand->process_flags)
3732 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
3733 #define IfNormalOp (*option=='-')
3734 #define IfPlusOp (*option!='-')
3735 #define IsNormalOp IfNormalOp ? MagickTrue : MagickFalse
3737 assert(cli_wand != (MagickCLI *) NULL);
3738 assert(cli_wand->signature == MagickWandSignature);
3739 assert(cli_wand->wand.signature == MagickWandSignature);
3740 assert(_images != (Image *) NULL); /* _images must be present */
3742 if (cli_wand->wand.debug != MagickFalse)
3743 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
3744 "- List Operator: %s \"%s\" \"%s\"", option,
3745 arg1n == (const char *) NULL ? "null" : arg1n,
3746 arg2n == (const char *) NULL ? "null" : arg2n);
3751 /* Interpret Percent Escapes in Arguments - using first image */
3752 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
3753 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
3754 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
3755 /* Interpret Percent escapes in argument 1 */
3756 if (arg1n != (char *) NULL) {
3757 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
3758 if (arg1 == (char *) NULL) {
3759 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3760 arg1=arg1n; /* use the given argument as is */
3763 if (arg2n != (char *) NULL) {
3764 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
3765 if (arg2 == (char *) NULL) {
3766 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3767 arg2=arg2n; /* use the given argument as is */
3771 #undef _process_flags
3775 new_images=NewImageList();
3777 switch (*(option+1))
3781 if (LocaleCompare("append",option+1) == 0)
3783 new_images=AppendImages(_images,IsNormalOp,_exception);
3786 if (LocaleCompare("average",option+1) == 0)
3788 CLIWandWarnReplaced("-evaluate-sequence Mean");
3789 (void) CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",
3793 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3797 if (LocaleCompare("channel-fx",option+1) == 0)
3799 new_images=ChannelFxImage(_images,arg1,_exception);
3802 if (LocaleCompare("clut",option+1) == 0)
3807 /* FUTURE - make this a compose option, and thus can be used
3808 with layers compose or even compose last image over all other
3811 new_images=RemoveFirstImageFromList(&_images);
3812 clut_image=RemoveLastImageFromList(&_images);
3813 /* FUTURE - produce Exception, rather than silent fail */
3814 if (clut_image == (Image *) NULL)
3816 (void) ClutImage(new_images,clut_image,new_images->interpolate,
3818 clut_image=DestroyImage(clut_image);
3821 if (LocaleCompare("coalesce",option+1) == 0)
3823 new_images=CoalesceImages(_images,_exception);
3826 if (LocaleCompare("combine",option+1) == 0)
3828 parse=(ssize_t) _images->colorspace;
3829 if (_images->number_channels < GetImageListLength(_images))
3830 parse=sRGBColorspace;
3832 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
3834 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
3836 new_images=CombineImages(_images,(ColorspaceType) parse,_exception);
3839 if (LocaleCompare("compare",option+1) == 0)
3852 Mathematically and visually annotate the difference between an
3853 image and its reconstruction.
3855 image=RemoveFirstImageFromList(&_images);
3856 reconstruct_image=RemoveFirstImageFromList(&_images);
3857 /* FUTURE - produce Exception, rather than silent fail */
3858 if (reconstruct_image == (Image *) NULL)
3860 metric=UndefinedErrorMetric;
3861 option=GetImageOption(_image_info,"metric");
3862 if (option != (const char *) NULL)
3863 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
3864 MagickFalse,option);
3865 new_images=CompareImages(image,reconstruct_image,metric,&distortion,
3868 reconstruct_image=DestroyImage(reconstruct_image);
3869 image=DestroyImage(image);
3872 if (LocaleCompare("complex",option+1) == 0)
3874 parse=ParseCommandOption(MagickComplexOptions,MagickFalse,arg1);
3876 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3878 new_images=ComplexImages(_images,(ComplexOperator) parse,_exception);
3881 if (LocaleCompare("composite",option+1) == 0)
3899 /* Compose value from "-compose" option only */
3900 value=GetImageOption(_image_info,"compose");
3901 if (value == (const char *) NULL)
3902 compose=OverCompositeOp; /* use Over not source_image->compose */
3904 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
3907 /* Get "clip-to-self" expert setting (false is normal) */
3908 clip_to_self=GetCompositeClipToSelf(compose);
3909 value=GetImageOption(_image_info,"compose:clip-to-self");
3910 if (value != (const char *) NULL)
3911 clip_to_self=IsStringTrue(value);
3912 value=GetImageOption(_image_info,"compose:outside-overlay");
3913 if (value != (const char *) NULL)
3914 clip_to_self=IsStringFalse(value); /* deprecated */
3916 new_images=RemoveFirstImageFromList(&_images);
3917 source_image=RemoveFirstImageFromList(&_images);
3918 if (source_image == (Image *) NULL)
3919 break; /* FUTURE - produce Exception, rather than silent fail */
3921 /* FUTURE - this should not be here! - should be part of -geometry */
3922 if (source_image->geometry != (char *) NULL)
3927 (void) ParseRegionGeometry(source_image,source_image->geometry,
3928 &resize_geometry,_exception);
3929 if ((source_image->columns != resize_geometry.width) ||
3930 (source_image->rows != resize_geometry.height))
3935 resize_image=ResizeImage(source_image,resize_geometry.width,
3936 resize_geometry.height,source_image->filter,_exception);
3937 if (resize_image != (Image *) NULL)
3939 source_image=DestroyImage(source_image);
3940 source_image=resize_image;
3944 SetGeometry(source_image,&geometry);
3945 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3946 GravityAdjustGeometry(new_images->columns,new_images->rows,
3947 new_images->gravity, &geometry);
3948 mask_image=RemoveFirstImageFromList(&_images);
3949 if (mask_image == (Image *) NULL)
3950 status&=CompositeImage(new_images,source_image,compose,clip_to_self,
3951 geometry.x,geometry.y,_exception);
3954 if ((compose == DisplaceCompositeOp) ||
3955 (compose == DistortCompositeOp))
3957 status&=CompositeImage(source_image,mask_image,
3958 CopyGreenCompositeOp,MagickTrue,0,0,_exception);
3959 status&=CompositeImage(new_images,source_image,compose,
3960 clip_to_self,geometry.x,geometry.y,_exception);
3967 clone_image=CloneImage(new_images,0,0,MagickTrue,_exception);
3968 if (clone_image == (Image *) NULL)
3970 status&=CompositeImage(new_images,source_image,compose,
3971 clip_to_self,geometry.x,geometry.y,_exception);
3972 status&=CompositeImage(new_images,mask_image,
3973 CopyAlphaCompositeOp,MagickTrue,0,0,_exception);
3974 status&=CompositeImage(clone_image,new_images,OverCompositeOp,
3975 clip_to_self,0,0,_exception);
3976 new_images=DestroyImage(new_images);
3977 new_images=clone_image;
3979 mask_image=DestroyImage(mask_image);
3981 source_image=DestroyImage(source_image);
3984 if (LocaleCompare("copy",option+1) == 0)
3998 if (IsGeometry(arg1) == MagickFalse)
3999 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4000 if (IsGeometry(arg2) == MagickFalse)
4001 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4002 (void) ParsePageGeometry(_images,arg2,&geometry,_exception);
4003 offset.x=geometry.x;
4004 offset.y=geometry.y;
4005 source_image=_images;
4006 if (source_image->next != (Image *) NULL)
4007 source_image=source_image->next;
4008 (void) ParsePageGeometry(source_image,arg1,&geometry,_exception);
4009 (void) CopyImagePixels(_images,source_image,&geometry,&offset,
4013 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4017 if (LocaleCompare("deconstruct",option+1) == 0)
4019 CLIWandWarnReplaced("-layer CompareAny");
4020 (void) CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
4023 if (LocaleCompare("delete",option+1) == 0)
4026 DeleteImages(&_images,arg1,_exception);
4028 DeleteImages(&_images,"-1",_exception);
4031 if (LocaleCompare("duplicate",option+1) == 0)
4041 if (IsGeometry(arg1) == MagickFalse)
4042 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
4044 number_duplicates=(size_t) StringToLong(arg1);
4046 if (p == (const char *) NULL)
4047 new_images=DuplicateImages(_images,number_duplicates,"-1",
4050 new_images=DuplicateImages(_images,number_duplicates,p,
4054 new_images=DuplicateImages(_images,1,"-1",_exception);
4055 AppendImageToList(&_images, new_images);
4056 new_images=(Image *) NULL;
4059 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4063 if (LocaleCompare("evaluate-sequence",option+1) == 0)
4065 parse=ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
4067 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
4069 new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
4073 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4077 if (LocaleCompare("fft",option+1) == 0)
4079 new_images=ForwardFourierTransformImage(_images,IsNormalOp,
4083 if (LocaleCompare("flatten",option+1) == 0)
4085 /* REDIRECTED to use -layers flatten instead */
4086 (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
4089 if (LocaleCompare("fx",option+1) == 0)
4091 new_images=FxImage(_images,arg1,_exception);
4094 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4098 if (LocaleCompare("hald-clut",option+1) == 0)
4100 /* FUTURE - make this a compose option (and thus layers compose )
4101 or perhaps compose last image over all other _images.
4106 new_images=RemoveFirstImageFromList(&_images);
4107 hald_image=RemoveLastImageFromList(&_images);
4108 if (hald_image == (Image *) NULL)
4110 (void) HaldClutImage(new_images,hald_image,_exception);
4111 hald_image=DestroyImage(hald_image);
4114 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4118 if (LocaleCompare("ift",option+1) == 0)
4124 magnitude_image=RemoveFirstImageFromList(&_images);
4125 phase_image=RemoveFirstImageFromList(&_images);
4126 /* FUTURE - produce Exception, rather than silent fail */
4127 if (phase_image == (Image *) NULL)
4129 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
4130 IsNormalOp,_exception);
4131 magnitude_image=DestroyImage(magnitude_image);
4132 phase_image=DestroyImage(phase_image);
4135 if (LocaleCompare("insert",option+1) == 0)
4144 if (IfNormalOp && (IsGeometry(arg1) == MagickFalse))
4145 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4147 insert_image=RemoveLastImageFromList(&_images);
4149 index=(ssize_t) StringToLong(arg1);
4150 index_image=insert_image;
4152 PrependImageToList(&_images,insert_image);
4153 else if (index == (ssize_t) GetImageListLength(_images))
4154 AppendImageToList(&_images,insert_image);
4157 index_image=GetImageFromList(_images,index-1);
4158 if (index_image == (Image *) NULL)
4159 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
4160 InsertImageInList(&index_image,insert_image);
4162 _images=GetFirstImageInList(index_image);
4165 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4169 if (LocaleCompare("layers",option+1) == 0)
4171 parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
4173 CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
4175 switch ((LayerMethod) parse)
4179 new_images=CoalesceImages(_images,_exception);
4182 case CompareAnyLayer:
4183 case CompareClearLayer:
4184 case CompareOverlayLayer:
4187 new_images=CompareImagesLayers(_images,(LayerMethod) parse,
4194 case TrimBoundsLayer:
4196 new_images=MergeImageLayers(_images,(LayerMethod) parse,
4202 new_images=DisposeImages(_images,_exception);
4205 case OptimizeImageLayer:
4207 new_images=OptimizeImageLayers(_images,_exception);
4210 case OptimizePlusLayer:
4212 new_images=OptimizePlusImageLayers(_images,_exception);
4215 case OptimizeTransLayer:
4217 OptimizeImageTransparency(_images,_exception);
4220 case RemoveDupsLayer:
4222 RemoveDuplicateLayers(&_images,_exception);
4225 case RemoveZeroLayer:
4227 RemoveZeroDelayLayers(&_images,_exception);
4231 { /* General Purpose, GIF Animation Optimizer. */
4232 new_images=CoalesceImages(_images,_exception);
4233 if (new_images == (Image *) NULL)
4235 _images=DestroyImageList(_images);
4236 _images=OptimizeImageLayers(new_images,_exception);
4237 if (_images == (Image *) NULL)
4239 new_images=DestroyImageList(new_images);
4240 OptimizeImageTransparency(_images,_exception);
4241 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
4245 case CompositeLayer:
4259 value=GetImageOption(_image_info,"compose");
4260 compose=OverCompositeOp; /* Default to Over */
4261 if (value != (const char *) NULL)
4262 compose=(CompositeOperator) ParseCommandOption(
4263 MagickComposeOptions,MagickFalse,value);
4265 /* Split image sequence at the first 'NULL:' image. */
4267 while (source != (Image *) NULL)
4269 source=GetNextImageInList(source);
4270 if ((source != (Image *) NULL) &&
4271 (LocaleCompare(source->magick,"NULL") == 0))
4274 if (source != (Image *) NULL)
4276 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4277 (GetNextImageInList(source) == (Image *) NULL))
4278 source=(Image *) NULL;
4280 { /* Separate the two lists, junk the null: image. */
4281 source=SplitImageList(source->previous);
4282 DeleteImageFromList(&source);
4285 if (source == (Image *) NULL)
4287 (void) ThrowMagickException(_exception,GetMagickModule(),
4288 OptionError,"MissingNullSeparator","layers Composite");
4291 /* Adjust offset with gravity and virtual canvas. */
4292 SetGeometry(_images,&geometry);
4293 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
4294 geometry.width=source->page.width != 0 ?
4295 source->page.width : source->columns;
4296 geometry.height=source->page.height != 0 ?
4297 source->page.height : source->rows;
4298 GravityAdjustGeometry(_images->page.width != 0 ?
4299 _images->page.width : _images->columns,
4300 _images->page.height != 0 ? _images->page.height :
4301 _images->rows,_images->gravity,&geometry);
4303 /* Compose the two image sequences together */
4304 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
4306 source=DestroyImageList(source);
4312 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4316 if (LocaleCompare("map",option+1) == 0)
4318 CLIWandWarnReplaced("+remap");
4319 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
4322 if (LocaleCompare("metric",option+1) == 0)
4324 (void) SetImageOption(_image_info,option+1,arg1);
4327 if (LocaleCompare("morph",option+1) == 0)
4332 if (IsGeometry(arg1) == MagickFalse)
4333 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4334 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4336 if (morph_image == (Image *) NULL)
4338 _images=DestroyImageList(_images);
4339 _images=morph_image;
4342 if (LocaleCompare("mosaic",option+1) == 0)
4344 /* REDIRECTED to use -layers mosaic instead */
4345 (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
4348 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4352 if (LocaleCompare("poly",option+1) == 0)
4360 /* convert argument string into an array of doubles */
4361 args = StringToArrayOfDoubles(arg1,&count,_exception);
4362 if (args == (double *) NULL )
4363 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg1);
4364 new_images=PolynomialImage(_images,(size_t) (count >> 1),args,
4366 args=(double *) RelinquishMagickMemory(args);
4369 if (LocaleCompare("process",option+1) == 0)
4371 /* FUTURE: better parsing using ScriptToken() from string ??? */
4379 arguments=StringToArgv(arg1,&number_arguments);
4380 if (arguments == (char **) NULL)
4382 if (strchr(arguments[1],'=') != (char *) NULL)
4403 Support old style syntax, filter="-option arg1".
4405 assert(arg1 != (const char *) NULL);
4406 length=strlen(arg1);
4407 token=(char *) NULL;
4408 if (~length >= (MagickPathExtent-1))
4409 token=(char *) AcquireQuantumMemory(length+MagickPathExtent,
4411 if (token == (char *) NULL)
4415 token_info=AcquireTokenInfo();
4416 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4417 "\"",'\0',&breaker,&next,"e);
4418 token_info=DestroyTokenInfo(token_info);
4424 argv=(&(arguments[next]));
4425 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4428 token=DestroyString(token);
4431 (void) SubstituteString(&arguments[1],"-","");
4432 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4433 number_arguments-2,(const char **) arguments+2,_exception);
4434 for (j=0; j < number_arguments; j++)
4435 arguments[j]=DestroyString(arguments[j]);
4436 arguments=(char **) RelinquishMagickMemory(arguments);
4439 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4443 if (LocaleCompare("remap",option+1) == 0)
4445 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
4448 if (LocaleCompare("reverse",option+1) == 0)
4450 ReverseImageList(&_images);
4453 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4457 if (LocaleCompare("smush",option+1) == 0)
4459 /* FUTURE: this option needs more work to make better */
4463 if (IsGeometry(arg1) == MagickFalse)
4464 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4465 offset=(ssize_t) StringToLong(arg1);
4466 new_images=SmushImages(_images,IsNormalOp,offset,_exception);
4469 if (LocaleCompare("subimage",option+1) == 0)
4487 base_image=GetImageFromList(_images,0);
4488 compare_image=GetImageFromList(_images,1);
4490 /* Comparision Metric */
4491 metric=UndefinedErrorMetric;
4492 value=GetImageOption(_image_info,"metric");
4493 if (value != (const char *) NULL)
4494 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
4497 new_images=SimilarityImage(base_image,compare_image,metric,0.0,
4498 &offset,&similarity,_exception);
4500 if (new_images != (Image *) NULL)
4503 result[MagickPathExtent];
4505 (void) FormatLocaleString(result,MagickPathExtent,"%lf",
4507 (void) SetImageProperty(new_images,"subimage:similarity",result,
4509 (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
4511 (void) SetImageProperty(new_images,"subimage:x",result,
4513 (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
4515 (void) SetImageProperty(new_images,"subimage:y",result,
4517 (void) FormatLocaleString(result,MagickPathExtent,
4518 "%lux%lu%+ld%+ld",(unsigned long) offset.width,(unsigned long)
4519 offset.height,(long) offset.x,(long) offset.y);
4520 (void) SetImageProperty(new_images,"subimage:offset",result,
4525 if (LocaleCompare("swap",option+1) == 0)
4546 flags=ParseGeometry(arg1,&geometry_info);
4547 if ((flags & RhoValue) == 0)
4548 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4549 index=(ssize_t) geometry_info.rho;
4550 if ((flags & SigmaValue) != 0)
4551 swap_index=(ssize_t) geometry_info.sigma;
4553 p=GetImageFromList(_images,index);
4554 q=GetImageFromList(_images,swap_index);
4555 if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
4557 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
4559 CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
4562 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
4563 swap=CloneImage(p,0,0,MagickTrue,_exception);
4564 if (swap == (Image *) NULL)
4565 CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
4566 option,GetExceptionMessage(errno));
4567 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
4568 ReplaceImageInList(&q,swap);
4569 _images=GetFirstImageInList(q);
4572 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4575 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4578 /* clean up percent escape interpreted strings */
4580 arg1=DestroyString((char *)arg1);
4582 arg2=DestroyString((char *)arg2);
4584 /* if new image list generated, replace existing image list */
4585 if (new_images == (Image *) NULL)
4586 return(status == 0 ? MagickFalse : MagickTrue);
4587 _images=DestroyImageList(_images);
4588 _images=GetFirstImageInList(new_images);
4589 return(status == 0 ? MagickFalse : MagickTrue);
4595 #undef _quantize_info
4602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4606 + C L I N o I m a g e O p e r a t i o n s %
4610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4612 % CLINoImageOperator() Applies operations that may not actually need images
4615 % The classic operators of this type is "-read", which actually creates
4616 % images even when no images are present. Or image stack operators, which
4617 % can be applied (push or pop) to an empty image list.
4619 % Note that these operators may involve other special 'option' prefix
4620 % characters other than '-' or '+', namely parenthesis and braces.
4622 % The format of the CLINoImageOption method is:
4624 % void CLINoImageOption(MagickCLI *cli_wand,const char *option,
4625 % const char *arg1, const char *arg2)
4627 % A description of each parameter follows:
4629 % o cli_wand: the main CLI Wand to use. (sometimes not required)
4631 % o option: The special option (with any switch char) to process
4633 % o arg1 & arg2: Argument for option, if required
4634 % Currently arg2 is not used.
4637 WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
4638 const char *option,const char *arg1n,const char *arg2n)
4640 const char /* percent escaped versions of the args */
4644 #define _image_info (cli_wand->wand.image_info)
4645 #define _images (cli_wand->wand.images)
4646 #define _exception (cli_wand->wand.exception)
4647 #define _process_flags (cli_wand->process_flags)
4648 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
4649 #define IfNormalOp (*option=='-')
4650 #define IfPlusOp (*option!='-')
4652 assert(cli_wand != (MagickCLI *) NULL);
4653 assert(cli_wand->signature == MagickWandSignature);
4654 assert(cli_wand->wand.signature == MagickWandSignature);
4656 if (cli_wand->wand.debug != MagickFalse)
4657 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
4658 "- NoImage Operator: %s \"%s\" \"%s\"", option,
4659 arg1n != (char *) NULL ? arg1n : "",
4660 arg2n != (char *) NULL ? arg2n : "");
4665 /* Interpret Percent Escapes in Arguments - using first image */
4666 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
4667 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
4668 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
4669 /* Interpret Percent escapes in argument 1 */
4670 if (arg1n != (char *) NULL) {
4671 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
4672 if (arg1 == (char *) NULL) {
4673 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4674 arg1=arg1n; /* use the given argument as is */
4677 if (arg2n != (char *) NULL) {
4678 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4679 if (arg2 == (char *) NULL) {
4680 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4681 arg2=arg2n; /* use the given argument as is */
4685 #undef _process_flags
4688 do { /* break to exit code */
4690 No-op options (ignore these)
4692 if (LocaleCompare("noop",option+1) == 0) /* zero argument */
4694 if (LocaleCompare("sans",option+1) == 0) /* one argument */
4696 if (LocaleCompare("sans0",option+1) == 0) /* zero argument */
4698 if (LocaleCompare("sans1",option+1) == 0) /* one argument */
4700 if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
4705 if ( ( LocaleCompare("read",option+1) == 0 ) ||
4706 ( LocaleCompare("--",option) == 0 ) ) {
4707 /* Do Glob filename Expansion for 'arg1' then read all images.
4709 * Expansion handles '@', '~', '*', and '?' meta-characters while ignoring
4710 * (but attaching to the filenames in the generated argument list) any
4711 * [...] read modifiers that may be present.
4713 * For example: It will expand '*.gif[20x20]' into a list such as
4714 * 'abc.gif[20x20]', 'foobar.gif[20x20]', 'xyzzy.gif[20x20]'
4716 * NOTE: In IMv6 this was done globally across all images. This
4717 * meant you could include IM options in '@filename' lists, but you
4718 * could not include comments. Doing it only for image read makes
4719 * it far more secure.
4721 * Note: arguments do not have percent escapes expanded for security
4729 argv = (char **) &arg1;
4731 /* Expand 'glob' expressions in the given filename.
4732 Expansion handles any 'coder:' prefix, or read modifiers attached
4733 to the filename, including them in the resulting expanded list.
4735 if (ExpandFilenames(&argc,&argv) == MagickFalse)
4736 CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
4737 option,GetExceptionMessage(errno));
4739 /* loop over expanded filename list, and read then all in */
4740 for (i=0; i < (ssize_t) argc; i++) {
4743 if (_image_info->ping != MagickFalse)
4744 new_images=PingImages(_image_info,argv[i],_exception);
4746 new_images=ReadImages(_image_info,argv[i],_exception);
4747 AppendImageToList(&_images, new_images);
4748 argv[i]=DestroyString(argv[i]);
4750 argv=(char **) RelinquishMagickMemory(argv);
4755 Note: Writing a empty image list is valid in specific cases
4757 if (LocaleCompare("write",option+1) == 0) {
4758 /* Note: arguments do not have percent escapes expanded */
4760 key[MagickPathExtent];
4768 /* Need images, unless a "null:" output coder is used */
4769 if ( _images == (Image *) NULL ) {
4770 if ( LocaleCompare(arg1,"null:") == 0 )
4772 CLIWandExceptArgBreak(OptionError,"NoImagesForWrite",option,arg1);
4775 (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",arg1);
4776 (void) DeleteImageRegistry(key);
4777 write_images=_images;
4779 write_images=CloneImageList(_images,_exception);
4780 write_info=CloneImageInfo(_image_info);
4781 (void) WriteImages(write_info,write_images,arg1,_exception);
4782 write_info=DestroyImageInfo(write_info);
4784 write_images=DestroyImageList(write_images);
4788 Parenthesis and Brace operations
4790 if (LocaleCompare("(",option) == 0) {
4791 /* stack 'push' images */
4799 node=cli_wand->image_list_stack;
4800 for ( ; node != (Stack *) NULL; node=node->next)
4802 if ( size >= MAX_STACK_DEPTH )
4803 CLIWandExceptionBreak(OptionError,"ParenthesisNestedTooDeeply",option);
4804 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4805 if (node == (Stack *) NULL)
4806 CLIWandExceptionBreak(ResourceLimitFatalError,
4807 "MemoryAllocationFailed",option);
4808 node->data = (void *)cli_wand->wand.images;
4809 node->next = cli_wand->image_list_stack;
4810 cli_wand->image_list_stack = node;
4811 cli_wand->wand.images = NewImageList();
4813 /* handle respect-parenthesis */
4814 if (IsStringTrue(GetImageOption(cli_wand->wand.image_info,
4815 "respect-parenthesis")) != MagickFalse)
4816 option="{"; /* fall-thru so as to push image settings too */
4819 /* fall thru to operation */
4821 if (LocaleCompare("{",option) == 0) {
4822 /* stack 'push' of image_info settings */
4830 node=cli_wand->image_info_stack;
4831 for ( ; node != (Stack *) NULL; node=node->next)
4833 if ( size >= MAX_STACK_DEPTH )
4834 CLIWandExceptionBreak(OptionError,"CurlyBracesNestedTooDeeply",option);
4835 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4836 if (node == (Stack *) NULL)
4837 CLIWandExceptionBreak(ResourceLimitFatalError,
4838 "MemoryAllocationFailed",option);
4840 node->data = (void *)cli_wand->wand.image_info;
4841 node->next = cli_wand->image_info_stack;
4843 cli_wand->image_info_stack = node;
4844 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
4845 if (cli_wand->wand.image_info == (ImageInfo *) NULL) {
4846 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4848 cli_wand->wand.image_info = (ImageInfo *)node->data;
4849 node = (Stack *)RelinquishMagickMemory(node);
4855 if (LocaleCompare(")",option) == 0) {
4856 /* pop images from stack */
4860 node = (Stack *)cli_wand->image_list_stack;
4861 if ( node == (Stack *) NULL)
4862 CLIWandExceptionBreak(OptionError,"UnbalancedParenthesis",option);
4863 cli_wand->image_list_stack = node->next;
4865 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4866 cli_wand->wand.images= (Image *)node->data;
4867 node = (Stack *)RelinquishMagickMemory(node);
4869 /* handle respect-parenthesis - of the previous 'pushed' settings */
4870 node = cli_wand->image_info_stack;
4871 if ( node != (Stack *) NULL)
4873 if (IsStringTrue(GetImageOption(
4874 cli_wand->wand.image_info,"respect-parenthesis")) != MagickFalse)
4875 option="}"; /* fall-thru so as to pop image settings too */
4881 /* fall thru to next if */
4883 if (LocaleCompare("}",option) == 0) {
4884 /* pop image_info settings from stack */
4888 node = (Stack *)cli_wand->image_info_stack;
4889 if ( node == (Stack *) NULL)
4890 CLIWandExceptionBreak(OptionError,"UnbalancedCurlyBraces",option);
4891 cli_wand->image_info_stack = node->next;
4893 (void) DestroyImageInfo(cli_wand->wand.image_info);
4894 cli_wand->wand.image_info = (ImageInfo *)node->data;
4895 node = (Stack *)RelinquishMagickMemory(node);
4897 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4898 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4899 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4903 if (LocaleCompare("print",option+1) == 0)
4905 (void) FormatLocaleFile(stdout,"%s",arg1);
4908 if (LocaleCompare("set",option+1) == 0)
4910 /* Settings are applied to each image in memory in turn (if any).
4911 While a option: only need to be applied once globally.
4913 NOTE: rguments have not been automatically percent expaneded
4916 /* escape the 'key' once only, using first image. */
4917 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
4918 if (arg1 == (char *) NULL)
4919 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
4922 if (LocaleNCompare(arg1,"registry:",9) == 0)
4926 (void) DeleteImageRegistry(arg1+9);
4927 arg1=DestroyString((char *)arg1);
4930 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4931 if (arg2 == (char *) NULL) {
4932 arg1=DestroyString((char *)arg1);
4933 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
4936 (void) SetImageRegistry(StringRegistryType,arg1+9,arg2,_exception);
4937 arg1=DestroyString((char *)arg1);
4938 arg2=DestroyString((char *)arg2);
4941 if (LocaleNCompare(arg1,"option:",7) == 0)
4943 /* delete equivelent artifact from all images (if any) */
4944 if (_images != (Image *) NULL)
4946 MagickResetIterator(&cli_wand->wand);
4947 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
4948 (void) DeleteImageArtifact(_images,arg1+7);
4949 MagickResetIterator(&cli_wand->wand);
4951 /* now set/delete the global option as needed */
4952 /* FUTURE: make escapes in a global 'option:' delayed */
4956 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4957 if (arg2 == (char *) NULL)
4958 CLIWandExceptionBreak(OptionWarning,
4959 "InterpretPropertyFailure",option);
4961 (void) SetImageOption(_image_info,arg1+7,arg2);
4962 arg1=DestroyString((char *)arg1);
4963 arg2=DestroyString((char *)arg2);
4966 /* Set Artifacts/Properties/Attributes all images (required) */
4967 if ( _images == (Image *) NULL )
4968 CLIWandExceptArgBreak(OptionWarning,"NoImageForProperty",option,arg1);
4970 MagickResetIterator(&cli_wand->wand);
4971 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
4976 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4977 if (arg2 == (char *) NULL)
4978 CLIWandExceptionBreak(OptionWarning,
4979 "InterpretPropertyFailure",option);
4981 if (LocaleNCompare(arg1,"artifact:",9) == 0)
4982 (void) SetImageArtifact(_images,arg1+9,arg2);
4983 else if (LocaleNCompare(arg1,"property:",9) == 0)
4984 (void) SetImageProperty(_images,arg1+9,arg2,_exception);
4986 (void) SetImageProperty(_images,arg1,arg2,_exception);
4987 arg2=DestroyString((char *)arg2);
4989 MagickResetIterator(&cli_wand->wand);
4990 arg1=DestroyString((char *)arg1);
4993 if (LocaleCompare("clone",option+1) == 0) {
4998 arg1=AcquireString("-1");
4999 if (IsSceneGeometry(arg1,MagickFalse) == MagickFalse)
5000 CLIWandExceptionBreak(OptionError,"InvalidArgument",option);
5001 if ( cli_wand->image_list_stack == (Stack *) NULL)
5002 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
5003 new_images = (Image *)cli_wand->image_list_stack->data;
5004 if (new_images == (Image *) NULL)
5005 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
5006 new_images=CloneImages(new_images,arg1,_exception);
5007 if (new_images == (Image *) NULL)
5008 CLIWandExceptionBreak(OptionError,"NoSuchImage",option);
5009 AppendImageToList(&_images,new_images);
5013 Informational Operations.
5015 Note that these do not require either a cli-wand or images!
5016 Though currently a cli-wand much be provided regardless.
5018 if (LocaleCompare("version",option+1) == 0)
5020 ListMagickVersion(stdout);
5023 if (LocaleCompare("list",option+1) == 0) {
5025 FUTURE: This 'switch' should really be part of MagickCore
5030 list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
5032 CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
5037 case MagickCoderOptions:
5039 (void) ListCoderInfo((FILE *) NULL,_exception);
5042 case MagickColorOptions:
5044 (void) ListColorInfo((FILE *) NULL,_exception);
5047 case MagickConfigureOptions:
5049 (void) ListConfigureInfo((FILE *) NULL,_exception);
5052 case MagickDelegateOptions:
5054 (void) ListDelegateInfo((FILE *) NULL,_exception);
5057 case MagickFontOptions:
5059 (void) ListTypeInfo((FILE *) NULL,_exception);
5062 case MagickFormatOptions:
5063 (void) ListMagickInfo((FILE *) NULL,_exception);
5065 case MagickLocaleOptions:
5066 (void) ListLocaleInfo((FILE *) NULL,_exception);
5068 case MagickLogOptions:
5069 (void) ListLogInfo((FILE *) NULL,_exception);
5071 case MagickMagicOptions:
5072 (void) ListMagicInfo((FILE *) NULL,_exception);
5074 case MagickMimeOptions:
5075 (void) ListMimeInfo((FILE *) NULL,_exception);
5077 case MagickModuleOptions:
5078 (void) ListModuleInfo((FILE *) NULL,_exception);
5080 case MagickPolicyOptions:
5081 (void) ListPolicyInfo((FILE *) NULL,_exception);
5083 case MagickResourceOptions:
5084 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
5086 case MagickThresholdOptions:
5087 (void) ListThresholdMaps((FILE *) NULL,_exception);
5090 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
5097 CLIWandException(OptionError,"UnrecognizedOption",option);
5099 DisableMSCWarning(4127)
5100 } while (0); /* break to exit code. */
5103 /* clean up percent escape interpreted strings */
5105 arg1=DestroyString((char *)arg1);
5107 arg2=DestroyString((char *)arg2);
5117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5121 + C L I O p t i o n %
5125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5127 % CLIOption() Processes the given option using the given CLI Magick Wand.
5128 % The option arguments can be variable in number, though at this time no more
5129 % that two is actually used by any option (this may change). Excess options
5130 % are simply ignored.
5132 % If the cli_wand->command pointer is non-null, then it is assumed that the
5133 % option has already been search for up from the CommandOptions[] table in
5134 % "MagickCore/options.c" using GetCommandOptionInfo(). If not set this
5135 % routine will do the lookup instead. The pointer is reset afterward.
5137 % This action allows the caller to lookup and pre-handle any 'special'
5138 % options, (such as implicit reads) before calling this general option
5139 % handler to deal with 'standard' command line options.
5141 % The format of the CLIOption method is:
5143 % void CLIOption(MagickCLI *cli_wand,const char *option, ...)
5145 % A description of each parameter follows:
5147 % o cli_wand: the main CLI Wand to use.
5149 % o option: The special option (with any switch char) to process
5151 % o args: any required arguments for an option (variable number)
5155 % CLIoption(cli_wand,"-read","rose:");
5156 % CLIoption(cli_wand,"-virtual-pixel","transparent");
5157 % CLIoption(cli_wand,"-distort","SRT:","30");
5158 % CLIoption(cli_wand,"-write","rotated_rose.png");
5161 WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
5163 const char /* extracted option args from args */
5170 assert(cli_wand != (MagickCLI *) NULL);
5171 assert(cli_wand->signature == MagickWandSignature);
5172 assert(cli_wand->wand.signature == MagickWandSignature);
5174 do { /* Break Code Block for error handling */
5176 /* get information about option */
5177 if ( cli_wand->command == (const OptionInfo *) NULL )
5178 cli_wand->command = GetCommandOptionInfo(option);
5180 (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
5181 option, cli_wand->command->mnemonic );
5183 option_type=(CommandOptionFlags) cli_wand->command->flags;
5185 if ( option_type == UndefinedOptionFlag )
5186 CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
5188 assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
5190 /* deprecated options */
5191 if ( (option_type & DeprecateOptionFlag) != 0 )
5192 CLIWandExceptionBreak(OptionError,"DeprecatedOptionNoCode",option);
5194 /* options that this module does not handle */
5195 if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
5196 CLIWandExceptionBreak(OptionFatalError,"InvalidUseOfOption",option);
5198 /* Get argument strings from VarArgs
5199 How can you determine if enough arguments was supplied?
5200 What happens if not enough arguments were supplied?
5203 count = (size_t) cli_wand->command->type;
5208 va_start(operands,option);
5212 arg1=(const char *) va_arg(operands, const char *);
5214 arg2=(const char *) va_arg(operands, const char *);
5218 (void) FormatLocaleFile(stderr,
5219 "CLIOption: \"%s\" Count: %ld Flags: %04x Args: \"%s\" \"%s\"\n",
5220 option,(long) count,option_type,arg1,arg2);
5225 Call the appropriate option handler
5228 /* FUTURE: this is temporary - get 'settings' to handle distribution of
5229 settings to images attributes,proprieties,artifacts */
5230 if ( cli_wand->wand.images != (Image *) NULL )
5231 (void) SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
5232 cli_wand->wand.exception);
5234 if ( (option_type & SettingOptionFlags) != 0 ) {
5235 CLISettingOptionInfo(cli_wand, option, arg1, arg2);
5237 FUTURE: Sync Specific Settings into Image Properities (not global)
5241 /* Operators that do not need images - read, write, stack, clone */
5242 if ((option_type & NoImageOperatorFlag) != 0)
5243 CLINoImageOperator(cli_wand, option, arg1, arg2);
5245 /* FUTURE: The not a setting part below is a temporary hack due to
5246 * some options being both a Setting and a Simple operator.
5247 * Specifically -monitor, -depth, and -colorspace */
5248 if ( cli_wand->wand.images == (Image *) NULL )
5249 if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
5250 ((option_type & SettingOptionFlags) == 0 )) /* temp hack */
5251 CLIWandExceptionBreak(OptionError,"NoImagesFound",option);
5253 /* Operators which loop of individual images, simply */
5254 if ( (option_type & SimpleOperatorFlag) != 0 &&
5255 cli_wand->wand.images != (Image *) NULL) /* temp hack */
5257 ExceptionInfo *exception=AcquireExceptionInfo();
5258 (void) CLISimpleOperatorImages(cli_wand, option, arg1, arg2,exception);
5259 exception=DestroyExceptionInfo(exception);
5262 /* Operators that work on the image list as a whole */
5263 if ( (option_type & ListOperatorFlag) != 0 )
5264 (void) CLIListOperatorImages(cli_wand, option, arg1, arg2);
5266 DisableMSCWarning(4127)
5267 } while (0); /* end Break code block */
5270 cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */