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-2017 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 % http://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/image-private.h"
59 #include "MagickCore/monitor-private.h"
60 #include "MagickCore/pixel-private.h"
61 #include "MagickCore/string-private.h"
62 #include "MagickCore/thread-private.h"
68 MogrifyAlphaColor[] = "#bdbdbd", /* slightly darker gray */
69 MogrifyBackgroundColor[] = "#fff", /* white */
70 MogrifyBorderColor[] = "#dfdfdf"; /* sRGB gray */
75 #define USE_WAND_METHODS 1
76 #define MAX_STACK_DEPTH 32
77 #define UNDEFINED_COMPRESSION_QUALITY 0UL
79 /* FUTURE: why is this default so specific? */
80 #define DEFAULT_DISSIMILARITY_THRESHOLD "0.31830988618379067154"
82 /* For Debugging Geometry Input */
83 #define ReportGeometry(flags,info) \
84 (void) FormatLocaleFile(stderr, "Geometry = 0x%04X : %lg x %lg %+lg %+lg\n", \
85 flags, info.rho, info.sigma, info.xi, info.psi )
88 ** Function to report on the progress of image operations
90 static MagickBooleanType MonitorProgress(const char *text,
91 const MagickOffsetType offset,const MagickSizeType extent,
92 void *wand_unused(client_data))
95 message[MagickPathExtent],
96 tag[MagickPathExtent];
104 magick_unreferenced(client_data);
106 if ((extent <= 1) || (offset < 0) || (offset >= (MagickOffsetType) extent))
108 if ((offset != (MagickOffsetType) (extent-1)) && ((offset % 50) != 0))
110 (void) CopyMagickString(tag,text,MagickPathExtent);
112 if (p != (char *) NULL)
114 (void) FormatLocaleString(message,MagickPathExtent,"Monitor/%s",tag);
115 locale_message=GetLocaleMessage(message);
116 if (locale_message == message)
118 if (p == (char *) NULL)
119 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
120 locale_message,(long) offset,(unsigned long) extent,(long)
121 (100L*offset/(extent-1)));
123 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
124 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
125 (100L*offset/(extent-1)));
126 if (offset == (MagickOffsetType) (extent-1))
127 (void) FormatLocaleFile(stderr,"\n");
128 (void) fflush(stderr);
133 ** GetImageCache() will read an image into a image cache if not already
134 ** present then return the image that is in the cache under that filename.
136 static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
137 ExceptionInfo *exception)
140 key[MagickPathExtent];
151 (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",path);
152 sans_exception=AcquireExceptionInfo();
153 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
154 sans_exception=DestroyExceptionInfo(sans_exception);
155 if (image != (Image *) NULL)
157 read_info=CloneImageInfo(image_info);
158 if (path != (const char *) NULL)
159 (void) CopyMagickString(read_info->filename,path,MagickPathExtent);
160 image=ReadImage(read_info,exception);
161 read_info=DestroyImageInfo(read_info);
162 if (image != (Image *) NULL)
163 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
168 SparseColorOption() parse the complex -sparse-color argument into an
169 an array of floating point values than call SparseColorImage().
170 Argument is a complex mix of floating-point pixel coodinates, and color
171 specifications (or direct floating point numbers). The number of floats
172 needed to represent a color varies depending on the current channel
175 This really should be in MagickCore, so that other API's can make use of it.
177 static Image *SparseColorOption(const Image *image,
178 const SparseColorMethod method,const char *arguments,ExceptionInfo *exception)
181 token[MagickPathExtent];
205 assert(image != (Image *) NULL);
206 assert(image->signature == MagickCoreSignature);
207 if (image->debug != MagickFalse)
208 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
209 assert(exception != (ExceptionInfo *) NULL);
210 assert(exception->signature == MagickCoreSignature);
212 Limit channels according to image
213 add up number of values needed per color.
216 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
218 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
220 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
222 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
223 (image->colorspace == CMYKColorspace))
225 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
226 image->alpha_trait != UndefinedPixelTrait)
230 Read string, to determine number of arguments needed,
236 GetNextToken(p,&p,MagickPathExtent,token);
237 if ( token[0] == ',' ) continue;
238 if ( isalpha((int) token[0]) || token[0] == '#' )
239 x += number_colors; /* color argument found */
241 x++; /* floating point argument */
243 /* control points and color values */
244 if ((x % (2+number_colors)) != 0)
246 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
247 "InvalidArgument","'%s': %s", "sparse-color",
248 "Invalid number of Arguments");
249 return( (Image *) NULL);
254 /* Allocate and fill in the floating point arguments */
255 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
256 sizeof(*sparse_arguments));
257 if (sparse_arguments == (double *) NULL) {
258 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
259 "MemoryAllocationFailed","%s","SparseColorOption");
260 return( (Image *) NULL);
262 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
263 sizeof(*sparse_arguments));
266 while( *p != '\0' && x < number_arguments ) {
268 token[0]=','; while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
269 if ( token[0] == '\0' ) break;
270 if ( isalpha((int) token[0]) || token[0] == '#' ) {
271 (void) ThrowMagickException(exception,GetMagickModule(),
272 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
273 "Color found, instead of X-coord");
277 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
279 token[0]=','; while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
280 if ( token[0] == '\0' ) break;
281 if ( isalpha((int) token[0]) || token[0] == '#' ) {
282 (void) ThrowMagickException(exception,GetMagickModule(),
283 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
284 "Color found, instead of Y-coord");
288 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
289 /* color name or function given in string argument */
290 token[0]=','; while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
291 if ( token[0] == '\0' ) break;
292 if ( isalpha((int) token[0]) || token[0] == '#' ) {
293 /* Color string given */
294 (void) QueryColorCompliance(token,AllCompliance,&color,
296 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
297 sparse_arguments[x++] = QuantumScale*color.red;
298 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
299 sparse_arguments[x++] = QuantumScale*color.green;
300 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
301 sparse_arguments[x++] = QuantumScale*color.blue;
302 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
303 (image->colorspace == CMYKColorspace))
304 sparse_arguments[x++] = QuantumScale*color.black;
305 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
306 image->alpha_trait != UndefinedPixelTrait)
307 sparse_arguments[x++] = QuantumScale*color.alpha;
310 /* Colors given as a set of floating point values - experimental */
311 /* NB: token contains the first floating point value to use! */
312 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
314 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
315 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
317 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
318 token[0] = ','; /* used this token - get another */
320 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
322 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
323 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
325 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
326 token[0] = ','; /* used this token - get another */
328 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
330 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
331 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
333 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
334 token[0] = ','; /* used this token - get another */
336 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
337 (image->colorspace == CMYKColorspace))
339 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
340 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
342 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
343 token[0] = ','; /* used this token - get another */
345 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
346 image->alpha_trait != UndefinedPixelTrait)
348 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
349 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
351 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
352 token[0] = ','; /* used this token - get another */
356 if (error != MagickFalse)
358 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
359 return((Image *) NULL);
361 if (number_arguments != x)
363 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
364 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
365 "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
366 return((Image *) NULL);
368 /* Call the Sparse Color Interpolation function with the parsed arguments */
369 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
371 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
372 return( sparse_image );
376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
380 % C L I S e t t i n g O p t i o n I n f o %
384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
386 % CLISettingOptionInfo() applies a single settings option into a CLI wand
387 % holding the image_info, draw_info, quantize_info structures that will be
388 % used when processing the images.
390 % These options do no require images to be present in the CLI wand for them
391 % to be able to be set, in which case they will generally be applied to image
392 % that are read in later
394 % Options handled by this function are listed in CommandOptions[] of
395 % "option.c" that is one of "SettingOptionFlags" option flags.
397 % The format of the CLISettingOptionInfo method is:
399 % void CLISettingOptionInfo(MagickCLI *cli_wand,
400 % const char *option, const char *arg1, const char *arg2)
402 % A description of each parameter follows:
404 % o cli_wand: structure holding settings to be applied
406 % o option: The option string to be set
408 % o arg1, arg2: optional argument strings to the operation
409 % arg2 is currently only used by "-limit"
412 WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
413 const char *option,const char *arg1n, const char *arg2n)
416 parse; /* option argument parsing (string to value table lookup) */
418 const char /* percent escaped versions of the args */
422 #define _image_info (cli_wand->wand.image_info)
423 #define _image (cli_wand->wand.images)
424 #define _exception (cli_wand->wand.exception)
425 #define _draw_info (cli_wand->draw_info)
426 #define _quantize_info (cli_wand->quantize_info)
427 #define IfSetOption (*option=='-')
428 #define ArgBoolean IfSetOption ? MagickTrue : MagickFalse
429 #define ArgBooleanNot IfSetOption ? MagickFalse : MagickTrue
430 #define ArgBooleanString (IfSetOption?"true":"false")
431 #define ArgOption(def) (IfSetOption?arg1:(const char *)(def))
433 assert(cli_wand != (MagickCLI *) NULL);
434 assert(cli_wand->signature == MagickWandSignature);
435 assert(cli_wand->wand.signature == MagickWandSignature);
437 if (cli_wand->wand.debug != MagickFalse)
438 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
439 "- Setting Option: %s \"%s\" \"%s\"", option,arg1n,arg2n);
445 #define _process_flags (cli_wand->process_flags)
446 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
447 /* Interpret Percent Escapes in Arguments - using first image */
448 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
449 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
450 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
451 /* Interpret Percent escapes in argument 1 */
452 if (arg1n != (char *) NULL) {
453 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
454 if (arg1 == (char *) NULL) {
455 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
456 arg1=arg1n; /* use the given argument as is */
459 if (arg2n != (char *) NULL) {
460 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
461 if (arg2 == (char *) NULL) {
462 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
463 arg2=arg2n; /* use the given argument as is */
467 #undef _process_flags
475 if (LocaleCompare("adjoin",option+1) == 0)
477 _image_info->adjoin = ArgBoolean;
480 if (LocaleCompare("affine",option+1) == 0)
482 CLIWandWarnReplaced("-draw 'affine ...'");
484 (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
486 GetAffineMatrix(&_draw_info->affine);
489 if (LocaleCompare("alpha-color",option+1) == 0)
491 /* SyncImageSettings() used to set per-image attribute. */
492 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
493 (void) QueryColorCompliance(ArgOption(MogrifyAlphaColor),AllCompliance,
494 &_image_info->alpha_color,_exception);
497 if (LocaleCompare("antialias",option+1) == 0)
499 _image_info->antialias =
500 _draw_info->stroke_antialias =
501 _draw_info->text_antialias = ArgBoolean;
504 if (LocaleCompare("attenuate",option+1) == 0)
506 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
507 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
508 (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
511 if (LocaleCompare("authenticate",option+1) == 0)
513 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
516 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
520 if (LocaleCompare("background",option+1) == 0)
522 /* FUTURE: both _image_info attribute & ImageOption in use!
523 _image_info only used directly for generating new images.
524 SyncImageSettings() used to set per-image attribute.
526 FUTURE: if _image_info->background_color is not set then
527 we should fall back to per-image background_color
529 At this time -background will 'wipe out' the per-image
532 Better error handling of QueryColorCompliance() needed.
534 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
535 (void) QueryColorCompliance(ArgOption(MogrifyBackgroundColor),AllCompliance,
536 &_image_info->background_color,_exception);
539 if (LocaleCompare("bias",option+1) == 0)
541 /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
542 as it is actually rarely used except in direct convolve operations
543 Usage outside a direct convolve operation is actally non-sensible!
545 SyncImageSettings() used to set per-image attribute.
547 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
548 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
549 (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
552 if (LocaleCompare("black-point-compensation",option+1) == 0)
554 /* Used as a image chromaticity setting
555 SyncImageSettings() used to set per-image attribute.
557 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
560 if (LocaleCompare("blue-primary",option+1) == 0)
562 /* Image chromaticity X,Y NB: Y=X if Y not defined
563 Used by many coders including PNG
564 SyncImageSettings() used to set per-image attribute.
566 arg1=ArgOption("0.0");
567 if (IsGeometry(arg1) == MagickFalse)
568 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
569 (void) SetImageOption(_image_info,option+1,arg1);
572 if (LocaleCompare("bordercolor",option+1) == 0)
574 /* FUTURE: both _image_info attribute & ImageOption in use!
575 SyncImageSettings() used to set per-image attribute.
576 Better error checking of QueryColorCompliance().
580 (void) SetImageOption(_image_info,option+1,arg1);
581 (void) QueryColorCompliance(arg1,AllCompliance,
582 &_image_info->border_color,_exception);
583 (void) QueryColorCompliance(arg1,AllCompliance,
584 &_draw_info->border_color,_exception);
587 (void) DeleteImageOption(_image_info,option+1);
588 (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
589 &_image_info->border_color,_exception);
590 (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
591 &_draw_info->border_color,_exception);
594 if (LocaleCompare("box",option+1) == 0)
596 CLIWandWarnReplaced("-undercolor");
597 CLISettingOptionInfo(cli_wand,"-undercolor",arg1, arg2);
600 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
604 if (LocaleCompare("cache",option+1) == 0)
609 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
610 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
611 limit=MagickResourceInfinity;
612 if (LocaleCompare("unlimited",arg1) != 0)
613 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
614 (void) SetMagickResourceLimit(MemoryResource,limit);
615 (void) SetMagickResourceLimit(MapResource,2*limit);
618 if (LocaleCompare("caption",option+1) == 0)
620 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
623 if (LocaleCompare("colorspace",option+1) == 0)
625 /* Setting used for new images via AquireImage()
626 But also used as a SimpleImageOperator
627 Undefined colorspace means don't modify images on
628 read or as a operation */
629 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
630 ArgOption("undefined"));
632 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
634 _image_info->colorspace=(ColorspaceType) parse;
637 if (LocaleCompare("comment",option+1) == 0)
639 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
642 if (LocaleCompare("compose",option+1) == 0)
644 /* FUTURE: _image_info should be used,
645 SyncImageSettings() used to set per-image attribute. - REMOVE
647 This setting should NOT be used to set image 'compose'
648 "-layer" operators shoud use _image_info if defined otherwise
649 they should use a per-image compose setting.
651 parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
652 ArgOption("undefined"));
654 CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
656 _image_info->compose=(CompositeOperator) parse;
657 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
660 if (LocaleCompare("compress",option+1) == 0)
662 /* FUTURE: What should be used? _image_info or ImageOption ???
663 The former is more efficent, but Crisy prefers the latter!
664 SyncImageSettings() used to set per-image attribute.
666 The coders appears to use _image_info, not Image_Option
667 however the image attribute (for save) is set from the
670 Note that "undefined" is a different setting to "none".
672 parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
673 ArgOption("undefined"));
675 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
677 _image_info->compression=(CompressionType) parse;
678 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
681 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
685 if (LocaleCompare("debug",option+1) == 0)
687 /* SyncImageSettings() used to set per-image attribute. */
688 arg1=ArgOption("none");
689 parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
691 CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
693 (void) SetLogEventMask(arg1);
694 _image_info->debug=IsEventLogging(); /* extract logging*/
695 cli_wand->wand.debug=IsEventLogging();
698 if (LocaleCompare("define",option+1) == 0)
700 if (LocaleNCompare(arg1,"registry:",9) == 0)
703 (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
705 (void) DeleteImageRegistry(arg1+9);
708 /* DefineImageOption() equals SetImageOption() but with '=' */
710 (void) DefineImageOption(_image_info,arg1);
711 else if (DeleteImageOption(_image_info,arg1) == MagickFalse)
712 CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
715 if (LocaleCompare("delay",option+1) == 0)
717 /* Only used for new images via AcquireImage()
718 FUTURE: Option should also be used for "-morph" (color morphing)
721 if (IsGeometry(arg1) == MagickFalse)
722 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
723 (void) SetImageOption(_image_info,option+1,arg1);
726 if (LocaleCompare("density",option+1) == 0)
728 /* FUTURE: strings used in _image_info attr and _draw_info!
729 Basically as density can be in a XxY form!
731 SyncImageSettings() used to set per-image attribute.
733 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
734 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
735 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
736 (void) CloneString(&_image_info->density,ArgOption(NULL));
737 (void) CloneString(&_draw_info->density,_image_info->density);
740 if (LocaleCompare("depth",option+1) == 0)
742 /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
743 SyncImageSettings() used to set per-image attribute.
745 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
746 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
747 _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
748 :MAGICKCORE_QUANTUM_DEPTH;
751 if (LocaleCompare("direction",option+1) == 0)
753 /* Image Option is only used to set _draw_info */
754 arg1=ArgOption("undefined");
755 parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
757 CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
759 _draw_info->direction=(DirectionType) parse;
760 (void) SetImageOption(_image_info,option+1,arg1);
763 if (LocaleCompare("display",option+1) == 0)
765 (void) CloneString(&_image_info->server_name,ArgOption(NULL));
766 (void) CloneString(&_draw_info->server_name,_image_info->server_name);
769 if (LocaleCompare("dispose",option+1) == 0)
771 /* only used in setting new images */
772 arg1=ArgOption("undefined");
773 parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
775 CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
777 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
780 if (LocaleCompare("dissimilarity-threshold",option+1) == 0)
782 /* FUTURE: this is only used by CompareImages() which is used
783 only by the "compare" CLI program at this time. */
784 arg1=ArgOption(DEFAULT_DISSIMILARITY_THRESHOLD);
785 if (IsGeometry(arg1) == MagickFalse)
786 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
787 (void) SetImageOption(_image_info,option+1,arg1);
790 if (LocaleCompare("dither",option+1) == 0)
792 /* _image_info attr (on/off), _quantize_info attr (on/off)
793 but also ImageInfo and _quantize_info method!
794 FUTURE: merge the duality of the dithering options
796 _image_info->dither = ArgBoolean;
797 (void) SetImageOption(_image_info,option+1,ArgOption("none"));
798 _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
799 MagickDitherOptions,MagickFalse,ArgOption("none"));
800 if (_quantize_info->dither_method == NoDitherMethod)
801 _image_info->dither = MagickFalse;
804 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
808 if (LocaleCompare("encoding",option+1) == 0)
810 (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
811 (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
814 if (LocaleCompare("endian",option+1) == 0)
816 /* Both _image_info attr and ImageInfo */
817 arg1 = ArgOption("undefined");
818 parse = ParseCommandOption(MagickEndianOptions,MagickFalse,arg1);
820 CLIWandExceptArgBreak(OptionError,"UnrecognizedEndianType",
822 /* FUTURE: check alloc/free of endian string! - remove? */
823 _image_info->endian=(EndianType) (*arg1);
824 (void) SetImageOption(_image_info,option+1,arg1);
827 if (LocaleCompare("extract",option+1) == 0)
829 (void) CloneString(&_image_info->extract,ArgOption(NULL));
832 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
836 if (LocaleCompare("family",option+1) == 0)
838 (void) CloneString(&_draw_info->family,ArgOption(NULL));
841 if (LocaleCompare("features",option+1) == 0)
843 (void) SetImageOption(_image_info,"identify:features",
846 (void) SetImageArtifact(_image,"verbose","true");
849 if (LocaleCompare("fill",option+1) == 0)
851 /* Set "fill" OR "fill-pattern" in _draw_info
852 The original fill color is preserved if a fill-pattern is given.
853 That way it does not effect other operations that directly using
854 the fill color and, can be retored using "+tile".
865 arg1 = ArgOption("none"); /* +fill turns it off! */
866 (void) SetImageOption(_image_info,option+1,arg1);
867 if (_draw_info->fill_pattern != (Image *) NULL)
868 _draw_info->fill_pattern=DestroyImage(_draw_info->fill_pattern);
870 /* is it a color or a image? -- ignore exceptions */
871 sans=AcquireExceptionInfo();
872 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
873 sans=DestroyExceptionInfo(sans);
875 if (status == MagickFalse)
876 _draw_info->fill_pattern=GetImageCache(_image_info,arg1,_exception);
878 _draw_info->fill=color;
881 if (LocaleCompare("filter",option+1) == 0)
883 /* SyncImageSettings() used to set per-image attribute. */
884 arg1 = ArgOption("undefined");
885 parse = ParseCommandOption(MagickFilterOptions,MagickFalse,arg1);
887 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageFilter",
889 (void) SetImageOption(_image_info,option+1,arg1);
892 if (LocaleCompare("font",option+1) == 0)
894 (void) CloneString(&_draw_info->font,ArgOption(NULL));
895 (void) CloneString(&_image_info->font,_draw_info->font);
898 if (LocaleCompare("format",option+1) == 0)
900 /* FUTURE: why the ping test, you could set ping after this! */
905 for (q=strchr(arg1,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
906 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
907 _image_info->ping=MagickFalse;
909 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
912 if (LocaleCompare("fuzz",option+1) == 0)
914 /* Option used to set image fuzz! unless blank canvas (from color)
915 Image attribute used for color compare operations
916 SyncImageSettings() used to set per-image attribute.
918 FUTURE: Can't find anything else using _image_info->fuzz directly!
919 convert structure attribute to 'option' string
922 if (IsGeometry(arg1) == MagickFalse)
923 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
924 _image_info->fuzz=StringToDoubleInterval(arg1,(double)
926 (void) SetImageOption(_image_info,option+1,arg1);
929 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
933 if (LocaleCompare("gravity",option+1) == 0)
935 /* SyncImageSettings() used to set per-image attribute. */
936 arg1 = ArgOption("none");
937 parse = ParseCommandOption(MagickGravityOptions,MagickFalse,arg1);
939 CLIWandExceptArgBreak(OptionError,"UnrecognizedGravityType",
941 _draw_info->gravity=(GravityType) parse;
942 (void) SetImageOption(_image_info,option+1,arg1);
945 if (LocaleCompare("green-primary",option+1) == 0)
947 /* Image chromaticity X,Y NB: Y=X if Y not defined
948 SyncImageSettings() used to set per-image attribute.
949 Used directly by many coders
951 arg1=ArgOption("0.0");
952 if (IsGeometry(arg1) == MagickFalse)
953 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
954 (void) SetImageOption(_image_info,option+1,arg1);
957 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
961 if (LocaleCompare("highlight-color",option+1) == 0)
963 /* FUTURE: this is only used by CompareImages() which is used
964 only by the "compare" CLI program at this time. */
965 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
968 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
972 if (LocaleCompare("intensity",option+1) == 0)
974 arg1 = ArgOption("undefined");
975 parse = ParseCommandOption(MagickPixelIntensityOptions,MagickFalse,
978 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityType",
980 (void) SetImageOption(_image_info,option+1,arg1);
983 if (LocaleCompare("intent",option+1) == 0)
985 /* Only used by coders: MIFF, MPC, BMP, PNG
986 and for image profile call to AcquireTransformThreadSet()
987 SyncImageSettings() used to set per-image attribute.
989 arg1 = ArgOption("undefined");
990 parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
992 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
994 (void) SetImageOption(_image_info,option+1,arg1);
997 if (LocaleCompare("interlace",option+1) == 0)
999 /* _image_info is directly used by coders (so why an image setting?)
1000 SyncImageSettings() used to set per-image attribute.
1002 arg1 = ArgOption("undefined");
1003 parse = ParseCommandOption(MagickInterlaceOptions,MagickFalse,arg1);
1005 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterlaceType",
1007 _image_info->interlace=(InterlaceType) parse;
1008 (void) SetImageOption(_image_info,option+1,arg1);
1011 if (LocaleCompare("interline-spacing",option+1) == 0)
1013 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1014 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1015 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1016 _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
1020 if (LocaleCompare("interpolate",option+1) == 0)
1022 /* SyncImageSettings() used to set per-image attribute. */
1023 arg1 = ArgOption("undefined");
1024 parse = ParseCommandOption(MagickInterpolateOptions,MagickFalse,arg1);
1026 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterpolateMethod",
1028 (void) SetImageOption(_image_info,option+1,arg1);
1031 if (LocaleCompare("interword-spacing",option+1) == 0)
1033 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1034 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1035 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1036 _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
1039 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1043 if (LocaleCompare("kerning",option+1) == 0)
1045 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1046 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1047 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1048 _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
1051 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1055 if (LocaleCompare("label",option+1) == 0)
1057 /* only used for new images - not in SyncImageOptions() */
1058 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1061 if (LocaleCompare("limit",option+1) == 0)
1066 limit=MagickResourceInfinity;
1067 parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1);
1069 CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType",
1071 if (LocaleCompare("unlimited",arg2) != 0)
1072 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
1073 (void) SetMagickResourceLimit((ResourceType)parse,limit);
1076 if (LocaleCompare("log",option+1) == 0)
1079 if ((strchr(arg1,'%') == (char *) NULL))
1080 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1081 (void) SetLogFormat(arg1);
1085 if (LocaleCompare("lowlight-color",option+1) == 0)
1087 /* FUTURE: this is only used by CompareImages() which is used
1088 only by the "compare" CLI program at this time. */
1089 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1092 if (LocaleCompare("loop",option+1) == 0)
1094 /* SyncImageSettings() used to set per-image attribute. */
1095 arg1=ArgOption("0");
1096 if (IsGeometry(arg1) == MagickFalse)
1097 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1098 (void) SetImageOption(_image_info,option+1,arg1);
1101 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1105 if (LocaleCompare("metric",option+1) == 0)
1107 /* FUTURE: this is only used by CompareImages() which is used
1108 only by the "compare" CLI program at this time. */
1109 parse=ParseCommandOption(MagickMetricOptions,MagickFalse,arg1);
1111 CLIWandExceptArgBreak(OptionError,"UnrecognizedMetricType",
1113 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1116 if (LocaleCompare("moments",option+1) == 0)
1118 (void) SetImageOption(_image_info,"identify:moments",
1121 (void) SetImageArtifact(_image,"verbose","true");
1124 if (LocaleCompare("monitor",option+1) == 0)
1126 (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
1127 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
1130 if (LocaleCompare("monochrome",option+1) == 0)
1132 /* Setting (used by some input coders!) -- why?
1133 Warning: This is also Special '-type' SimpleOperator
1135 _image_info->monochrome= ArgBoolean;
1138 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1142 if (LocaleCompare("orient",option+1) == 0)
1144 /* Is not used when defining for new images.
1145 This makes it more of a 'operation' than a setting
1146 FUTURE: make set meta-data operator instead.
1147 SyncImageSettings() used to set per-image attribute.
1149 parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
1150 ArgOption("undefined"));
1152 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
1154 _image_info->orientation=(OrientationType)parse;
1155 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1158 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1162 if (LocaleCompare("page",option+1) == 0)
1164 /* Only used for new images and image generators.
1165 SyncImageSettings() used to set per-image attribute. ?????
1166 That last is WRONG!!!!
1167 FUTURE: adjust named 'page' sizes according density
1171 page[MagickPathExtent];
1184 (void) DeleteImageOption(_image_info,option+1);
1185 (void) CloneString(&_image_info->page,(char *) NULL);
1188 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
1189 image_option=GetImageOption(_image_info,"page");
1190 if (image_option != (const char *) NULL)
1191 flags=ParseAbsoluteGeometry(image_option,&geometry);
1192 canonical_page=GetPageGeometry(arg1);
1193 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1194 canonical_page=DestroyString(canonical_page);
1195 (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu",
1196 (unsigned long) geometry.width,(unsigned long) geometry.height);
1197 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1198 (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu%+ld%+ld",
1199 (unsigned long) geometry.width,(unsigned long) geometry.height,
1200 (long) geometry.x,(long) geometry.y);
1201 (void) SetImageOption(_image_info,option+1,page);
1202 (void) CloneString(&_image_info->page,page);
1205 if (LocaleCompare("ping",option+1) == 0)
1207 _image_info->ping = ArgBoolean;
1210 if (LocaleCompare("pointsize",option+1) == 0)
1213 if (IsGeometry(arg1) == MagickFalse)
1214 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1215 _image_info->pointsize =
1216 _draw_info->pointsize =
1217 StringToDouble(arg1,(char **) NULL);
1220 _image_info->pointsize=0.0; /* unset pointsize */
1221 _draw_info->pointsize=12.0;
1225 if (LocaleCompare("precision",option+1) == 0)
1227 arg1=ArgOption("-1");
1228 if (IsGeometry(arg1) == MagickFalse)
1229 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1230 (void) SetMagickPrecision(StringToInteger(arg1));
1233 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1237 if (LocaleCompare("quality",option+1) == 0)
1239 if (IsGeometry(arg1) == MagickFalse)
1240 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1241 _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
1242 : UNDEFINED_COMPRESSION_QUALITY;
1243 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1246 if (LocaleCompare("quantize",option+1) == 0)
1248 /* Just a set direct in _quantize_info */
1249 arg1=ArgOption("undefined");
1250 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
1252 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
1254 _quantize_info->colorspace=(ColorspaceType)parse;
1257 if (LocaleCompare("quiet",option+1) == 0)
1259 /* FUTURE: if two -quiet is performed you can not do +quiet!
1260 This needs to be checked over thoughly.
1262 static WarningHandler
1263 warning_handler = (WarningHandler) NULL;
1266 tmp = SetWarningHandler((WarningHandler) NULL);
1268 if ( tmp != (WarningHandler) NULL)
1269 warning_handler = tmp; /* remember the old handler */
1270 if (!IfSetOption) /* set the old handler */
1271 warning_handler=SetWarningHandler(warning_handler);
1274 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1278 if (LocaleCompare("red-primary",option+1) == 0)
1280 /* Image chromaticity X,Y NB: Y=X if Y not defined
1282 SyncImageSettings() used to set per-image attribute.
1284 arg1=ArgOption("0.0");
1285 if (IsGeometry(arg1) == MagickFalse)
1286 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1287 (void) SetImageOption(_image_info,option+1,arg1);
1290 if (LocaleCompare("regard-warnings",option+1) == 0)
1291 /* FUTURE: to be replaced by a 'fatal-level' type setting */
1293 if (LocaleCompare("render",option+1) == 0)
1295 /* _draw_info only setting */
1296 _draw_info->render= ArgBooleanNot;
1299 if (LocaleCompare("respect-parenthesis",option+1) == 0)
1301 /* link image and setting stacks - option is itself saved on stack! */
1302 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1305 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1309 if (LocaleCompare("sampling-factor",option+1) == 0)
1311 /* FUTURE: should be converted to jpeg:sampling_factor */
1312 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1313 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1314 (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
1317 if (LocaleCompare("scene",option+1) == 0)
1319 /* SyncImageSettings() used to set this as a per-image attribute.
1322 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1323 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1324 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1325 _image_info->scene=StringToUnsignedLong(ArgOption("0"));
1328 if (LocaleCompare("seed",option+1) == 0)
1330 if (IsGeometry(arg1) == MagickFalse)
1331 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1333 IfSetOption ? (unsigned long) StringToUnsignedLong(arg1)
1334 : (unsigned long) time((time_t *) NULL) );
1337 if (LocaleCompare("size",option+1) == 0)
1339 /* FUTURE: string in _image_info -- convert to Option ???
1340 Look at the special handling for "size" in SetImageOption()
1342 (void) CloneString(&_image_info->size,ArgOption(NULL));
1345 if (LocaleCompare("stretch",option+1) == 0)
1347 arg1=ArgOption("undefined");
1348 parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
1350 CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
1352 _draw_info->stretch=(StretchType) parse;
1355 if (LocaleCompare("stroke",option+1) == 0)
1357 /* set stroke color OR stroke-pattern
1358 UPDATE: ensure stroke color is not destroyed is a pattern
1359 is given. Just in case the color is also used for other purposes.
1370 arg1 = ArgOption("none"); /* +fill turns it off! */
1371 (void) SetImageOption(_image_info,option+1,arg1);
1372 if (_draw_info->stroke_pattern != (Image *) NULL)
1373 _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
1375 /* is it a color or a image? -- ignore exceptions */
1376 sans=AcquireExceptionInfo();
1377 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
1378 sans=DestroyExceptionInfo(sans);
1380 if (status == MagickFalse)
1381 _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
1383 _draw_info->stroke=color;
1386 if (LocaleCompare("strokewidth",option+1) == 0)
1388 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1389 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1390 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1391 _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
1395 if (LocaleCompare("style",option+1) == 0)
1397 arg1=ArgOption("undefined");
1398 parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
1400 CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
1402 _draw_info->style=(StyleType) parse;
1406 if (LocaleCompare("subimage-search",option+1) == 0)
1408 /* FUTURE: this is only used by CompareImages() which is used
1409 only by the "compare" CLI program at this time. */
1410 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1414 if (LocaleCompare("synchronize",option+1) == 0)
1416 /* FUTURE: syncronize to storage - but what does that mean? */
1417 _image_info->synchronize = ArgBoolean;
1420 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1424 if (LocaleCompare("taint",option+1) == 0)
1426 /* SyncImageSettings() used to set per-image attribute. */
1427 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1430 if (LocaleCompare("texture",option+1) == 0)
1432 /* Note: arguments do not have percent escapes expanded */
1433 /* FUTURE: move _image_info string to option splay-tree
1434 Other than "montage" what uses "texture" ????
1436 (void) CloneString(&_image_info->texture,ArgOption(NULL));
1439 if (LocaleCompare("tile",option+1) == 0)
1441 /* Note: arguments do not have percent escapes expanded */
1442 _draw_info->fill_pattern=IfSetOption
1443 ?GetImageCache(_image_info,arg1,_exception)
1444 :DestroyImage(_draw_info->fill_pattern);
1447 if (LocaleCompare("tile-offset",option+1) == 0)
1449 /* SyncImageSettings() used to set per-image attribute. ??? */
1450 arg1=ArgOption("0");
1451 if (IsGeometry(arg1) == MagickFalse)
1452 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1453 (void) SetImageOption(_image_info,option+1,arg1);
1456 if (LocaleCompare("transparent-color",option+1) == 0)
1458 /* FUTURE: both _image_info attribute & ImageOption in use!
1459 _image_info only used for generating new images.
1460 SyncImageSettings() used to set per-image attribute.
1462 Note that +transparent-color, means fall-back to image
1463 attribute so ImageOption is deleted, not set to a default.
1465 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1466 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1467 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1468 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
1469 &_image_info->transparent_color,_exception);
1472 if (LocaleCompare("treedepth",option+1) == 0)
1474 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1475 _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
1478 if (LocaleCompare("type",option+1) == 0)
1480 /* SyncImageSettings() used to set per-image attribute. */
1481 parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
1482 ArgOption("undefined"));
1484 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
1486 _image_info->type=(ImageType) parse;
1487 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1490 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1494 if (LocaleCompare("undercolor",option+1) == 0)
1496 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1497 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
1498 &_draw_info->undercolor,_exception);
1501 if (LocaleCompare("units",option+1) == 0)
1503 /* SyncImageSettings() used to set per-image attribute.
1504 Should this effect _draw_info X and Y resolution?
1505 FUTURE: this probably should be part of the density setting
1507 parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1508 ArgOption("undefined"));
1510 CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
1512 _image_info->units=(ResolutionType) parse;
1513 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1516 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1520 if (LocaleCompare("verbose",option+1) == 0)
1522 /* FUTURE: Remember all options become image artifacts
1523 _image_info->verbose is only used by coders.
1525 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1526 _image_info->verbose= ArgBoolean;
1527 _image_info->ping=MagickFalse; /* verbose can't be a ping */
1530 if (LocaleCompare("virtual-pixel",option+1) == 0)
1532 /* SyncImageSettings() used to set per-image attribute.
1533 This is VERY deep in the image caching structure.
1535 parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1536 ArgOption("undefined"));
1538 CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
1540 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1543 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1547 if (LocaleCompare("weight",option+1) == 0)
1552 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,arg1);
1554 weight=(ssize_t) StringToUnsignedLong(arg1);
1555 _draw_info->weight=(size_t) weight;
1558 if (LocaleCompare("white-point",option+1) == 0)
1560 /* Used as a image chromaticity setting
1561 SyncImageSettings() used to set per-image attribute.
1563 arg1=ArgOption("0.0");
1564 if (IsGeometry(arg1) == MagickFalse)
1565 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1566 (void) SetImageOption(_image_info,option+1,arg1);
1569 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1572 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1575 /* clean up percent escape interpreted strings */
1576 if ((arg1 && arg1n) && (arg1 != arg1n ))
1577 arg1=DestroyString((char *) arg1);
1578 if ((arg2 && arg2n) && (arg2 != arg2n ))
1579 arg2=DestroyString((char *) arg2);
1584 #undef _quantize_info
1587 #undef ArgBooleanNot
1588 #undef ArgBooleanString
1595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1599 + C L I S i m p l e O p e r a t o r I m a g e s %
1603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1605 % CLISimpleOperatorImages() applys one simple image operation given to all
1606 % the images in the CLI wand, using any per-image or global settings that was
1607 % previously saved in the CLI wand.
1609 % It is assumed that any such settings are up-to-date.
1611 % The format of the WandSimpleOperatorImages method is:
1613 % MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,const char *option,
1614 % const char *arg1, const char *arg2,ExceptionInfo *exception)
1616 % A description of each parameter follows:
1618 % o cli_wand: structure holding settings and images to be operated on
1620 % o option: The option string for the operation
1622 % o arg1, arg2: optional argument strings to the operation
1627 CLISimpleOperatorImage() is an Internal subrountine to apply one simple
1628 image operation to the current image pointed to by the CLI wand.
1630 The image in the list may be modified in three different ways...
1631 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1632 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1633 * one image replace by a list of images (-separate and -crop only!)
1635 In each case the result replaces the single original image in the list, as
1636 well as the pointer to the modified image (last image added if replaced by a
1637 list of images) is returned.
1639 As the image pointed to may be replaced, the first image in the list may
1640 also change. GetFirstImageInList() should be used by caller if they wish
1641 return the Image pointer to the first image in list.
1643 static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
1644 const char *option, const char *arg1n, const char *arg2n,
1645 ExceptionInfo *exception)
1662 const char /* percent escaped versions of the args */
1666 #define _image_info (cli_wand->wand.image_info)
1667 #define _image (cli_wand->wand.images)
1668 #define _exception (cli_wand->wand.exception)
1669 #define _draw_info (cli_wand->draw_info)
1670 #define _quantize_info (cli_wand->quantize_info)
1671 #define _process_flags (cli_wand->process_flags)
1672 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
1673 #define IfNormalOp (*option=='-')
1674 #define IfPlusOp (*option!='-')
1675 #define IsNormalOp IfNormalOp ? MagickTrue : MagickFalse
1676 #define IsPlusOp IfNormalOp ? MagickFalse : MagickTrue
1678 assert(cli_wand != (MagickCLI *) NULL);
1679 assert(cli_wand->signature == MagickWandSignature);
1680 assert(cli_wand->wand.signature == MagickWandSignature);
1681 assert(_image != (Image *) NULL); /* an image must be present */
1682 if (cli_wand->wand.debug != MagickFalse)
1683 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
1688 /* Interpret Percent Escapes in Arguments - using first image */
1689 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
1690 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
1691 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
1692 /* Interpret Percent escapes in argument 1 */
1693 if (arg1n != (char *) NULL) {
1694 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
1695 if (arg1 == (char *) NULL) {
1696 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1697 arg1=arg1n; /* use the given argument as is */
1700 if (arg2n != (char *) NULL) {
1701 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
1702 if (arg2 == (char *) NULL) {
1703 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1704 arg2=arg2n; /* use the given argument as is */
1708 #undef _process_flags
1712 (void) FormatLocaleFile(stderr,
1713 "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
1716 new_image = (Image *) NULL; /* the replacement image, if not null at end */
1717 SetGeometryInfo(&geometry_info);
1719 switch (*(option+1))
1723 if (LocaleCompare("adaptive-blur",option+1) == 0)
1725 flags=ParseGeometry(arg1,&geometry_info);
1726 if ((flags & (RhoValue|SigmaValue)) == 0)
1727 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1728 if ((flags & SigmaValue) == 0)
1729 geometry_info.sigma=1.0;
1730 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
1731 geometry_info.sigma,_exception);
1734 if (LocaleCompare("adaptive-resize",option+1) == 0)
1736 /* FUTURE: Roll into a resize special operator */
1737 if (IsGeometry(arg1) == MagickFalse)
1738 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1739 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1740 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
1744 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
1746 flags=ParseGeometry(arg1,&geometry_info);
1747 if ((flags & (RhoValue|SigmaValue)) == 0)
1748 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1749 if ((flags & SigmaValue) == 0)
1750 geometry_info.sigma=1.0;
1751 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
1752 geometry_info.sigma,_exception);
1755 if (LocaleCompare("alpha",option+1) == 0)
1757 parse=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,arg1);
1759 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelOption",
1761 (void) SetImageAlphaChannel(_image,(AlphaChannelOption) parse,
1765 if (LocaleCompare("annotate",option+1) == 0)
1768 geometry[MagickPathExtent];
1770 SetGeometryInfo(&geometry_info);
1771 flags=ParseGeometry(arg1,&geometry_info);
1773 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1774 if ((flags & SigmaValue) == 0)
1775 geometry_info.sigma=geometry_info.rho;
1776 (void) CloneString(&_draw_info->text,arg2);
1777 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
1778 geometry_info.xi,geometry_info.psi);
1779 (void) CloneString(&_draw_info->geometry,geometry);
1780 _draw_info->affine.sx=cos(DegreesToRadians(
1781 fmod(geometry_info.rho,360.0)));
1782 _draw_info->affine.rx=sin(DegreesToRadians(
1783 fmod(geometry_info.rho,360.0)));
1784 _draw_info->affine.ry=(-sin(DegreesToRadians(
1785 fmod(geometry_info.sigma,360.0))));
1786 _draw_info->affine.sy=cos(DegreesToRadians(
1787 fmod(geometry_info.sigma,360.0)));
1788 (void) AnnotateImage(_image,_draw_info,_exception);
1789 GetAffineMatrix(&_draw_info->affine);
1792 if (LocaleCompare("auto-gamma",option+1) == 0)
1794 (void) AutoGammaImage(_image,_exception);
1797 if (LocaleCompare("auto-level",option+1) == 0)
1799 (void) AutoLevelImage(_image,_exception);
1802 if (LocaleCompare("auto-orient",option+1) == 0)
1804 new_image=AutoOrientImage(_image,_image->orientation,_exception);
1807 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1811 if (LocaleCompare("black-threshold",option+1) == 0)
1813 if (IsGeometry(arg1) == MagickFalse)
1814 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1815 (void) BlackThresholdImage(_image,arg1,_exception);
1818 if (LocaleCompare("blue-shift",option+1) == 0)
1820 geometry_info.rho=1.5;
1822 flags=ParseGeometry(arg1,&geometry_info);
1823 if ((flags & RhoValue) == 0)
1824 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1826 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
1829 if (LocaleCompare("blur",option+1) == 0)
1831 flags=ParseGeometry(arg1,&geometry_info);
1832 if ((flags & (RhoValue|SigmaValue)) == 0)
1833 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1834 if ((flags & SigmaValue) == 0)
1835 geometry_info.sigma=1.0;
1836 new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
1840 if (LocaleCompare("border",option+1) == 0)
1848 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
1849 if ((flags & (WidthValue | HeightValue)) == 0)
1850 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1851 compose=OverCompositeOp;
1852 value=GetImageOption(_image_info,"compose");
1853 if (value != (const char *) NULL)
1854 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
1856 new_image=BorderImage(_image,&geometry,compose,_exception);
1859 if (LocaleCompare("brightness-contrast",option+1) == 0)
1871 flags=ParseGeometry(arg1,&geometry_info);
1872 if ((flags & RhoValue) == 0)
1873 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1874 brightness=geometry_info.rho;
1876 if ((flags & SigmaValue) != 0)
1877 contrast=geometry_info.sigma;
1878 (void) BrightnessContrastImage(_image,brightness,contrast,
1882 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1886 if (LocaleCompare("canny",option+1) == 0)
1888 flags=ParseGeometry(arg1,&geometry_info);
1889 if ((flags & (RhoValue|SigmaValue)) == 0)
1890 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1891 if ((flags & SigmaValue) == 0)
1892 geometry_info.sigma=1.0;
1893 if ((flags & XiValue) == 0)
1894 geometry_info.xi=10;
1895 if ((flags & PsiValue) == 0)
1896 geometry_info.psi=30;
1897 if ((flags & PercentValue) != 0)
1899 geometry_info.xi/=100.0;
1900 geometry_info.psi/=100.0;
1902 new_image=CannyEdgeImage(_image,geometry_info.rho,geometry_info.sigma,
1903 geometry_info.xi,geometry_info.psi,_exception);
1906 if (LocaleCompare("cdl",option+1) == 0)
1908 /* Note: arguments do not have percent escapes expanded */
1910 *color_correction_collection;
1913 Color correct with a color decision list.
1915 color_correction_collection=FileToString(arg1,~0UL,_exception);
1916 if (color_correction_collection == (char *) NULL)
1918 (void) ColorDecisionListImage(_image,color_correction_collection,
1922 if (LocaleCompare("channel",option+1) == 0)
1926 (void) SetPixelChannelMask(_image,DefaultChannels);
1929 parse=ParseChannelOption(arg1);
1931 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
1933 (void) SetPixelChannelMask(_image,(ChannelType) parse);
1936 if (LocaleCompare("charcoal",option+1) == 0)
1938 flags=ParseGeometry(arg1,&geometry_info);
1939 if ((flags & (RhoValue|SigmaValue)) == 0)
1940 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1941 if ((flags & SigmaValue) == 0)
1942 geometry_info.sigma=1.0;
1943 if ((flags & XiValue) == 0)
1944 geometry_info.xi=1.0;
1945 new_image=CharcoalImage(_image,geometry_info.rho,geometry_info.sigma,
1949 if (LocaleCompare("chop",option+1) == 0)
1951 if (IsGeometry(arg1) == MagickFalse)
1952 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1953 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1954 new_image=ChopImage(_image,&geometry,_exception);
1957 if (LocaleCompare("clamp",option+1) == 0)
1959 (void) ClampImage(_image,_exception);
1962 if (LocaleCompare("clip",option+1) == 0)
1965 (void) ClipImage(_image,_exception);
1966 else /* "+mask" remove the write mask */
1967 (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,_exception);
1970 if (LocaleCompare("clip-mask",option+1) == 0)
1972 /* Note: arguments do not have percent escapes expanded */
1989 /* use "+clip-mask" Remove the write mask for -clip-path */
1990 (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,_exception);
1993 mask_image=GetImageCache(_image_info,arg1,_exception);
1994 if (mask_image == (Image *) NULL)
1996 if (SetImageStorageClass(mask_image,DirectClass,_exception) == MagickFalse)
1998 /* Create a write mask from cli_wand mask image */
1999 /* FUTURE: use Alpha operations instead and create a Grey Image */
2000 mask_view=AcquireAuthenticCacheView(mask_image,_exception);
2001 for (y=0; y < (ssize_t) mask_image->rows; y++)
2003 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
2005 if (q == (Quantum *) NULL)
2007 for (x=0; x < (ssize_t) mask_image->columns; x++)
2009 if (mask_image->alpha_trait == UndefinedPixelTrait)
2010 SetPixelAlpha(mask_image,(Quantum)
2011 GetPixelIntensity(mask_image,q),q);
2012 SetPixelGray(mask_image,GetPixelAlpha(mask_image,q),q);
2013 q+=GetPixelChannels(mask_image);
2015 if (SyncCacheViewAuthenticPixels(mask_view,_exception) == MagickFalse)
2018 /* clean up and set the write mask */
2019 mask_view=DestroyCacheView(mask_view);
2020 mask_image->alpha_trait=BlendPixelTrait;
2021 (void) SetImageColorspace(_image,GRAYColorspace,_exception);
2022 (void) SetImageMask(_image,ReadPixelMask,mask_image,_exception);
2023 mask_image=DestroyImage(mask_image);
2026 if (LocaleCompare("clip-path",option+1) == 0)
2028 (void) ClipImagePath(_image,arg1,IsNormalOp,_exception);
2029 /* Note: Use "+clip-mask" remove the write mask added */
2032 if (LocaleCompare("colorize",option+1) == 0)
2034 if (IsGeometry(arg1) == MagickFalse)
2035 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2036 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
2039 if (LocaleCompare("color-matrix",option+1) == 0)
2044 kernel=AcquireKernelInfo(arg1,exception);
2045 if (kernel == (KernelInfo *) NULL)
2046 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2047 new_image=ColorMatrixImage(_image,kernel,_exception);
2048 kernel=DestroyKernelInfo(kernel);
2051 if (LocaleCompare("colors",option+1) == 0)
2053 /* Reduce the number of colors in the image.
2054 FUTURE: also provide 'plus version with image 'color counts'
2056 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2057 if (_quantize_info->number_colors == 0)
2058 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2059 if ((_image->storage_class == DirectClass) ||
2060 _image->colors > _quantize_info->number_colors)
2061 (void) QuantizeImage(_quantize_info,_image,_exception);
2063 (void) CompressImageColormap(_image,_exception);
2066 if (LocaleCompare("colorspace",option+1) == 0)
2068 /* WARNING: this is both a image_info setting (already done)
2069 and a operator to change image colorspace.
2071 FUTURE: default colorspace should be sRGB!
2072 Unless some type of 'linear colorspace' mode is set.
2074 Note that +colorspace sets "undefined" or no effect on
2075 new images, but forces images already in memory back to RGB!
2076 That seems to be a little strange!
2078 (void) TransformImageColorspace(_image,
2079 IfNormalOp ? _image_info->colorspace : sRGBColorspace,
2083 if (LocaleCompare("connected-components",option+1) == 0)
2085 if (IsGeometry(arg1) == MagickFalse)
2086 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2087 new_image=ConnectedComponentsImage(_image,(size_t)
2088 StringToInteger(arg1),(CCObjectInfo **) NULL,_exception);
2091 if (LocaleCompare("contrast",option+1) == 0)
2093 CLIWandWarnReplaced(IfNormalOp?"-level":"+level");
2094 (void) ContrastImage(_image,IsNormalOp,_exception);
2097 if (LocaleCompare("contrast-stretch",option+1) == 0)
2106 flags=ParseGeometry(arg1,&geometry_info);
2107 if ((flags & RhoValue) == 0)
2108 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2109 black_point=geometry_info.rho;
2110 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2112 if ((flags & PercentValue) != 0) {
2113 black_point*=(double) _image->columns*_image->rows/100.0;
2114 white_point*=(double) _image->columns*_image->rows/100.0;
2116 white_point=(double) _image->columns*_image->rows-white_point;
2117 (void) ContrastStretchImage(_image,black_point,white_point,
2121 if (LocaleCompare("convolve",option+1) == 0)
2132 kernel_info=AcquireKernelInfo(arg1,exception);
2133 if (kernel_info == (KernelInfo *) NULL)
2134 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2136 for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
2137 gamma+=kernel_info->values[j];
2138 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
2139 for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
2140 kernel_info->values[j]*=gamma;
2141 new_image=MorphologyImage(_image,CorrelateMorphology,1,kernel_info,
2143 kernel_info=DestroyKernelInfo(kernel_info);
2146 if (LocaleCompare("crop",option+1) == 0)
2148 /* WARNING: This can generate multiple images! */
2149 if (IsGeometry(arg1) == MagickFalse)
2150 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2151 new_image=CropImageToTiles(_image,arg1,_exception);
2154 if (LocaleCompare("cycle",option+1) == 0)
2156 if (IsGeometry(arg1) == MagickFalse)
2157 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2158 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2162 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2166 if (LocaleCompare("decipher",option+1) == 0)
2168 /* Note: arguments do not have percent escapes expanded */
2172 passkey=FileToStringInfo(arg1,~0UL,_exception);
2173 if (passkey == (StringInfo *) NULL)
2174 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2176 (void) PasskeyDecipherImage(_image,passkey,_exception);
2177 passkey=DestroyStringInfo(passkey);
2180 if (LocaleCompare("depth",option+1) == 0)
2182 /* The _image_info->depth setting has already been set
2183 We just need to apply it to all images in current sequence
2185 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2186 That is it really is an operation, not a setting! Arrgghhh
2188 FUTURE: this should not be an operator!!!
2190 (void) SetImageDepth(_image,_image_info->depth,_exception);
2193 if (LocaleCompare("deskew",option+1) == 0)
2199 if (IsGeometry(arg1) == MagickFalse)
2200 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2201 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
2204 threshold=40.0*QuantumRange/100.0;
2205 new_image=DeskewImage(_image,threshold,_exception);
2208 if (LocaleCompare("despeckle",option+1) == 0)
2210 new_image=DespeckleImage(_image,_exception);
2213 if (LocaleCompare("distort",option+1) == 0)
2221 parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2223 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2225 if ((DistortMethod) parse == ResizeDistortion)
2229 /* Special Case - Argument is actually a resize geometry!
2230 ** Convert that to an appropriate distortion argument array.
2231 ** FUTURE: make a separate special resize operator
2232 Roll into a resize special operator */
2233 if (IsGeometry(arg2) == MagickFalse)
2234 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2236 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
2237 resize_args[0]=(double) geometry.width;
2238 resize_args[1]=(double) geometry.height;
2239 new_image=DistortImage(_image,(DistortMethod) parse,
2240 (size_t)2,resize_args,MagickTrue,_exception);
2243 /* convert argument string into an array of doubles */
2244 args = StringToArrayOfDoubles(arg2,&count,_exception);
2245 if (args == (double *) NULL )
2246 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2248 new_image=DistortImage(_image,(DistortMethod) parse,(size_t)
2249 count,args,IsPlusOp,_exception);
2250 args=(double *) RelinquishMagickMemory(args);
2253 if (LocaleCompare("draw",option+1) == 0)
2255 (void) CloneString(&_draw_info->primitive,arg1);
2256 (void) DrawImage(_image,_draw_info,_exception);
2257 (void) CloneString(&_draw_info->primitive,(char *) NULL);
2260 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2264 if (LocaleCompare("edge",option+1) == 0)
2266 flags=ParseGeometry(arg1,&geometry_info);
2267 if ((flags & (RhoValue|SigmaValue)) == 0)
2268 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2269 new_image=EdgeImage(_image,geometry_info.rho,_exception);
2272 if (LocaleCompare("emboss",option+1) == 0)
2274 flags=ParseGeometry(arg1,&geometry_info);
2275 if ((flags & (RhoValue|SigmaValue)) == 0)
2276 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2277 if ((flags & SigmaValue) == 0)
2278 geometry_info.sigma=1.0;
2279 new_image=EmbossImage(_image,geometry_info.rho,
2280 geometry_info.sigma,_exception);
2283 if (LocaleCompare("encipher",option+1) == 0)
2285 /* Note: arguments do not have percent escapes expanded */
2289 passkey=FileToStringInfo(arg1,~0UL,_exception);
2290 if (passkey != (StringInfo *) NULL)
2292 (void) PasskeyEncipherImage(_image,passkey,_exception);
2293 passkey=DestroyStringInfo(passkey);
2297 if (LocaleCompare("enhance",option+1) == 0)
2299 new_image=EnhanceImage(_image,_exception);
2302 if (LocaleCompare("equalize",option+1) == 0)
2304 (void) EqualizeImage(_image,_exception);
2307 if (LocaleCompare("evaluate",option+1) == 0)
2312 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
2314 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
2316 if (IsGeometry(arg2) == MagickFalse)
2317 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
2318 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
2319 (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
2323 if (LocaleCompare("extent",option+1) == 0)
2325 if (IsGeometry(arg1) == MagickFalse)
2326 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2327 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
2328 if (geometry.width == 0)
2329 geometry.width=_image->columns;
2330 if (geometry.height == 0)
2331 geometry.height=_image->rows;
2332 new_image=ExtentImage(_image,&geometry,_exception);
2335 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2339 if (LocaleCompare("flip",option+1) == 0)
2341 new_image=FlipImage(_image,_exception);
2344 if (LocaleCompare("flop",option+1) == 0)
2346 new_image=FlopImage(_image,_exception);
2349 if (LocaleCompare("floodfill",option+1) == 0)
2354 if (IsGeometry(arg1) == MagickFalse)
2355 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2356 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2357 (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
2358 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2359 geometry.y,IsPlusOp,_exception);
2362 if (LocaleCompare("frame",option+1) == 0)
2373 value=GetImageOption(_image_info,"compose");
2374 compose=OverCompositeOp; /* use Over not _image->compose */
2375 if (value != (const char *) NULL)
2376 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
2378 if (IsGeometry(arg1) == MagickFalse)
2379 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2380 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
2381 frame_info.width=geometry.width;
2382 frame_info.height=geometry.height;
2383 frame_info.outer_bevel=geometry.x;
2384 frame_info.inner_bevel=geometry.y;
2385 frame_info.x=(ssize_t) frame_info.width;
2386 frame_info.y=(ssize_t) frame_info.height;
2387 frame_info.width=_image->columns+2*frame_info.width;
2388 frame_info.height=_image->rows+2*frame_info.height;
2389 new_image=FrameImage(_image,&frame_info,compose,_exception);
2392 if (LocaleCompare("function",option+1) == 0)
2400 parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
2402 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2404 /* convert argument string into an array of doubles */
2405 args = StringToArrayOfDoubles(arg2,&count,_exception);
2406 if (args == (double *) NULL )
2407 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2409 (void) FunctionImage(_image,(MagickFunction)parse,(size_t) count,args,
2411 args=(double *) RelinquishMagickMemory(args);
2414 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2418 if (LocaleCompare("gamma",option+1) == 0)
2423 if (IsGeometry(arg1) == MagickFalse)
2424 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2425 constant=StringToDouble(arg1,(char **) NULL);
2427 /* Using Gamma, via a cache */
2429 constant=PerceptibleReciprocal(constant);
2430 (void) GammaImage(_image,constant,_exception);
2432 /* Using Evaluate POW, direct update of values - more accurite */
2434 constant=PerceptibleReciprocal(constant);
2435 (void) EvaluateImage(_image,PowEvaluateOperator,constant,_exception);
2436 _image->gamma*=StringToDouble(arg1,(char **) NULL);
2438 /* Set gamma setting -- Old meaning of "+gamma"
2439 * _image->gamma=StringToDouble(arg1,(char **) NULL);
2443 if (LocaleCompare("gaussian-blur",option+1) == 0)
2445 flags=ParseGeometry(arg1,&geometry_info);
2446 if ((flags & (RhoValue|SigmaValue)) == 0)
2447 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2448 if ((flags & SigmaValue) == 0)
2449 geometry_info.sigma=1.0;
2450 new_image=GaussianBlurImage(_image,geometry_info.rho,
2451 geometry_info.sigma,_exception);
2454 if (LocaleCompare("gaussian",option+1) == 0)
2456 CLIWandWarnReplaced("-gaussian-blur");
2457 (void) CLISimpleOperatorImage(cli_wand,"-gaussian-blur",arg1,NULL,exception);
2459 if (LocaleCompare("geometry",option+1) == 0)
2462 Record Image offset for composition. (A Setting)
2463 Resize last _image. (ListOperator) -- DEPRECIATE
2464 FUTURE: Why if no 'offset' does this resize ALL images?
2465 Also why is the setting recorded in the IMAGE non-sense!
2468 { /* remove the previous composition geometry offset! */
2469 if (_image->geometry != (char *) NULL)
2470 _image->geometry=DestroyString(_image->geometry);
2473 if (IsGeometry(arg1) == MagickFalse)
2474 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2475 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
2476 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2477 (void) CloneString(&_image->geometry,arg1);
2479 new_image=ResizeImage(_image,geometry.width,geometry.height,
2480 _image->filter,_exception);
2483 if (LocaleCompare("grayscale",option+1) == 0)
2485 parse=ParseCommandOption(MagickPixelIntensityOptions,
2488 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
2490 (void) GrayscaleImage(_image,(PixelIntensityMethod) parse,_exception);
2493 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2497 if (LocaleCompare("hough-lines",option+1) == 0)
2499 flags=ParseGeometry(arg1,&geometry_info);
2500 if ((flags & (RhoValue|SigmaValue)) == 0)
2501 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2502 if ((flags & SigmaValue) == 0)
2503 geometry_info.sigma=geometry_info.rho;
2504 if ((flags & XiValue) == 0)
2505 geometry_info.xi=40;
2506 new_image=HoughLineImage(_image,(size_t) geometry_info.rho,
2507 (size_t) geometry_info.sigma,(size_t) geometry_info.xi,_exception);
2510 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2514 if (LocaleCompare("identify",option+1) == 0)
2520 format=GetImageOption(_image_info,"format");
2521 if (format == (char *) NULL)
2523 (void) IdentifyImage(_image,stdout,_image_info->verbose,
2527 text=InterpretImageProperties(_image_info,_image,format,_exception);
2528 if (text == (char *) NULL)
2529 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
2531 (void) fputs(text,stdout);
2532 text=DestroyString((char *)text);
2535 if (LocaleCompare("implode",option+1) == 0)
2537 flags=ParseGeometry(arg1,&geometry_info);
2538 if ((flags & RhoValue) == 0)
2539 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2540 new_image=ImplodeImage(_image,geometry_info.rho,_image->interpolate,
2544 if (LocaleCompare("interpolative-resize",option+1) == 0)
2546 /* FUTURE: New to IMv7
2547 Roll into a resize special operator */
2548 if (IsGeometry(arg1) == MagickFalse)
2549 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2550 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2551 new_image=InterpolativeResizeImage(_image,geometry.width,
2552 geometry.height,_image->interpolate,_exception);
2555 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2559 if (LocaleCompare("kuwahara",option+1) == 0)
2562 Edge preserving blur.
2564 flags=ParseGeometry(arg1,&geometry_info);
2565 if ((flags & (RhoValue|SigmaValue)) == 0)
2566 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2567 if ((flags & SigmaValue) == 0)
2568 geometry_info.sigma=geometry_info.rho-0.5;
2569 new_image=KuwaharaImage(_image,geometry_info.rho,geometry_info.sigma,
2573 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2577 if (LocaleCompare("lat",option+1) == 0)
2579 flags=ParseGeometry(arg1,&geometry_info);
2580 if ((flags & (RhoValue|SigmaValue)) == 0)
2581 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2582 if ((flags & SigmaValue) == 0)
2583 geometry_info.sigma=1.0;
2584 if ((flags & PercentValue) != 0)
2585 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2586 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
2587 (size_t) geometry_info.sigma,(double) geometry_info.xi,
2591 if (LocaleCompare("level",option+1) == 0)
2601 flags=ParseGeometry(arg1,&geometry_info);
2602 if ((flags & RhoValue) == 0)
2603 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2604 black_point=geometry_info.rho;
2605 white_point=(double) QuantumRange;
2606 if ((flags & SigmaValue) != 0)
2607 white_point=geometry_info.sigma;
2609 if ((flags & XiValue) != 0)
2610 gamma=geometry_info.xi;
2611 if ((flags & PercentValue) != 0)
2613 black_point*=(double) (QuantumRange/100.0);
2614 white_point*=(double) (QuantumRange/100.0);
2616 if ((flags & SigmaValue) == 0)
2617 white_point=(double) QuantumRange-black_point;
2618 if (IfPlusOp || ((flags & AspectValue) != 0))
2619 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
2621 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
2624 if (LocaleCompare("level-colors",option+1) == 0)
2627 token[MagickPathExtent];
2636 p=(const char *) arg1;
2637 GetNextToken(p,&p,MagickPathExtent,token); /* get black point color */
2638 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2639 (void) QueryColorCompliance(token,AllCompliance,
2640 &black_point,_exception);
2642 (void) QueryColorCompliance("#000000",AllCompliance,
2643 &black_point,_exception);
2644 if (isalpha((int) token[0]) || (token[0] == '#'))
2645 GetNextToken(p,&p,MagickPathExtent,token);
2647 white_point=black_point; /* set everything to that color */
2650 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2651 GetNextToken(p,&p,MagickPathExtent,token); /* Get white point color. */
2652 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2653 (void) QueryColorCompliance(token,AllCompliance,
2654 &white_point,_exception);
2656 (void) QueryColorCompliance("#ffffff",AllCompliance,
2657 &white_point,_exception);
2659 (void) LevelImageColors(_image,&black_point,&white_point,
2660 IsPlusOp,_exception);
2663 if (LocaleCompare("linear-stretch",option+1) == 0)
2672 flags=ParseGeometry(arg1,&geometry_info);
2673 if ((flags & RhoValue) == 0)
2674 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2675 black_point=geometry_info.rho;
2676 white_point=(double) _image->columns*_image->rows;
2677 if ((flags & SigmaValue) != 0)
2678 white_point=geometry_info.sigma;
2679 if ((flags & PercentValue) != 0)
2681 black_point*=(double) _image->columns*_image->rows/100.0;
2682 white_point*=(double) _image->columns*_image->rows/100.0;
2684 if ((flags & SigmaValue) == 0)
2685 white_point=(double) _image->columns*_image->rows-
2687 (void) LinearStretchImage(_image,black_point,white_point,_exception);
2690 if (LocaleCompare("liquid-rescale",option+1) == 0)
2692 /* FUTURE: Roll into a resize special operator */
2693 if (IsGeometry(arg1) == MagickFalse)
2694 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2695 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
2696 if ((flags & XValue) == 0)
2698 if ((flags & YValue) == 0)
2700 new_image=LiquidRescaleImage(_image,geometry.width,
2701 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
2704 if (LocaleCompare("local-contrast",option+1) == 0)
2709 flags=ParseGeometry(arg1,&geometry_info);
2710 if ((flags & RhoValue) == 0)
2711 geometry_info.rho=10;
2712 if ((flags & SigmaValue) == 0)
2713 geometry_info.sigma=12.5;
2714 new_image=LocalContrastImage(_image,geometry_info.rho,
2715 geometry_info.sigma,exception);
2718 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2722 if (LocaleCompare("magnify",option+1) == 0)
2724 new_image=MagnifyImage(_image,_exception);
2727 if (LocaleCompare("map",option+1) == 0)
2729 CLIWandWarnReplaced("-remap");
2730 (void) CLISimpleOperatorImage(cli_wand,"-remap",NULL,NULL,exception);
2733 if (LocaleCompare("mask",option+1) == 0)
2743 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,
2750 mask=GetImageCache(_image_info,arg1,_exception);
2751 if (mask == (Image *) NULL)
2753 (void) NegateImage(mask,MagickFalse,exception);
2754 (void) SetImageMask(_image,WritePixelMask,mask,_exception);
2755 mask=DestroyImage(mask);
2758 if (LocaleCompare("matte",option+1) == 0)
2760 CLIWandWarnReplaced(IfNormalOp?"-alpha Set":"-alpha Off");
2761 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2762 DeactivateAlphaChannel, _exception);
2765 if (LocaleCompare("mean-shift",option+1) == 0)
2767 flags=ParseGeometry(arg1,&geometry_info);
2768 if ((flags & (RhoValue|SigmaValue)) == 0)
2769 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2770 if ((flags & SigmaValue) == 0)
2771 geometry_info.sigma=1.0;
2772 if ((flags & XiValue) == 0)
2773 geometry_info.xi=0.10*QuantumRange;
2774 if ((flags & PercentValue) != 0)
2775 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2776 new_image=MeanShiftImage(_image,(size_t) geometry_info.rho,
2777 (size_t) geometry_info.sigma,geometry_info.xi,_exception);
2780 if (LocaleCompare("median",option+1) == 0)
2782 CLIWandWarnReplaced("-statistic Median");
2783 (void) CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1,exception);
2786 if (LocaleCompare("mode",option+1) == 0)
2788 /* FUTURE: note this is also a special "montage" option */
2789 CLIWandWarnReplaced("-statistic Mode");
2790 (void) CLISimpleOperatorImage(cli_wand,"-statistic","Mode",arg1,exception);
2793 if (LocaleCompare("modulate",option+1) == 0)
2795 if (IsGeometry(arg1) == MagickFalse)
2796 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2797 (void) ModulateImage(_image,arg1,_exception);
2800 if (LocaleCompare("monitor",option+1) == 0)
2802 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
2803 (MagickProgressMonitor) NULL,(void *) NULL);
2806 if (LocaleCompare("monochrome",option+1) == 0)
2808 (void) SetImageType(_image,BilevelType,_exception);
2811 if (LocaleCompare("morphology",option+1) == 0)
2814 token[MagickPathExtent];
2826 GetNextToken(p,&p,MagickPathExtent,token);
2827 parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
2829 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",option,
2832 GetNextToken(p,&p,MagickPathExtent,token);
2833 if ((*p == ':') || (*p == ','))
2834 GetNextToken(p,&p,MagickPathExtent,token);
2836 iterations=(ssize_t) StringToLong(p);
2837 kernel=AcquireKernelInfo(arg2,exception);
2838 if (kernel == (KernelInfo *) NULL)
2839 CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",option,arg2);
2840 new_image=MorphologyImage(_image,(MorphologyMethod)parse,iterations,
2842 kernel=DestroyKernelInfo(kernel);
2845 if (LocaleCompare("motion-blur",option+1) == 0)
2847 flags=ParseGeometry(arg1,&geometry_info);
2848 if ((flags & (RhoValue|SigmaValue)) == 0)
2849 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2850 if ((flags & SigmaValue) == 0)
2851 geometry_info.sigma=1.0;
2852 new_image=MotionBlurImage(_image,geometry_info.rho,geometry_info.sigma,
2853 geometry_info.xi,_exception);
2856 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2860 if (LocaleCompare("negate",option+1) == 0)
2862 (void) NegateImage(_image, IsPlusOp, _exception);
2865 if (LocaleCompare("noise",option+1) == 0)
2875 CLIWandWarnReplaced("-statistic NonPeak");
2876 (void) CLISimpleOperatorImage(cli_wand,"-statistic","NonPeak",arg1,exception);
2879 parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
2881 CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
2884 value=GetImageOption(_image_info,"attenuate");
2885 if (value != (const char *) NULL)
2886 attenuate=StringToDouble(value,(char **) NULL);
2887 new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
2891 if (LocaleCompare("normalize",option+1) == 0)
2893 (void) NormalizeImage(_image,_exception);
2896 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2900 if (LocaleCompare("opaque",option+1) == 0)
2905 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2906 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,IsPlusOp,
2910 if (LocaleCompare("ordered-dither",option+1) == 0)
2912 (void) OrderedDitherImage(_image,arg1,_exception);
2915 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2919 if (LocaleCompare("paint",option+1) == 0)
2921 flags=ParseGeometry(arg1,&geometry_info);
2922 if ((flags & (RhoValue|SigmaValue)) == 0)
2923 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2924 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2928 if (LocaleCompare("perceptible",option+1) == 0)
2930 (void) PerceptibleImage(_image,StringToDouble(arg1,(char **) NULL),
2934 if (LocaleCompare("polaroid",option+1) == 0)
2946 random_info=AcquireRandomInfo();
2947 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2948 random_info=DestroyRandomInfo(random_info);
2951 flags=ParseGeometry(arg1,&geometry_info);
2952 if ((flags & RhoValue) == 0)
2953 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2954 angle=geometry_info.rho;
2956 caption=GetImageProperty(_image,"caption",_exception);
2957 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2958 _image->interpolate,_exception);
2961 if (LocaleCompare("posterize",option+1) == 0)
2963 flags=ParseGeometry(arg1,&geometry_info);
2964 if ((flags & RhoValue) == 0)
2965 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2966 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
2967 _quantize_info->dither_method,_exception);
2970 if (LocaleCompare("preview",option+1) == 0)
2972 /* FUTURE: should be a 'Genesis' option?
2973 Option however is also in WandSettingOptionInfo()
2976 parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
2978 CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
2980 new_image=PreviewImage(_image,(PreviewType)parse,_exception);
2983 if (LocaleCompare("profile",option+1) == 0)
2985 /* Note: arguments do not have percent escapes expanded */
2999 { /* Remove a profile from the _image. */
3000 (void) ProfileImage(_image,arg1,(const unsigned char *)
3004 /* Associate a profile with the _image. */
3005 profile_info=CloneImageInfo(_image_info);
3006 profile=GetImageProfile(_image,"iptc");
3007 if (profile != (StringInfo *) NULL)
3008 profile_info->profile=(void *) CloneStringInfo(profile);
3009 profile_image=GetImageCache(profile_info,arg1,_exception);
3010 profile_info=DestroyImageInfo(profile_info);
3011 if (profile_image == (Image *) NULL)
3016 profile_info=CloneImageInfo(_image_info);
3017 (void) CopyMagickString(profile_info->filename,arg1,
3019 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
3020 if (profile != (StringInfo *) NULL)
3022 (void) ProfileImage(_image,profile_info->magick,
3023 GetStringInfoDatum(profile),(size_t)
3024 GetStringInfoLength(profile),_exception);
3025 profile=DestroyStringInfo(profile);
3027 profile_info=DestroyImageInfo(profile_info);
3030 ResetImageProfileIterator(profile_image);
3031 name=GetNextImageProfile(profile_image);
3032 while (name != (const char *) NULL)
3034 profile=GetImageProfile(profile_image,name);
3035 if (profile != (StringInfo *) NULL)
3036 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
3037 (size_t) GetStringInfoLength(profile),_exception);
3038 name=GetNextImageProfile(profile_image);
3040 profile_image=DestroyImage(profile_image);
3043 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3047 if (LocaleCompare("raise",option+1) == 0)
3049 if (IsGeometry(arg1) == MagickFalse)
3050 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3051 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3052 (void) RaiseImage(_image,&geometry,IsNormalOp,_exception);
3055 if (LocaleCompare("random-threshold",option+1) == 0)
3061 if (IsGeometry(arg1) == MagickFalse)
3062 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3064 max_threshold=(double) QuantumRange;
3065 flags=ParseGeometry(arg1,&geometry_info);
3066 min_threshold=geometry_info.rho;
3067 max_threshold=geometry_info.sigma;
3068 if ((flags & SigmaValue) == 0)
3069 max_threshold=min_threshold;
3070 if (strchr(arg1,'%') != (char *) NULL)
3072 max_threshold*=(double) (0.01*QuantumRange);
3073 min_threshold*=(double) (0.01*QuantumRange);
3075 (void) RandomThresholdImage(_image,min_threshold,max_threshold,
3079 if (LocaleCompare("read-mask",option+1) == 0)
3081 /* Note: arguments do not have percent escapes expanded */
3086 { /* Remove a mask. */
3087 (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,
3091 /* Set the image mask. */
3092 mask=GetImageCache(_image_info,arg1,_exception);
3093 if (mask == (Image *) NULL)
3095 (void) SetImageMask(_image,ReadPixelMask,mask,_exception);
3096 mask=DestroyImage(mask);
3099 if (LocaleCompare("recolor",option+1) == 0)
3101 CLIWandWarnReplaced("-color-matrix");
3102 (void) CLISimpleOperatorImage(cli_wand,"-color-matrix",arg1,NULL,
3105 if (LocaleCompare("region",option+1) == 0)
3107 if (IsGeometry(arg1) == MagickFalse)
3108 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3111 (void) SetImageRegionMask(_image,ReadPixelMask,
3112 (const RectangleInfo *) NULL,_exception);
3115 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
3116 (void) SetImageRegionMask(_image,ReadPixelMask,&geometry,_exception);
3119 if (LocaleCompare("remap",option+1) == 0)
3121 /* Note: arguments do not have percent escapes expanded */
3125 remap_image=GetImageCache(_image_info,arg1,_exception);
3126 if (remap_image == (Image *) NULL)
3128 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
3129 remap_image=DestroyImage(remap_image);
3132 if (LocaleCompare("repage",option+1) == 0)
3136 if (IsGeometry(arg1) == MagickFalse)
3137 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3139 (void) ResetImagePage(_image,arg1);
3142 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
3145 if (LocaleCompare("resample",option+1) == 0)
3147 /* FUTURE: Roll into a resize special operation */
3148 flags=ParseGeometry(arg1,&geometry_info);
3149 if ((flags & (RhoValue|SigmaValue)) == 0)
3150 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3151 if ((flags & SigmaValue) == 0)
3152 geometry_info.sigma=geometry_info.rho;
3153 new_image=ResampleImage(_image,geometry_info.rho,
3154 geometry_info.sigma,_image->filter,_exception);
3157 if (LocaleCompare("resize",option+1) == 0)
3159 if (IsGeometry(arg1) == MagickFalse)
3160 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3161 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3162 new_image=ResizeImage(_image,geometry.width,geometry.height,
3163 _image->filter,_exception);
3166 if (LocaleCompare("roll",option+1) == 0)
3168 if (IsGeometry(arg1) == MagickFalse)
3169 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3170 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
3171 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
3174 if (LocaleCompare("rotate",option+1) == 0)
3176 flags=ParseGeometry(arg1,&geometry_info);
3177 if ((flags & RhoValue) == 0)
3178 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3179 if ((flags & GreaterValue) != 0 && (_image->columns <= _image->rows))
3181 if ((flags & LessValue) != 0 && (_image->columns >= _image->rows))
3183 new_image=RotateImage(_image,geometry_info.rho,_exception);
3186 if (LocaleCompare("rotational-blur",option+1) == 0)
3188 flags=ParseGeometry(arg1,&geometry_info);
3189 if ((flags & RhoValue) == 0)
3190 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3191 new_image=RotationalBlurImage(_image,geometry_info.rho,_exception);
3194 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3198 if (LocaleCompare("sample",option+1) == 0)
3200 /* FUTURE: Roll into a resize special operator */
3201 if (IsGeometry(arg1) == MagickFalse)
3202 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3203 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3204 new_image=SampleImage(_image,geometry.width,geometry.height,
3208 if (LocaleCompare("scale",option+1) == 0)
3210 /* FUTURE: Roll into a resize special operator */
3211 if (IsGeometry(arg1) == MagickFalse)
3212 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3213 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3214 new_image=ScaleImage(_image,geometry.width,geometry.height,
3218 if (LocaleCompare("segment",option+1) == 0)
3220 flags=ParseGeometry(arg1,&geometry_info);
3221 if ((flags & (RhoValue|SigmaValue)) == 0)
3222 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3223 if ((flags & SigmaValue) == 0)
3224 geometry_info.sigma=1.0;
3225 (void) SegmentImage(_image,_image->colorspace,
3226 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3230 if (LocaleCompare("selective-blur",option+1) == 0)
3232 flags=ParseGeometry(arg1,&geometry_info);
3233 if ((flags & (RhoValue|SigmaValue)) == 0)
3234 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3235 if ((flags & SigmaValue) == 0)
3236 geometry_info.sigma=1.0;
3237 if ((flags & PercentValue) != 0)
3238 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3239 new_image=SelectiveBlurImage(_image,geometry_info.rho,
3240 geometry_info.sigma,geometry_info.xi,_exception);
3243 if (LocaleCompare("separate",option+1) == 0)
3245 /* WARNING: This can generate multiple images! */
3246 /* FUTURE - this may be replaced by a "-channel" method */
3247 new_image=SeparateImages(_image,_exception);
3250 if (LocaleCompare("sepia-tone",option+1) == 0)
3252 if (IsGeometry(arg1) == MagickFalse)
3253 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3254 new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
3255 (double) QuantumRange+1.0),_exception);
3258 if (LocaleCompare("shade",option+1) == 0)
3260 flags=ParseGeometry(arg1,&geometry_info);
3261 if (((flags & RhoValue) == 0) || ((flags & SigmaValue) == 0))
3262 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3263 new_image=ShadeImage(_image,IsNormalOp,geometry_info.rho,
3264 geometry_info.sigma,_exception);
3267 if (LocaleCompare("shadow",option+1) == 0)
3269 flags=ParseGeometry(arg1,&geometry_info);
3270 if ((flags & (RhoValue|SigmaValue)) == 0)
3271 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3272 if ((flags & SigmaValue) == 0)
3273 geometry_info.sigma=1.0;
3274 if ((flags & XiValue) == 0)
3275 geometry_info.xi=4.0;
3276 if ((flags & PsiValue) == 0)
3277 geometry_info.psi=4.0;
3278 new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
3279 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3280 ceil(geometry_info.psi-0.5),_exception);
3283 if (LocaleCompare("sharpen",option+1) == 0)
3285 flags=ParseGeometry(arg1,&geometry_info);
3286 if ((flags & (RhoValue|SigmaValue)) == 0)
3287 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3288 if ((flags & SigmaValue) == 0)
3289 geometry_info.sigma=1.0;
3290 if ((flags & XiValue) == 0)
3291 geometry_info.xi=0.0;
3292 new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
3296 if (LocaleCompare("shave",option+1) == 0)
3298 if (IsGeometry(arg1) == MagickFalse)
3299 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3300 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3301 new_image=ShaveImage(_image,&geometry,_exception);
3304 if (LocaleCompare("shear",option+1) == 0)
3306 flags=ParseGeometry(arg1,&geometry_info);
3307 if ((flags & RhoValue) == 0)
3308 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3309 if ((flags & SigmaValue) == 0)
3310 geometry_info.sigma=geometry_info.rho;
3311 new_image=ShearImage(_image,geometry_info.rho,geometry_info.sigma,
3315 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
3317 flags=ParseGeometry(arg1,&geometry_info);
3318 if ((flags & RhoValue) == 0)
3319 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3320 if ((flags & SigmaValue) == 0)
3321 geometry_info.sigma=(double) QuantumRange/2.0;
3322 if ((flags & PercentValue) != 0)
3323 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3325 (void) SigmoidalContrastImage(_image,IsNormalOp,geometry_info.rho,
3326 geometry_info.sigma,_exception);
3329 if (LocaleCompare("sketch",option+1) == 0)
3331 flags=ParseGeometry(arg1,&geometry_info);
3332 if ((flags & (RhoValue|SigmaValue)) == 0)
3333 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3334 if ((flags & SigmaValue) == 0)
3335 geometry_info.sigma=1.0;
3336 new_image=SketchImage(_image,geometry_info.rho,
3337 geometry_info.sigma,geometry_info.xi,_exception);
3340 if (LocaleCompare("solarize",option+1) == 0)
3342 if (IsGeometry(arg1) == MagickFalse)
3343 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3344 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3345 QuantumRange+1.0),_exception);
3348 if (LocaleCompare("sparse-color",option+1) == 0)
3350 parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
3352 CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
3354 new_image=SparseColorOption(_image,(SparseColorMethod)parse,arg2,
3358 if (LocaleCompare("splice",option+1) == 0)
3360 if (IsGeometry(arg1) == MagickFalse)
3361 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3362 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
3363 new_image=SpliceImage(_image,&geometry,_exception);
3366 if (LocaleCompare("spread",option+1) == 0)
3368 flags=ParseGeometry(arg1,&geometry_info);
3369 if ((flags & RhoValue) == 0)
3370 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3371 new_image=SpreadImage(_image,_image->interpolate,geometry_info.rho,
3375 if (LocaleCompare("statistic",option+1) == 0)
3377 parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
3379 CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
3381 flags=ParseGeometry(arg2,&geometry_info);
3382 if ((flags & RhoValue) == 0)
3383 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3384 if ((flags & SigmaValue) == 0)
3385 geometry_info.sigma=geometry_info.rho;
3386 new_image=StatisticImage(_image,(StatisticType)parse,
3387 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3391 if (LocaleCompare("strip",option+1) == 0)
3393 (void) StripImage(_image,_exception);
3396 if (LocaleCompare("swirl",option+1) == 0)
3398 flags=ParseGeometry(arg1,&geometry_info);
3399 if ((flags & RhoValue) == 0)
3400 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3401 new_image=SwirlImage(_image,geometry_info.rho,
3402 _image->interpolate,_exception);
3405 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3409 if (LocaleCompare("threshold",option+1) == 0)
3414 threshold=(double) QuantumRange/2;
3416 if (IsGeometry(arg1) == MagickFalse)
3417 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3418 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
3420 (void) BilevelImage(_image,threshold,_exception);
3423 if (LocaleCompare("thumbnail",option+1) == 0)
3425 if (IsGeometry(arg1) == MagickFalse)
3426 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3427 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3428 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3432 if (LocaleCompare("tint",option+1) == 0)
3434 if (IsGeometry(arg1) == MagickFalse)
3435 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3436 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
3439 if (LocaleCompare("transform",option+1) == 0)
3441 CLIWandWarnReplaced("+distort AffineProjection");
3442 new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
3445 if (LocaleCompare("transparent",option+1) == 0)
3450 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3451 (void) TransparentPaintImage(_image,&target,(Quantum)
3452 TransparentAlpha,IsPlusOp,_exception);
3455 if (LocaleCompare("transpose",option+1) == 0)
3457 new_image=TransposeImage(_image,_exception);
3460 if (LocaleCompare("transverse",option+1) == 0)
3462 new_image=TransverseImage(_image,_exception);
3465 if (LocaleCompare("trim",option+1) == 0)
3467 new_image=TrimImage(_image,_exception);
3470 if (LocaleCompare("type",option+1) == 0)
3472 /* Note that "type" setting should have already been defined */
3473 (void) SetImageType(_image,_image_info->type,_exception);
3476 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3480 if (LocaleCompare("unique",option+1) == 0)
3482 /* FUTURE: move to SyncImageSettings() and AcqireImage()???
3483 Option is not documented, bt appears to be for "identify".
3484 We may need a identify specific verbose!
3487 (void) DeleteImageArtifact(_image,"identify:unique-colors");
3490 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3491 (void) SetImageArtifact(_image,"verbose","true");
3494 if (LocaleCompare("unique-colors",option+1) == 0)
3496 new_image=UniqueImageColors(_image,_exception);
3499 if (LocaleCompare("unsharp",option+1) == 0)
3501 flags=ParseGeometry(arg1,&geometry_info);
3502 if ((flags & (RhoValue|SigmaValue)) == 0)
3503 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3504 if ((flags & SigmaValue) == 0)
3505 geometry_info.sigma=1.0;
3506 if ((flags & XiValue) == 0)
3507 geometry_info.xi=1.0;
3508 if ((flags & PsiValue) == 0)
3509 geometry_info.psi=0.05;
3510 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3511 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
3514 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3518 if (LocaleCompare("verbose",option+1) == 0)
3520 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
3521 three places! ImageArtifact ImageOption _image_info->verbose
3522 Some how new images also get this artifact!
3524 (void) SetImageArtifact(_image,option+1,
3525 IfNormalOp ? "true" : "false" );
3528 if (LocaleCompare("vignette",option+1) == 0)
3530 flags=ParseGeometry(arg1,&geometry_info);
3531 if ((flags & (RhoValue|SigmaValue)) == 0)
3532 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3533 if ((flags & SigmaValue) == 0)
3534 geometry_info.sigma=1.0;
3535 if ((flags & XiValue) == 0)
3536 geometry_info.xi=0.1*_image->columns;
3537 if ((flags & PsiValue) == 0)
3538 geometry_info.psi=0.1*_image->rows;
3539 if ((flags & PercentValue) != 0)
3541 geometry_info.xi*=(double) _image->columns/100.0;
3542 geometry_info.psi*=(double) _image->rows/100.0;
3544 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
3545 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3546 ceil(geometry_info.psi-0.5),_exception);
3549 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3553 if (LocaleCompare("wave",option+1) == 0)
3555 flags=ParseGeometry(arg1,&geometry_info);
3556 if ((flags & (RhoValue|SigmaValue)) == 0)
3557 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3558 if ((flags & SigmaValue) == 0)
3559 geometry_info.sigma=1.0;
3560 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3561 _image->interpolate,_exception);
3564 if (LocaleCompare("wavelet-denoise",option+1) == 0)
3566 flags=ParseGeometry(arg1,&geometry_info);
3567 if ((flags & RhoValue) == 0)
3568 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3569 if ((flags & PercentValue) != 0)
3571 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
3572 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
3574 if ((flags & SigmaValue) == 0)
3575 geometry_info.sigma=0.0;
3576 new_image=WaveletDenoiseImage(_image,geometry_info.rho,
3577 geometry_info.sigma,_exception);
3580 if (LocaleCompare("white-threshold",option+1) == 0)
3582 if (IsGeometry(arg1) == MagickFalse)
3583 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3584 (void) WhiteThresholdImage(_image,arg1,_exception);
3587 if (LocaleCompare("write-mask",option+1) == 0)
3589 /* Note: arguments do not have percent escapes expanded */
3594 { /* Remove a mask. */
3595 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,
3599 /* Set the image mask. */
3600 mask=GetImageCache(_image_info,arg1,_exception);
3601 if (mask == (Image *) NULL)
3603 (void) SetImageMask(_image,WritePixelMask,mask,_exception);
3604 mask=DestroyImage(mask);
3607 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3610 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3612 /* clean up percent escape interpreted strings */
3614 arg1=DestroyString((char *)arg1);
3616 arg2=DestroyString((char *)arg2);
3618 /* Replace current image with any image that was generated
3619 and set image point to last image (so image->next is correct) */
3620 if (new_image != (Image *) NULL)
3621 ReplaceImageInListReturnLast(&_image,new_image);
3626 #undef _quantize_info
3635 WandPrivate MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,
3636 const char *option,const char *arg1,const char *arg2,ExceptionInfo *exception)
3638 #if !USE_WAND_METHODS
3644 assert(cli_wand != (MagickCLI *) NULL);
3645 assert(cli_wand->signature == MagickWandSignature);
3646 assert(cli_wand->wand.signature == MagickWandSignature);
3647 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
3649 if (cli_wand->wand.debug != MagickFalse)
3650 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
3651 "- Simple Operator: %s \"%s\" \"%s\"", option,arg1,arg2);
3653 #if !USE_WAND_METHODS
3654 /* FUTURE add appropriate tracing */
3656 n=GetImageListLength(cli_wand->wand.images);
3657 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
3660 CLISimpleOperatorImage(cli_wand, option, arg1, arg2,exception);
3661 if ( cli_wand->wand.images->next == (Image *) NULL )
3663 cli_wand->wand.images=cli_wand->wand.images->next;
3666 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
3668 MagickResetIterator(&cli_wand->wand);
3669 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
3670 (void) CLISimpleOperatorImage(cli_wand, option, arg1, arg2,exception);
3671 MagickResetIterator(&cli_wand->wand);
3677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3681 + C L I L i s t O p e r a t o r I m a g e s %
3685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3687 % CLIListOperatorImages() applies a single operation that is apply to the
3688 % entire image list as a whole. The result is often a complete replacment
3689 % of the image list with a completely new list, or with just a single image
3692 % The format of the MogrifyImage method is:
3694 % MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
3695 % const char *option,const char *arg1,const char *arg2)
3697 % A description of each parameter follows:
3699 % o cli_wand: structure holding settings to be applied
3701 % o option: The option string for the operation
3703 % o arg1, arg2: optional argument strings to the operation
3704 % arg2 is currently not used
3707 WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
3708 const char *option,const char *arg1n,const char *arg2n)
3710 const char /* percent escaped versions of the args */
3723 #define _image_info (cli_wand->wand.image_info)
3724 #define _images (cli_wand->wand.images)
3725 #define _exception (cli_wand->wand.exception)
3726 #define _draw_info (cli_wand->draw_info)
3727 #define _quantize_info (cli_wand->quantize_info)
3728 #define _process_flags (cli_wand->process_flags)
3729 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
3730 #define IfNormalOp (*option=='-')
3731 #define IfPlusOp (*option!='-')
3732 #define IsNormalOp IfNormalOp ? MagickTrue : MagickFalse
3734 assert(cli_wand != (MagickCLI *) NULL);
3735 assert(cli_wand->signature == MagickWandSignature);
3736 assert(cli_wand->wand.signature == MagickWandSignature);
3737 assert(_images != (Image *) NULL); /* _images must be present */
3739 if (cli_wand->wand.debug != MagickFalse)
3740 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
3741 "- List Operator: %s \"%s\" \"%s\"", option,
3742 arg1n == (const char *) NULL ? "null" : arg1n,
3743 arg2n == (const char *) NULL ? "null" : arg2n);
3748 /* Interpret Percent Escapes in Arguments - using first image */
3749 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
3750 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
3751 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
3752 /* Interpret Percent escapes in argument 1 */
3753 if (arg1n != (char *) NULL) {
3754 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
3755 if (arg1 == (char *) NULL) {
3756 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3757 arg1=arg1n; /* use the given argument as is */
3760 if (arg2n != (char *) NULL) {
3761 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
3762 if (arg2 == (char *) NULL) {
3763 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3764 arg2=arg2n; /* use the given argument as is */
3768 #undef _process_flags
3772 new_images=NewImageList();
3774 switch (*(option+1))
3778 if (LocaleCompare("append",option+1) == 0)
3780 new_images=AppendImages(_images,IsNormalOp,_exception);
3783 if (LocaleCompare("average",option+1) == 0)
3785 CLIWandWarnReplaced("-evaluate-sequence Mean");
3786 (void) CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
3789 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3793 if (LocaleCompare("channel-fx",option+1) == 0)
3795 new_images=ChannelFxImage(_images,arg1,_exception);
3798 if (LocaleCompare("clut",option+1) == 0)
3803 /* FUTURE - make this a compose option, and thus can be used
3804 with layers compose or even compose last image over all other
3807 new_images=RemoveFirstImageFromList(&_images);
3808 clut_image=RemoveLastImageFromList(&_images);
3809 /* FUTURE - produce Exception, rather than silent fail */
3810 if (clut_image == (Image *) NULL)
3812 (void) ClutImage(new_images,clut_image,new_images->interpolate,
3814 clut_image=DestroyImage(clut_image);
3817 if (LocaleCompare("coalesce",option+1) == 0)
3819 new_images=CoalesceImages(_images,_exception);
3822 if (LocaleCompare("combine",option+1) == 0)
3824 parse=(ssize_t) _images->colorspace;
3826 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
3828 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
3830 new_images=CombineImages(_images,(ColorspaceType) parse,_exception);
3833 if (LocaleCompare("compare",option+1) == 0)
3846 Mathematically and visually annotate the difference between an
3847 image and its reconstruction.
3849 image=RemoveFirstImageFromList(&_images);
3850 reconstruct_image=RemoveFirstImageFromList(&_images);
3851 /* FUTURE - produce Exception, rather than silent fail */
3852 if (reconstruct_image == (Image *) NULL)
3854 metric=UndefinedErrorMetric;
3855 option=GetImageOption(_image_info,"metric");
3856 if (option != (const char *) NULL)
3857 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
3858 MagickFalse,option);
3859 new_images=CompareImages(image,reconstruct_image,metric,&distortion,
3862 reconstruct_image=DestroyImage(reconstruct_image);
3863 image=DestroyImage(image);
3866 if (LocaleCompare("complex",option+1) == 0)
3868 parse=ParseCommandOption(MagickComplexOptions,MagickFalse,arg1);
3870 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3872 new_images=ComplexImages(_images,(ComplexOperator) parse,_exception);
3875 if (LocaleCompare("composite",option+1) == 0)
3893 /* Compose value from "-compose" option only */
3894 value=GetImageOption(_image_info,"compose");
3895 if (value == (const char *) NULL)
3896 compose=OverCompositeOp; /* use Over not source_image->compose */
3898 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
3901 /* Get "clip-to-self" expert setting (false is normal) */
3902 value=GetImageOption(_image_info,"compose:clip-to-self");
3903 if (value == (const char *) NULL)
3904 clip_to_self=MagickTrue;
3906 clip_to_self=IsStringTrue(GetImageOption(_image_info,
3907 "compose:clip-to-self")); /* if this is true */
3908 value=GetImageOption(_image_info,"compose:outside-overlay");
3909 if (value != (const char *) NULL) { /* or this false */
3910 /* FUTURE: depreciate warning for "compose:outside-overlay"*/
3911 clip_to_self=IsStringFalse(value);
3914 new_images=RemoveFirstImageFromList(&_images);
3915 source_image=RemoveFirstImageFromList(&_images);
3916 if (source_image == (Image *) NULL)
3917 break; /* FUTURE - produce Exception, rather than silent fail */
3919 /* FUTURE - this should not be here! - should be part of -geometry */
3920 if (source_image->geometry != (char *) NULL)
3925 (void) ParseRegionGeometry(source_image,source_image->geometry,
3926 &resize_geometry,_exception);
3927 if ((source_image->columns != resize_geometry.width) ||
3928 (source_image->rows != resize_geometry.height))
3933 resize_image=ResizeImage(source_image,resize_geometry.width,
3934 resize_geometry.height,source_image->filter,_exception);
3935 if (resize_image != (Image *) NULL)
3937 source_image=DestroyImage(source_image);
3938 source_image=resize_image;
3942 SetGeometry(source_image,&geometry);
3943 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3944 GravityAdjustGeometry(new_images->columns,new_images->rows,
3945 new_images->gravity, &geometry);
3946 mask_image=RemoveFirstImageFromList(&_images);
3947 if (mask_image == (Image *) NULL)
3948 status&=CompositeImage(new_images,source_image,compose,clip_to_self,
3949 geometry.x,geometry.y,_exception);
3952 if ((compose == DisplaceCompositeOp) ||
3953 (compose == DistortCompositeOp))
3955 status&=CompositeImage(source_image,mask_image,
3956 CopyGreenCompositeOp,MagickTrue,0,0,_exception);
3957 status&=CompositeImage(new_images,source_image,compose,
3958 clip_to_self,geometry.x,geometry.y,_exception);
3965 clone_image=CloneImage(new_images,0,0,MagickTrue,_exception);
3966 if (clone_image == (Image *) NULL)
3968 status&=CompositeImage(new_images,source_image,compose,
3969 clip_to_self,geometry.x,geometry.y,_exception);
3970 status&=CompositeImage(new_images,mask_image,
3971 CopyAlphaCompositeOp,MagickTrue,0,0,_exception);
3972 status&=CompositeImage(clone_image,new_images,OverCompositeOp,
3973 clip_to_self,0,0,_exception);
3974 new_images=DestroyImage(new_images);
3975 new_images=clone_image;
3977 mask_image=DestroyImage(mask_image);
3979 source_image=DestroyImage(source_image);
3982 if (LocaleCompare("copy",option+1) == 0)
3996 if (IsGeometry(arg1) == MagickFalse)
3997 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3998 if (IsGeometry(arg2) == MagickFalse)
3999 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4000 (void) ParsePageGeometry(_images,arg2,&geometry,_exception);
4001 offset.x=geometry.x;
4002 offset.y=geometry.y;
4003 source_image=_images;
4004 if (source_image->next != (Image *) NULL)
4005 source_image=source_image->next;
4006 (void) ParsePageGeometry(source_image,arg1,&geometry,_exception);
4007 (void) CopyImagePixels(_images,source_image,&geometry,&offset,
4011 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4015 if (LocaleCompare("deconstruct",option+1) == 0)
4017 CLIWandWarnReplaced("-layer CompareAny");
4018 (void) CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
4021 if (LocaleCompare("delete",option+1) == 0)
4024 DeleteImages(&_images,arg1,_exception);
4026 DeleteImages(&_images,"-1",_exception);
4029 if (LocaleCompare("duplicate",option+1) == 0)
4039 if (IsGeometry(arg1) == MagickFalse)
4040 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
4042 number_duplicates=(size_t) StringToLong(arg1);
4044 if (p == (const char *) NULL)
4045 new_images=DuplicateImages(_images,number_duplicates,"-1",
4048 new_images=DuplicateImages(_images,number_duplicates,p,
4052 new_images=DuplicateImages(_images,1,"-1",_exception);
4053 AppendImageToList(&_images, new_images);
4054 new_images=(Image *) NULL;
4057 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4061 if (LocaleCompare("evaluate-sequence",option+1) == 0)
4063 parse=ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
4065 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
4067 new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
4071 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4075 if (LocaleCompare("fft",option+1) == 0)
4077 new_images=ForwardFourierTransformImage(_images,IsNormalOp,
4081 if (LocaleCompare("flatten",option+1) == 0)
4083 /* REDIRECTED to use -layers flatten instead */
4084 (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
4087 if (LocaleCompare("fx",option+1) == 0)
4089 new_images=FxImage(_images,arg1,_exception);
4092 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4096 if (LocaleCompare("hald-clut",option+1) == 0)
4098 /* FUTURE - make this a compose option (and thus layers compose )
4099 or perhaps compose last image over all other _images.
4104 new_images=RemoveFirstImageFromList(&_images);
4105 hald_image=RemoveLastImageFromList(&_images);
4106 if (hald_image == (Image *) NULL)
4108 (void) HaldClutImage(new_images,hald_image,_exception);
4109 hald_image=DestroyImage(hald_image);
4112 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4116 if (LocaleCompare("ift",option+1) == 0)
4122 magnitude_image=RemoveFirstImageFromList(&_images);
4123 phase_image=RemoveFirstImageFromList(&_images);
4124 /* FUTURE - produce Exception, rather than silent fail */
4125 if (phase_image == (Image *) NULL)
4127 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
4128 IsNormalOp,_exception);
4129 magnitude_image=DestroyImage(magnitude_image);
4130 phase_image=DestroyImage(phase_image);
4133 if (LocaleCompare("insert",option+1) == 0)
4142 if (IfNormalOp && (IsGeometry(arg1) == MagickFalse))
4143 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4145 insert_image=RemoveLastImageFromList(&_images);
4147 index=(ssize_t) StringToLong(arg1);
4148 index_image=insert_image;
4150 PrependImageToList(&_images,insert_image);
4151 else if (index == (ssize_t) GetImageListLength(_images))
4152 AppendImageToList(&_images,insert_image);
4155 index_image=GetImageFromList(_images,index-1);
4156 if (index_image == (Image *) NULL)
4157 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
4158 InsertImageInList(&index_image,insert_image);
4160 _images=GetFirstImageInList(index_image);
4163 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4167 if (LocaleCompare("layers",option+1) == 0)
4169 parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
4171 CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
4173 switch ((LayerMethod) parse)
4177 new_images=CoalesceImages(_images,_exception);
4180 case CompareAnyLayer:
4181 case CompareClearLayer:
4182 case CompareOverlayLayer:
4185 new_images=CompareImagesLayers(_images,(LayerMethod) parse,
4192 case TrimBoundsLayer:
4194 new_images=MergeImageLayers(_images,(LayerMethod) parse,
4200 new_images=DisposeImages(_images,_exception);
4203 case OptimizeImageLayer:
4205 new_images=OptimizeImageLayers(_images,_exception);
4208 case OptimizePlusLayer:
4210 new_images=OptimizePlusImageLayers(_images,_exception);
4213 case OptimizeTransLayer:
4215 OptimizeImageTransparency(_images,_exception);
4218 case RemoveDupsLayer:
4220 RemoveDuplicateLayers(&_images,_exception);
4223 case RemoveZeroLayer:
4225 RemoveZeroDelayLayers(&_images,_exception);
4229 { /* General Purpose, GIF Animation Optimizer. */
4230 new_images=CoalesceImages(_images,_exception);
4231 if (new_images == (Image *) NULL)
4233 _images=DestroyImageList(_images);
4234 _images=OptimizeImageLayers(new_images,_exception);
4235 if (_images == (Image *) NULL)
4237 new_images=DestroyImageList(new_images);
4238 OptimizeImageTransparency(_images,_exception);
4239 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
4243 case CompositeLayer:
4257 value=GetImageOption(_image_info,"compose");
4258 compose=OverCompositeOp; /* Default to Over */
4259 if (value != (const char *) NULL)
4260 compose=(CompositeOperator) ParseCommandOption(
4261 MagickComposeOptions,MagickFalse,value);
4263 /* Split image sequence at the first 'NULL:' image. */
4265 while (source != (Image *) NULL)
4267 source=GetNextImageInList(source);
4268 if ((source != (Image *) NULL) &&
4269 (LocaleCompare(source->magick,"NULL") == 0))
4272 if (source != (Image *) NULL)
4274 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4275 (GetNextImageInList(source) == (Image *) NULL))
4276 source=(Image *) NULL;
4278 { /* Separate the two lists, junk the null: image. */
4279 source=SplitImageList(source->previous);
4280 DeleteImageFromList(&source);
4283 if (source == (Image *) NULL)
4285 (void) ThrowMagickException(_exception,GetMagickModule(),
4286 OptionError,"MissingNullSeparator","layers Composite");
4289 /* Adjust offset with gravity and virtual canvas. */
4290 SetGeometry(_images,&geometry);
4291 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
4292 geometry.width=source->page.width != 0 ?
4293 source->page.width : source->columns;
4294 geometry.height=source->page.height != 0 ?
4295 source->page.height : source->rows;
4296 GravityAdjustGeometry(_images->page.width != 0 ?
4297 _images->page.width : _images->columns,
4298 _images->page.height != 0 ? _images->page.height :
4299 _images->rows,_images->gravity,&geometry);
4301 /* Compose the two image sequences together */
4302 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
4304 source=DestroyImageList(source);
4310 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4314 if (LocaleCompare("map",option+1) == 0)
4316 CLIWandWarnReplaced("+remap");
4317 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
4320 if (LocaleCompare("metric",option+1) == 0)
4322 (void) SetImageOption(_image_info,option+1,arg1);
4325 if (LocaleCompare("morph",option+1) == 0)
4330 if (IsGeometry(arg1) == MagickFalse)
4331 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4332 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4334 if (morph_image == (Image *) NULL)
4336 _images=DestroyImageList(_images);
4337 _images=morph_image;
4340 if (LocaleCompare("mosaic",option+1) == 0)
4342 /* REDIRECTED to use -layers mosaic instead */
4343 (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
4346 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4350 if (LocaleCompare("poly",option+1) == 0)
4358 /* convert argument string into an array of doubles */
4359 args = StringToArrayOfDoubles(arg1,&count,_exception);
4360 if (args == (double *) NULL )
4361 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg1);
4362 new_images=PolynomialImage(_images,(size_t) (count >> 1),args,
4364 args=(double *) RelinquishMagickMemory(args);
4367 if (LocaleCompare("process",option+1) == 0)
4369 /* FUTURE: better parsing using ScriptToken() from string ??? */
4377 arguments=StringToArgv(arg1,&number_arguments);
4378 if (arguments == (char **) NULL)
4380 if (strchr(arguments[1],'=') != (char *) NULL)
4401 Support old style syntax, filter="-option arg1".
4403 assert(arg1 != (const char *) NULL);
4404 length=strlen(arg1);
4405 token=(char *) NULL;
4406 if (~length >= (MagickPathExtent-1))
4407 token=(char *) AcquireQuantumMemory(length+MagickPathExtent,
4409 if (token == (char *) NULL)
4413 token_info=AcquireTokenInfo();
4414 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4415 "\"",'\0',&breaker,&next,"e);
4416 token_info=DestroyTokenInfo(token_info);
4422 argv=(&(arguments[next]));
4423 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4426 token=DestroyString(token);
4429 (void) SubstituteString(&arguments[1],"-","");
4430 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4431 number_arguments-2,(const char **) arguments+2,_exception);
4432 for (j=0; j < number_arguments; j++)
4433 arguments[j]=DestroyString(arguments[j]);
4434 arguments=(char **) RelinquishMagickMemory(arguments);
4437 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4441 if (LocaleCompare("remap",option+1) == 0)
4443 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
4446 if (LocaleCompare("reverse",option+1) == 0)
4448 ReverseImageList(&_images);
4451 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4455 if (LocaleCompare("smush",option+1) == 0)
4457 /* FUTURE: this option needs more work to make better */
4461 if (IsGeometry(arg1) == MagickFalse)
4462 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4463 offset=(ssize_t) StringToLong(arg1);
4464 new_images=SmushImages(_images,IsNormalOp,offset,_exception);
4467 if (LocaleCompare("subimage",option+1) == 0)
4485 base_image=GetImageFromList(_images,0);
4486 compare_image=GetImageFromList(_images,1);
4488 /* Comparision Metric */
4489 metric=UndefinedErrorMetric;
4490 value=GetImageOption(_image_info,"metric");
4491 if (value != (const char *) NULL)
4492 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
4495 new_images=SimilarityImage(base_image,compare_image,metric,0.0,
4496 &offset,&similarity,_exception);
4498 if (new_images != (Image *) NULL)
4501 result[MagickPathExtent];
4503 (void) FormatLocaleString(result,MagickPathExtent,"%lf",
4505 (void) SetImageProperty(new_images,"subimage:similarity",result,
4507 (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
4509 (void) SetImageProperty(new_images,"subimage:x",result,
4511 (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
4513 (void) SetImageProperty(new_images,"subimage:y",result,
4515 (void) FormatLocaleString(result,MagickPathExtent,
4516 "%lux%lu%+ld%+ld",(unsigned long) offset.width,(unsigned long)
4517 offset.height,(long) offset.x,(long) offset.y);
4518 (void) SetImageProperty(new_images,"subimage:offset",result,
4523 if (LocaleCompare("swap",option+1) == 0)
4544 flags=ParseGeometry(arg1,&geometry_info);
4545 if ((flags & RhoValue) == 0)
4546 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4547 index=(ssize_t) geometry_info.rho;
4548 if ((flags & SigmaValue) != 0)
4549 swap_index=(ssize_t) geometry_info.sigma;
4551 p=GetImageFromList(_images,index);
4552 q=GetImageFromList(_images,swap_index);
4553 if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
4555 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
4557 CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
4560 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
4561 swap=CloneImage(p,0,0,MagickTrue,_exception);
4562 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
4563 ReplaceImageInList(&q,swap);
4564 _images=GetFirstImageInList(q);
4567 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4570 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4573 /* clean up percent escape interpreted strings */
4575 arg1=DestroyString((char *)arg1);
4577 arg2=DestroyString((char *)arg2);
4579 /* if new image list generated, replace existing image list */
4580 if (new_images == (Image *) NULL)
4581 return(status == 0 ? MagickFalse : MagickTrue);
4582 _images=DestroyImageList(_images);
4583 _images=GetFirstImageInList(new_images);
4584 return(status == 0 ? MagickFalse : MagickTrue);
4590 #undef _quantize_info
4597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4601 + C L I N o I m a g e O p e r a t i o n s %
4605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4607 % CLINoImageOperator() Applies operations that may not actually need images
4610 % The classic operators of this type is "-read", which actually creates
4611 % images even when no images are present. Or image stack operators, which
4612 % can be applied (push or pop) to an empty image list.
4614 % Note that these operators may involve other special 'option' prefix
4615 % characters other than '-' or '+', namely parenthesis and braces.
4617 % The format of the CLINoImageOption method is:
4619 % void CLINoImageOption(MagickCLI *cli_wand,const char *option,
4620 % const char *arg1, const char *arg2)
4622 % A description of each parameter follows:
4624 % o cli_wand: the main CLI Wand to use. (sometimes not required)
4626 % o option: The special option (with any switch char) to process
4628 % o arg1 & arg2: Argument for option, if required
4629 % Currently arg2 is not used.
4632 WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
4633 const char *option,const char *arg1n,const char *arg2n)
4635 const char /* percent escaped versions of the args */
4639 #define _image_info (cli_wand->wand.image_info)
4640 #define _images (cli_wand->wand.images)
4641 #define _exception (cli_wand->wand.exception)
4642 #define _process_flags (cli_wand->process_flags)
4643 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
4644 #define IfNormalOp (*option=='-')
4645 #define IfPlusOp (*option!='-')
4647 assert(cli_wand != (MagickCLI *) NULL);
4648 assert(cli_wand->signature == MagickWandSignature);
4649 assert(cli_wand->wand.signature == MagickWandSignature);
4651 if (cli_wand->wand.debug != MagickFalse)
4652 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
4653 "- NoImage Operator: %s \"%s\" \"%s\"", option,
4654 arg1n != (char *) NULL ? arg1n : "",
4655 arg2n != (char *) NULL ? arg2n : "");
4660 /* Interpret Percent Escapes in Arguments - using first image */
4661 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
4662 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
4663 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
4664 /* Interpret Percent escapes in argument 1 */
4665 if (arg1n != (char *) NULL) {
4666 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
4667 if (arg1 == (char *) NULL) {
4668 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4669 arg1=arg1n; /* use the given argument as is */
4672 if (arg2n != (char *) NULL) {
4673 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4674 if (arg2 == (char *) NULL) {
4675 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4676 arg2=arg2n; /* use the given argument as is */
4680 #undef _process_flags
4683 do { /* break to exit code */
4685 No-op options (ignore these)
4687 if (LocaleCompare("noop",option+1) == 0) /* zero argument */
4689 if (LocaleCompare("sans",option+1) == 0) /* one argument */
4691 if (LocaleCompare("sans0",option+1) == 0) /* zero argument */
4693 if (LocaleCompare("sans1",option+1) == 0) /* one argument */
4695 if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
4700 if ( ( LocaleCompare("read",option+1) == 0 ) ||
4701 ( LocaleCompare("--",option) == 0 ) ) {
4702 /* Do Glob filename Expansion for 'arg1' then read all images.
4704 * Expansion handles '@', '~', '*', and '?' meta-characters while ignoring
4705 * (but attaching to the filenames in the generated argument list) any
4706 * [...] read modifiers that may be present.
4708 * For example: It will expand '*.gif[20x20]' into a list such as
4709 * 'abc.gif[20x20]', 'foobar.gif[20x20]', 'xyzzy.gif[20x20]'
4711 * NOTE: In IMv6 this was done globally across all images. This
4712 * meant you could include IM options in '@filename' lists, but you
4713 * could not include comments. Doing it only for image read makes
4714 * it far more secure.
4716 * Note: arguments do not have percent escapes expanded for security
4724 argv = (char **) &arg1;
4726 /* Expand 'glob' expressions in the given filename.
4727 Expansion handles any 'coder:' prefix, or read modifiers attached
4728 to the filename, including them in the resulting expanded list.
4730 if (ExpandFilenames(&argc,&argv) == MagickFalse)
4731 CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
4732 option,GetExceptionMessage(errno));
4734 /* loop over expanded filename list, and read then all in */
4735 for (i=0; i < (ssize_t) argc; i++) {
4738 if (_image_info->ping != MagickFalse)
4739 new_images=PingImages(_image_info,argv[i],_exception);
4741 new_images=ReadImages(_image_info,argv[i],_exception);
4742 AppendImageToList(&_images, new_images);
4744 argv=DestroyStringList(argv); /* Destroy the Expanded Filename list */
4749 Note: Writing a empty image list is valid in specific cases
4751 if (LocaleCompare("write",option+1) == 0) {
4752 /* Note: arguments do not have percent escapes expanded */
4754 key[MagickPathExtent];
4762 /* Need images, unless a "null:" output coder is used */
4763 if ( _images == (Image *) NULL ) {
4764 if ( LocaleCompare(arg1,"null:") == 0 )
4766 CLIWandExceptArgBreak(OptionError,"NoImagesForWrite",option,arg1);
4769 (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",arg1);
4770 (void) DeleteImageRegistry(key);
4771 write_images=_images;
4773 write_images=CloneImageList(_images,_exception);
4774 write_info=CloneImageInfo(_image_info);
4775 (void) WriteImages(write_info,write_images,arg1,_exception);
4776 write_info=DestroyImageInfo(write_info);
4778 write_images=DestroyImageList(write_images);
4782 Parenthesis and Brace operations
4784 if (LocaleCompare("(",option) == 0) {
4785 /* stack 'push' images */
4793 node=cli_wand->image_list_stack;
4794 for ( ; node != (Stack *) NULL; node=node->next)
4796 if ( size >= MAX_STACK_DEPTH )
4797 CLIWandExceptionBreak(OptionError,"ParenthesisNestedTooDeeply",option);
4798 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4799 if (node == (Stack *) NULL)
4800 CLIWandExceptionBreak(ResourceLimitFatalError,
4801 "MemoryAllocationFailed",option);
4802 node->data = (void *)cli_wand->wand.images;
4803 node->next = cli_wand->image_list_stack;
4804 cli_wand->image_list_stack = node;
4805 cli_wand->wand.images = NewImageList();
4807 /* handle respect-parenthesis */
4808 if (IsStringTrue(GetImageOption(cli_wand->wand.image_info,
4809 "respect-parenthesis")) != MagickFalse)
4810 option="{"; /* fall-thru so as to push image settings too */
4813 /* fall thru to operation */
4815 if (LocaleCompare("{",option) == 0) {
4816 /* stack 'push' of image_info settings */
4824 node=cli_wand->image_info_stack;
4825 for ( ; node != (Stack *) NULL; node=node->next)
4827 if ( size >= MAX_STACK_DEPTH )
4828 CLIWandExceptionBreak(OptionError,"CurlyBracesNestedTooDeeply",option);
4829 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4830 if (node == (Stack *) NULL)
4831 CLIWandExceptionBreak(ResourceLimitFatalError,
4832 "MemoryAllocationFailed",option);
4834 node->data = (void *)cli_wand->wand.image_info;
4835 node->next = cli_wand->image_info_stack;
4837 cli_wand->image_info_stack = node;
4838 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
4839 if (cli_wand->wand.image_info == (ImageInfo *) NULL) {
4840 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4842 cli_wand->wand.image_info = (ImageInfo *)node->data;
4843 node = (Stack *)RelinquishMagickMemory(node);
4849 if (LocaleCompare(")",option) == 0) {
4850 /* pop images from stack */
4854 node = (Stack *)cli_wand->image_list_stack;
4855 if ( node == (Stack *) NULL)
4856 CLIWandExceptionBreak(OptionError,"UnbalancedParenthesis",option);
4857 cli_wand->image_list_stack = node->next;
4859 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4860 cli_wand->wand.images= (Image *)node->data;
4861 node = (Stack *)RelinquishMagickMemory(node);
4863 /* handle respect-parenthesis - of the previous 'pushed' settings */
4864 node = cli_wand->image_info_stack;
4865 if ( node != (Stack *) NULL)
4867 if (IsStringTrue(GetImageOption(
4868 cli_wand->wand.image_info,"respect-parenthesis")) != MagickFalse)
4869 option="}"; /* fall-thru so as to pop image settings too */
4875 /* fall thru to next if */
4877 if (LocaleCompare("}",option) == 0) {
4878 /* pop image_info settings from stack */
4882 node = (Stack *)cli_wand->image_info_stack;
4883 if ( node == (Stack *) NULL)
4884 CLIWandExceptionBreak(OptionError,"UnbalancedCurlyBraces",option);
4885 cli_wand->image_info_stack = node->next;
4887 (void) DestroyImageInfo(cli_wand->wand.image_info);
4888 cli_wand->wand.image_info = (ImageInfo *)node->data;
4889 node = (Stack *)RelinquishMagickMemory(node);
4891 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4892 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4893 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4897 if (LocaleCompare("print",option+1) == 0)
4899 (void) FormatLocaleFile(stdout,"%s",arg1);
4902 if (LocaleCompare("set",option+1) == 0)
4904 /* Settings are applied to each image in memory in turn (if any).
4905 While a option: only need to be applied once globally.
4907 NOTE: rguments have not been automatically percent expaneded
4910 /* escape the 'key' once only, using first image. */
4911 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
4912 if (arg1 == (char *) NULL)
4913 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
4916 if (LocaleNCompare(arg1,"registry:",9) == 0)
4920 (void) DeleteImageRegistry(arg1+9);
4921 arg1=DestroyString((char *)arg1);
4924 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4925 if (arg2 == (char *) NULL) {
4926 arg1=DestroyString((char *)arg1);
4927 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
4930 (void) SetImageRegistry(StringRegistryType,arg1+9,arg2,_exception);
4931 arg1=DestroyString((char *)arg1);
4932 arg2=DestroyString((char *)arg2);
4935 if (LocaleNCompare(arg1,"option:",7) == 0)
4937 /* delete equivelent artifact from all images (if any) */
4938 if (_images != (Image *) NULL)
4940 MagickResetIterator(&cli_wand->wand);
4941 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
4942 (void) DeleteImageArtifact(_images,arg1+7);
4943 MagickResetIterator(&cli_wand->wand);
4945 /* now set/delete the global option as needed */
4946 /* FUTURE: make escapes in a global 'option:' delayed */
4950 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4951 if (arg2 == (char *) NULL)
4952 CLIWandExceptionBreak(OptionWarning,
4953 "InterpretPropertyFailure",option);
4955 (void) SetImageOption(_image_info,arg1+7,arg2);
4956 arg1=DestroyString((char *)arg1);
4957 arg2=DestroyString((char *)arg2);
4960 /* Set Artifacts/Properties/Attributes all images (required) */
4961 if ( _images == (Image *) NULL )
4962 CLIWandExceptArgBreak(OptionWarning,"NoImageForProperty",option,arg1);
4964 MagickResetIterator(&cli_wand->wand);
4965 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
4970 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4971 if (arg2 == (char *) NULL)
4972 CLIWandExceptionBreak(OptionWarning,
4973 "InterpretPropertyFailure",option);
4975 if (LocaleNCompare(arg1,"artifact:",9) == 0)
4976 (void) SetImageArtifact(_images,arg1+9,arg2);
4977 else if (LocaleNCompare(arg1,"property:",9) == 0)
4978 (void) SetImageProperty(_images,arg1+9,arg2,_exception);
4980 (void) SetImageProperty(_images,arg1,arg2,_exception);
4981 arg2=DestroyString((char *)arg2);
4983 MagickResetIterator(&cli_wand->wand);
4984 arg1=DestroyString((char *)arg1);
4987 if (LocaleCompare("clone",option+1) == 0) {
4992 arg1=AcquireString("-1");
4993 if (IsSceneGeometry(arg1,MagickFalse) == MagickFalse)
4994 CLIWandExceptionBreak(OptionError,"InvalidArgument",option);
4995 if ( cli_wand->image_list_stack == (Stack *) NULL)
4996 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
4997 new_images = (Image *)cli_wand->image_list_stack->data;
4998 if (new_images == (Image *) NULL)
4999 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
5000 new_images=CloneImages(new_images,arg1,_exception);
5001 if (new_images == (Image *) NULL)
5002 CLIWandExceptionBreak(OptionError,"NoSuchImage",option);
5003 AppendImageToList(&_images,new_images);
5007 Informational Operations.
5009 Note that these do not require either a cli-wand or images!
5010 Though currently a cli-wand much be provided regardless.
5012 if (LocaleCompare("version",option+1) == 0)
5014 ListMagickVersion(stdout);
5017 if (LocaleCompare("list",option+1) == 0) {
5019 FUTURE: This 'switch' should really be part of MagickCore
5024 list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
5026 CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
5031 case MagickCoderOptions:
5033 (void) ListCoderInfo((FILE *) NULL,_exception);
5036 case MagickColorOptions:
5038 (void) ListColorInfo((FILE *) NULL,_exception);
5041 case MagickConfigureOptions:
5043 (void) ListConfigureInfo((FILE *) NULL,_exception);
5046 case MagickDelegateOptions:
5048 (void) ListDelegateInfo((FILE *) NULL,_exception);
5051 case MagickFontOptions:
5053 (void) ListTypeInfo((FILE *) NULL,_exception);
5056 case MagickFormatOptions:
5057 (void) ListMagickInfo((FILE *) NULL,_exception);
5059 case MagickLocaleOptions:
5060 (void) ListLocaleInfo((FILE *) NULL,_exception);
5062 case MagickLogOptions:
5063 (void) ListLogInfo((FILE *) NULL,_exception);
5065 case MagickMagicOptions:
5066 (void) ListMagicInfo((FILE *) NULL,_exception);
5068 case MagickMimeOptions:
5069 (void) ListMimeInfo((FILE *) NULL,_exception);
5071 case MagickModuleOptions:
5072 (void) ListModuleInfo((FILE *) NULL,_exception);
5074 case MagickPolicyOptions:
5075 (void) ListPolicyInfo((FILE *) NULL,_exception);
5077 case MagickResourceOptions:
5078 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
5080 case MagickThresholdOptions:
5081 (void) ListThresholdMaps((FILE *) NULL,_exception);
5084 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
5091 CLIWandException(OptionError,"UnrecognizedOption",option);
5093 DisableMSCWarning(4127)
5094 } while (0); /* break to exit code. */
5097 /* clean up percent escape interpreted strings */
5099 arg1=DestroyString((char *)arg1);
5101 arg2=DestroyString((char *)arg2);
5111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5115 + C L I O p t i o n %
5119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5121 % CLIOption() Processes the given option using the given CLI Magick Wand.
5122 % The option arguments can be variable in number, though at this time no more
5123 % that two is actually used by any option (this may change). Excess options
5124 % are simply ignored.
5126 % If the cli_wand->command pointer is non-null, then it is assumed that the
5127 % option has already been search for up from the CommandOptions[] table in
5128 % "MagickCore/options.c" using GetCommandOptionInfo(). If not set this
5129 % routine will do the lookup instead. The pointer is reset afterward.
5131 % This action allows the caller to lookup and pre-handle any 'special'
5132 % options, (such as implicit reads) before calling this general option
5133 % handler to deal with 'standard' command line options.
5135 % The format of the CLIOption method is:
5137 % void CLIOption(MagickCLI *cli_wand,const char *option, ...)
5139 % A description of each parameter follows:
5141 % o cli_wand: the main CLI Wand to use.
5143 % o option: The special option (with any switch char) to process
5145 % o args: any required arguments for an option (variable number)
5149 % CLIoption(cli_wand,"-read","rose:");
5150 % CLIoption(cli_wand,"-virtual-pixel","transparent");
5151 % CLIoption(cli_wand,"-distort","SRT:","30");
5152 % CLIoption(cli_wand,"-write","rotated_rose.png");
5155 WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
5157 const char /* extracted option args from args */
5164 assert(cli_wand != (MagickCLI *) NULL);
5165 assert(cli_wand->signature == MagickWandSignature);
5166 assert(cli_wand->wand.signature == MagickWandSignature);
5168 do { /* Break Code Block for error handling */
5170 /* get information about option */
5171 if ( cli_wand->command == (const OptionInfo *) NULL )
5172 cli_wand->command = GetCommandOptionInfo(option);
5174 (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
5175 option, cli_wand->command->mnemonic );
5177 option_type=(CommandOptionFlags) cli_wand->command->flags;
5179 if ( option_type == UndefinedOptionFlag )
5180 CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
5182 assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
5184 /* deprecated options */
5185 if ( (option_type & DeprecateOptionFlag) != 0 )
5186 CLIWandExceptionBreak(OptionError,"DeprecatedOptionNoCode",option);
5188 /* options that this module does not handle */
5189 if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
5190 CLIWandExceptionBreak(OptionFatalError,"InvalidUseOfOption",option);
5192 /* Get argument strings from VarArgs
5193 How can you determine if enough arguments was supplied?
5194 What happens if not enough arguments were supplied?
5197 count = (size_t) cli_wand->command->type;
5202 va_start(operands,option);
5206 arg1=(const char *) va_arg(operands, const char *);
5208 arg2=(const char *) va_arg(operands, const char *);
5212 (void) FormatLocaleFile(stderr,
5213 "CLIOption: \"%s\" Count: %ld Flags: %04x Args: \"%s\" \"%s\"\n",
5214 option,(long) count,option_type,arg1,arg2);
5219 Call the appropriate option handler
5222 /* FUTURE: this is temporary - get 'settings' to handle distribution of
5223 settings to images attributes,proprieties,artifacts */
5224 if ( cli_wand->wand.images != (Image *) NULL )
5225 (void) SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
5226 cli_wand->wand.exception);
5228 if ( (option_type & SettingOptionFlags) != 0 ) {
5229 CLISettingOptionInfo(cli_wand, option, arg1, arg2);
5230 // FUTURE: Sync Specific Settings into Image Properities (not global)
5233 /* Operators that do not need images - read, write, stack, clone */
5234 if ((option_type & NoImageOperatorFlag) != 0)
5235 CLINoImageOperator(cli_wand, option, arg1, arg2);
5237 /* FUTURE: The not a setting part below is a temporary hack due to
5238 * some options being both a Setting and a Simple operator.
5239 * Specifically -monitor, -depth, and -colorspace */
5240 if ( cli_wand->wand.images == (Image *) NULL )
5241 if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
5242 ((option_type & SettingOptionFlags) == 0 )) /* temp hack */
5243 CLIWandExceptionBreak(OptionError,"NoImagesFound",option);
5245 /* Operators which loop of individual images, simply */
5246 if ( (option_type & SimpleOperatorFlag) != 0 &&
5247 cli_wand->wand.images != (Image *) NULL) /* temp hack */
5249 ExceptionInfo *exception=AcquireExceptionInfo();
5250 (void) CLISimpleOperatorImages(cli_wand, option, arg1, arg2,exception);
5251 exception=DestroyExceptionInfo(exception);
5254 /* Operators that work on the image list as a whole */
5255 if ( (option_type & ListOperatorFlag) != 0 )
5256 (void) CLIListOperatorImages(cli_wand, option, arg1, arg2);
5258 DisableMSCWarning(4127)
5259 } while (0); /* end Break code block */
5262 cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */