2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % OOO PPPP EEEE RRRR AA TTTTTT III OOO N N %
7 % O O P P E R R A A TT I O O NN N %
8 % O O PPPP EEE RRRR AAAA TT I O O N N N %
9 % O O P E R R A A TT I O O N NN %
10 % OOO P EEEE R RR A A TT III OOO N N %
13 % MagickWand Module Methods %
20 % Copyright 1999-2011 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" and "draw_info"
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, Sept 2011
51 #include "MagickWand/studio.h"
52 #include "MagickWand/MagickWand.h"
53 #include "MagickWand/mogrify-private.h"
54 #include "MagickCore/monitor-private.h"
55 #include "MagickCore/thread-private.h"
56 #include "MagickCore/string-private.h"
61 #define UndefinedCompressionQuality 0UL
63 Constant declaration. (temporary exports)
66 BackgroundColor[] = "#fff", /* white */
67 BorderColor[] = "#dfdfdf", /* gray */
68 MatteColor[] = "#bdbdbd"; /* gray */
71 ** Function to report on the progress of image operations
73 static MagickBooleanType MonitorProgress(const char *text,
74 const MagickOffsetType offset,const MagickSizeType extent,
75 void *wand_unused(client_data))
78 message[MaxTextExtent],
89 (void) CopyMagickMemory(tag,text,MaxTextExtent);
91 if (p != (char *) NULL)
93 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
94 locale_message=GetLocaleMessage(message);
95 if (locale_message == message)
97 if (p == (char *) NULL)
98 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
99 locale_message,(long) offset,(unsigned long) extent,(long)
100 (100L*offset/(extent-1)));
102 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
103 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
104 (100L*offset/(extent-1)));
105 if (offset == (MagickOffsetType) (extent-1))
106 (void) FormatLocaleFile(stderr,"\n");
107 (void) fflush(stderr);
112 ** GetImageCache() will read an image into a image cache if not already
113 ** present then return the image that is in the cache under that filename.
115 static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
116 ExceptionInfo *exception)
130 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
131 sans_exception=AcquireExceptionInfo();
132 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
133 sans_exception=DestroyExceptionInfo(sans_exception);
134 if (image != (Image *) NULL)
136 read_info=CloneImageInfo(image_info);
137 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
138 image=ReadImage(read_info,exception);
139 read_info=DestroyImageInfo(read_info);
140 if (image != (Image *) NULL)
141 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
146 SparseColorOption() parse the complex -sparse-color argument into an
147 an array of floating point values than call SparseColorImage().
148 Argument is a complex mix of floating-point pixel coodinates, and color
149 specifications (or direct floating point numbers). The number of floats
150 needed to represent a color varies depending on teh current channel
153 static Image *SparseColorOption(const Image *image,
154 const SparseColorMethod method,const char *arguments,
155 const MagickBooleanType color_from_image,ExceptionInfo *exception)
158 token[MaxTextExtent];
182 assert(image != (Image *) NULL);
183 assert(image->signature == MagickSignature);
184 if (image->debug != MagickFalse)
185 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
186 assert(exception != (ExceptionInfo *) NULL);
187 assert(exception->signature == MagickSignature);
189 Limit channels according to image - and add up number of color channel.
192 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
194 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
196 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
198 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
199 (image->colorspace == CMYKColorspace))
201 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
202 (image->matte != MagickFalse))
206 Read string, to determine number of arguments needed,
212 GetMagickToken(p,&p,token);
213 if ( token[0] == ',' ) continue;
214 if ( isalpha((int) token[0]) || token[0] == '#' ) {
215 if ( color_from_image ) {
216 (void) ThrowMagickException(exception,GetMagickModule(),
217 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
218 "Color arg given, when colors are coming from image");
219 return( (Image *)NULL);
221 x += number_colors; /* color argument */
224 x++; /* floating point argument */
228 if ( color_from_image ) {
229 /* just the control points are being given */
230 error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse;
231 number_arguments=(x/2)*(2+number_colors);
234 /* control points and color values */
235 error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
239 (void) ThrowMagickException(exception,GetMagickModule(),
240 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
241 "Invalid number of Arguments");
242 return( (Image *)NULL);
245 /* Allocate and fill in the floating point arguments */
246 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
247 sizeof(*sparse_arguments));
248 if (sparse_arguments == (double *) NULL) {
249 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
250 "MemoryAllocationFailed","%s","SparseColorOption");
251 return( (Image *)NULL);
253 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
254 sizeof(*sparse_arguments));
257 while( *p != '\0' && x < number_arguments ) {
259 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
260 if ( token[0] == '\0' ) break;
261 if ( isalpha((int) token[0]) || token[0] == '#' ) {
262 (void) ThrowMagickException(exception,GetMagickModule(),
263 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
264 "Color found, instead of X-coord");
268 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
270 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
271 if ( token[0] == '\0' ) break;
272 if ( isalpha((int) token[0]) || token[0] == '#' ) {
273 (void) ThrowMagickException(exception,GetMagickModule(),
274 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
275 "Color found, instead of Y-coord");
279 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
280 /* color values for this control point */
282 if ( (color_from_image ) {
283 /* get color from image */
289 /* color name or function given in string argument */
290 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
291 if ( token[0] == '\0' ) break;
292 if ( isalpha((int) token[0]) || token[0] == '#' ) {
293 /* Color string given */
294 (void) 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->matte != MagickFalse))
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] == ',' ) GetMagickToken(p,&p,token);
315 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
317 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
318 token[0] = ','; /* used this token - get another */
320 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
322 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
323 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
325 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
326 token[0] = ','; /* used this token - get another */
328 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
330 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
331 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
333 sparse_arguments[x++]=InterpretLocaleValue(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] == ',' ) GetMagickToken(p,&p,token);
340 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
342 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
343 token[0] = ','; /* used this token - get another */
345 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
346 (image->matte != MagickFalse))
348 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
349 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
351 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
352 token[0] = ','; /* used this token - get another */
357 if ( number_arguments != x && !error ) {
358 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
359 "InvalidArgument","`%s': %s","sparse-color","Argument Parsing Error");
360 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
361 return( (Image *)NULL);
364 return( (Image *)NULL);
366 /* Call the Interpolation function with the parsed arguments */
367 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
369 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
370 return( sparse_image );
374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378 + A p p l y S e t t i n g O p t i o n %
382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384 % ApplySettingOption() saves the given single settings option into a CLI wand
385 % holding the image_info, draw_info, quantize_info structures that is later
386 % used for reading, processing, and writing images.
388 % No image in the wand is actually modified (setting options only)
390 % The format of the ApplySettingOption method is:
392 % MagickBooleanType ApplySettingOption(MagickWand *wand,
393 % const int argc, const char **argv,ExceptionInfo *exception)
395 % A description of each parameter follows:
397 % o wand: structure holding settings to be applied
399 % o argc: Specifies a pointer to an integer describing the number of
400 % elements in the argument vector.
402 % o argv: Specifies a pointer to a text array containing the command line
405 % o exception: return any errors or warnings in this structure.
408 WandExport MagickBooleanType ApplySettingsOption(ImageInfo *image_info,
409 const int argc,const char **argv,ExceptionInfo *exception)
423 assert(wand != (MagickWand *) NULL);
424 assert(wand->signature == WandSignature);
425 assert(wand->draw_info != (DrawInfo *) NULL); /* ensure it is a CLI wand */
426 assert(wand->quantize_info == (QuantizeInfo *) NULL);
427 if (wand->debug != MagickFalse)
428 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
433 image_info=wand->image_info;
434 draw_info=wand->_info;
436 #define IfSetOption ((*argv[0])=='-')
442 if (LocaleCompare("adjoin",option) == 0)
444 image_info->adjoin = IfSetOption ? MagickTrue : MagickFalse;
447 if (LocaleCompare("affine",option) == 0)
450 (void) ParseAffineGeometry(argv[1],draw_info->affine,
453 GetAffineMatrix(draw_info->affine);
456 if (LocaleCompare("antialias",option) == 0)
458 image_info->antialias =
459 draw_info->stroke_antialias =
460 draw_info->text_antialias =
461 IfSetOption ? MagickTrue : MagickFalse;
464 if (LocaleCompare("authenticate",option) == 0)
466 (void) SetImageOption(image_info,option,
467 IfSetOption ? argv[1] : (const char*)NULL);
474 if (LocaleCompare("background",option) == 0)
476 /* FUTURE: both image_info attribute & ImageOption in use!
477 Note that +background, means fall-back to image attribute
478 so ImageOption is deleted, not set to a default.
482 (void) DeleteImageOption(image_info,option);
483 (void) QueryColorCompliance(BackgroundColor,AllCompliance,
484 image_info->background_color,exception);
487 (void) SetImageOption(image_info,option,argv[1]);
488 (void) QueryColorCompliance(argv[1],AllCompliance,
489 image_info->background_color,exception);
492 if (LocaleCompare("bias",option) == 0)
494 /* FUTURE: bias OBSOLETED, replaced by "convolve:bias"
495 as it is actually rarely used except in direct convolve
496 Usage outside direct convolve is actally non-sensible!
498 (void) SetImageOption(image_info,option,
499 IfSetOption ? argv[1] : "0");
502 if (LocaleCompare("black-point-compensation",option) == 0)
504 (void) SetImageOption(image_info,option,
505 IfSetOption ? "true" : "false" );
508 if (LocaleCompare("blue-primary",option) == 0)
510 /* Image chromaticity X,Y NB: Y=X if Y not defined
513 (void) SetImageOption(image_info,option,
514 IfSetOption ? argv[1] : "0" );
517 if (LocaleCompare("bordercolor",option) == 0)
519 /* FUTURE: both image_info attribute & ImageOption in use! */
522 (void) SetImageOption(image_info,option,argv[1]);
523 (void) QueryColorCompliance(argv[1],AllCompliece,
524 &image_info->border_color,exception);
525 (void) QueryColorCompliance(argv[1],AllCompliance,
526 &draw_info->border_color,exception);
529 (void) DeleteImageOption(image_info,option);
530 (void) QueryColorCompliance(BorderColor,AllCompliance,
531 &image_info->border_color,exception);
532 (void) QueryColorCompliance(BorderColor,AllCompliance,
533 &draw_info->border_color,exception);
536 if (LocaleCompare("box",option) == 0)
539 *value = IfSetOption ? argv[1] : "none";
540 (void) SetImageOption(image_info,option,value);
541 (void) QueryColorCompliance(value,AllCompliance,
542 &draw_info->undercolor,exception);
549 if (LocaleCompare("cache",option) == 0)
554 limit=MagickResourceInfinity;
555 if (LocaleCompare("unlimited",argv[1]) != 0)
556 limit=(MagickSizeType) SiPrefixToDouble(argv[1],100.0);
557 (void) SetMagickResourceLimit(MemoryResource,limit);
558 (void) SetMagickResourceLimit(MapResource,2*limit);
561 if (LocaleCompare("caption",option) == 0)
563 /* Only used for new images via AquireImage() */
564 (void) SetImageOption(image_info,option,
565 IfSetOption ? argv[1] : (const char*)NULL);
568 if (LocaleCompare("channel",option) == 0)
570 image_info->channel=(ChannelType) (
571 IfSetOption ? ParseChannelOption(argv[1]) : DefaultChannels );
572 /* FUTURE: This is also a SimpleImageOperator!!! */
575 if (LocaleCompare("colorspace",option) == 0)
577 /* Setting for new images, and for existing images */
578 /* This is also a SimpleImageOperator */
579 /* Undefined colorspace means don't modify images */
580 image_info->colorspace=UndefinedColorspace;
582 image_info->colorspace=(ColorspaceType) ParseCommandOption(
583 MagickColorspaceOptions,MagickFalse,argv[1])
586 if (LocaleCompare("comment",option) == 0)
588 /* Only used for new images via AquireImage() */
589 (void) SetImageOption(image_info,option,
590 IfSetOption ? argv[1] : (const char*)NULL);
593 if (LocaleCompare("compose",option) == 0)
595 /* FUTURE: image_info should be used, Option for escapes
596 This option should NOT be used to set image 'compose'
597 which is used by "-layer" operators is image_info is undefined
599 (void) SetImageOption(image_info,option,
600 IfSetOption ? argv[1] : (const char*)NULL);
601 image_info->compose=(CompositeOperator) ParseCommandOption(
602 MagickComposeOptions,MagickFalse,
603 IfSetOption ? argv[1] : "undefined");
606 if (LocaleCompare("compress",option) == 0)
608 /* FUTURE: What should be used? image_info or ImageOption ???
609 The former is more efficent, but Crisy prefers the latter!
611 The coders appears to use image_info, not Image_Option
612 however the image attribute (for save) is set from the
617 image_info->compression=(CompressionType) ParseCommandOption(
618 MagickCompressOptions,MagickFalse,argv[1]);
619 (void) SetImageOption(image_info,option,argv[1]);
622 image_info->compression=UndefinedCompression;
623 (void) SetImageOption(image_info,option,"undefined");
630 if (LocaleCompare("debug",option) == 0)
633 (void) SetLogEventMask(IfSetOption?argv[1]:"none");
634 image_info->debug=IsEventLogging(); /* extract logging*/
635 wand->debug=IsEventLogging();
638 if (LocaleCompare("define",option) == 0)
640 /* FUTURE both -set and -define sets ImageOption
641 But differs in that -set tried to set image properity (attribute)
643 if (LocaleNCompare(argv[1],"registry:",9) == 0)
646 (void) DefineImageRegistry(StringRegistryType,argv[1]+9,
649 (void) DefineImageOption(image_info,argv[1],exception);
653 (void) DefineImageOption(image_info,argv[1],exception);
655 (void) DeleteImageOption(image_info,argv[1],exception);
658 if (LocaleCompare("delay",option) == 0)
660 /* Only used for new images via AcquireImage()
661 Option should also be used for "-morph" (color morphong)
663 (void) SetImageOption(image_info,option,
664 IfSetOption ? argv[1] : "0");
667 if (LocaleCompare("density",option) == 0)
669 /* Used by both draw_info and in images via SyncImageSettings() */
672 (void) CloneString(&image_info->density,argv[1]);
673 (void) CloneString(&draw_info->density,argv[1]);
674 (void) SetImageOption(image_info,option,argv[1]);
677 if (image_info->density != (char *) NULL)
678 image_info->density=DestroyString(image_info->density);
679 if (draw_info->density != (char *) NULL)
680 draw_info->density=DestroyString(draw_info->density);
681 (void) SetImageOption(image_info,option,"72");
684 if (LocaleCompare("depth",option) == 0)
686 /* This is also a SimpleImageOperator! */
687 image_info->depth=IsSetOption?StringToUnsignedLong(argv[1])
688 :MAGICKCORE_QUANTUM_DEPTH;
691 if (LocaleCompare("direction",option) == 0)
693 /* Image Option is only used to set draw_info */
694 (void) SetImageOption(image_info,option,
695 IfSetOption ? argv[1] : "undefined");
696 draw_info->direction=(DirectionType) ParseCommandOption(
697 MagickDirectionOptions,MagickFalse,
698 IfSetOption ? argv[1] : "undefined");
701 if (LocaleCompare("display",option) == 0)
704 (void) CloneString(&image_info->server_name,argv[1]);
706 if (image_info->server_name != (char *) NULL)
707 image_info->server_name=DestroyString(image_info->server_name);
710 if (LocaleCompare("dispose",option) == 0)
712 (void) SetImageOption(image_info,option,
713 IfSetOption ? argv[1] : "undefined");
716 if (LocaleCompare("dither",option) == 0)
718 /* FUTURE: Merge boolean image_info->dither with Dither type */
719 (void) SetImageOption(image_info,option,
720 IfSetOption ? argv[1] : "none");
721 image_info->dither = quantize_info->dither =
722 IfSetOption ? MagickTrue : MagickFalse;
723 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
724 MagickDitherOptions,MagickFalse,
725 IfSetOption ? argv[1] : "none");
726 if (quantize_info->dither_method == NoDitherMethod)
727 image_info->dither = quantize_info->dither = MagickFalse;
734 if (LocaleCompare("encoding",option) == 0)
736 (void) CloneString(&draw_info->encoding,
737 IfSetOption ? argv[1] : "undefined");
738 (void) SetImageOption(image_info,option,&draw_info->encoding);
741 if (LocaleCompare("endian",option) == 0)
746 value=IfSetOption?argv[1]:"undefined";
747 (void) SetImageOption(image_info,option,value);
748 image_info->endian=(EndianType) ParseCommandOption(
749 MagickEndianOptions,MagickFalse,value);
752 if (LocaleCompare("extract",option) == 0)
754 (void) CloneString(&image_info->extract,
755 IfSetOption?argv[1]:(const char *) NULL);
762 if (LocaleCompare("family",argv[0]+1) == 0)
764 (void) CloneString(&draw_info->family,
765 IfSetOption ? argv[1] : (const char *) NULL);
768 if (LocaleCompare("fill",option) == 0)
770 /* set fill OR a fill-pattern */
771 /* FUTURE: tile is only set in draw_info, not in image_info ! */
778 value = IfSetOption ? argv[1] : "none";
779 (void) SetImageOption(image_info,option,value);
781 sans=AcquireExceptionInfo();
782 status=QueryColorCompliance(value,AllCompliance,&draw_info->fill,sans);
783 sans=DestroyExceptionInfo(sans);
785 if (draw_info->fill_pattern != (Image *) NULL)
786 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
787 if (status == MagickFalse)
788 draw_info->fill_pattern=GetImageCache(image_info,value,
792 if (LocaleCompare("filter",option) == 0)
794 (void) SetImageOption(image_info,option,
795 IfSetOption ? argv[1] : "undefined");
798 if (LocaleCompare("font",option) == 0)
800 (void) CloneString(&draw_info->font,
801 IfSetOption ? argv[1] : (const char *) NULL);
802 (void) CloneString(&image_info->font,draw_info->font);
805 if (LocaleCompare("format",option) == 0)
807 /* FUTURE: why the ping test, you could set ping after this! */
812 for (q=strchr(argv[1],'%'); q != (char *) NULL; q=strchr(q+1,'%'))
813 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
814 image_info->ping=MagickFalse;
816 (void) SetImageOption(image_info,option,
817 IfSetOption ? argv[1] : (const char *) NULL);
820 if (LocaleCompare("fuzz",option) == 0)
822 /* FUTURE: image_info and ImageOption!
823 Option used to set image fuzz! unless blank canvas (from color)
824 Image attribute used for color compare operations
825 image->fuzz is being set by SyncImageSettings()
826 Can't find anything making use of image_info->fuzz
828 (void) SetImageOption(image_info,option,
829 IfSetOption ? argv[1] : (const char *) NULL);
831 image_info->fuzz=SiPrefixToDouble(argv[1],(double) QuantumRange+1.0);
833 image_info->fuzz=0.0;
840 if (LocaleCompare("gravity",option) == 0)
842 /* FUTURE gravity also set in image via SyncImageSettings() */
846 value = IfSetOption ? argv[1] : "none";
847 (void) SetImageOption(image_info,option,value);
848 draw_info->gravity=(GravityType) ParseCommandOption(
849 MagickGravityOptions,MagickFalse,value);
852 if (LocaleCompare("green-primary",option) == 0)
854 /* Image chromaticity X,Y NB: Y=X if Y not defined
857 (void) SetImageOption(image_info,option,
858 IfSetOption ? argv[1] : "0.0");
865 if (LocaleCompare("intent",option) == 0)
867 /* FUTURE: this should also set image->rendering_intent
868 Which is only used by coders: MIFF, MPC, BMP, PNG
869 and for image profile call to AcquireTransformThreadSet()
871 (void) SetImageOption(image_info,option,
872 IfSetOption ? argv[1] : "undefined");
875 if (LocaleCompare("interlace",option) == 0)
877 /* sets image attibute interlace via SyncImageSettings()
878 Also image_info is directly used by coders
883 value = IfSetOption ? argv[1] : "undefined";
884 (void) SetImageOption(image_info,option, value);
885 image_info->interlace=(InterlaceType) ParseCommandOption(
886 MagickInterlaceOptions,MagickFalse,value);
889 if (LocaleCompare("interline-spacing",option) == 0)
894 value = IfSetOption ? argv[1] : "0"; /* undefined? */
895 (void) SetImageOption(image_info,option, value);
896 draw_info->interline_spacing=InterpretLocaleValue(value,
900 if (LocaleCompare("interpolate",option) == 0)
902 /* FUTURE: sets image interpolate value via SyncImageSettings()
903 It is NOT used by coders, only in image processing,
904 so shoud really be a image_info attribute.
906 (void) SetImageOption(image_info,option,
907 IfSetOption ? argv[1] : "undefined");
910 if (LocaleCompare("interword-spacing",argv[0]+1) == 0)
915 value = IfSetOption ? argv[1] : "0"; /* undefined? */
916 (void) SetImageOption(image_info,option, value);
917 draw_info->interword_spacing=InterpretLocaleValue(value,
925 if (LocaleCompare("kerning",option) == 0)
930 value = IfSetOption ? argv[1] : "0"; /* undefined? */
931 (void) SetImageOption(image_info,option, value);
932 draw_info->kerning=InterpretLocaleValue(value,(char **) NULL);
939 if (LocaleCompare("label",option) == 0)
941 /* only used for new images */
942 (void) SetImageOption(image_info,option,
943 IfSetOption ? argv[1] : (char *)NULL);
946 if (LocaleCompare("limit",option) == 0)
956 type=(ResourceType) ParseCommandOption(MagickResourceOptions,
957 MagickFalse,argv[1]);
958 limit=MagickResourceInfinity;
959 if (LocaleCompare("unlimited",argv[2]) != 0)
960 limit=(MagickSizeType) SiPrefixToDouble(argv[2],100.0);
961 (void) SetMagickResourceLimit(type,limit);
964 if (LocaleCompare("linewidth",argv[0]+1) == 0)
966 /* FUTURE: obsoleted by stroke-width setting */
967 draw_info->stroke_width=InterpretLocaleValue(argv[1],
971 if (LocaleCompare("list",option) == 0)
976 list=ParseCommandOption(MagickListOptions,MagickFalse,argv[1]);
979 case MagickCoderOptions:
981 (void) ListCoderInfo((FILE *) NULL,exception);
984 case MagickColorOptions:
986 (void) ListColorInfo((FILE *) NULL,exception);
989 case MagickConfigureOptions:
991 (void) ListConfigureInfo((FILE *) NULL,exception);
994 case MagickDelegateOptions:
996 (void) ListDelegateInfo((FILE *) NULL,exception);
999 case MagickFontOptions:
1001 (void) ListTypeInfo((FILE *) NULL,exception);
1004 case MagickFormatOptions:
1006 (void) ListMagickInfo((FILE *) NULL,exception);
1009 case MagickLocaleOptions:
1011 (void) ListLocaleInfo((FILE *) NULL,exception);
1014 case MagickLogOptions:
1016 (void) ListLogInfo((FILE *) NULL,exception);
1019 case MagickMagicOptions:
1021 (void) ListMagicInfo((FILE *) NULL,exception);
1024 case MagickMimeOptions:
1026 (void) ListMimeInfo((FILE *) NULL,exception);
1029 case MagickModuleOptions:
1031 (void) ListModuleInfo((FILE *) NULL,exception);
1034 case MagickPolicyOptions:
1036 (void) ListPolicyInfo((FILE *) NULL,exception);
1039 case MagickResourceOptions:
1041 (void) ListMagickResourceInfo((FILE *) NULL,exception);
1044 case MagickThresholdOptions:
1046 (void) ListThresholdMaps((FILE *) NULL,exception);
1051 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
1058 if (LocaleCompare("log",option) == 0)
1061 (void) SetLogFormat(argv[1]);
1064 if (LocaleCompare("loop",option) == 0)
1066 /* Sets image attibutes iterations via SyncImageSettings() */
1067 (void) SetImageOption(image_info,option,
1068 IfSetOption ? argv[1] : "0");
1075 if (LocaleCompare("mattecolor",option) == 0)
1077 (void) SetImageOption(image_info,option,argv[1]);
1078 (void) QueryColorCompliance(argv[1],AllCompliance,
1079 &image_info->matte_color,exception);
1082 if (LocaleCompare("monitor",option) == 0)
1084 (void) SetImageInfoProgressMonitor(image_info,MonitorProgress,
1088 if (LocaleCompare("monochrome",option) == 0)
1090 /* Setting (for input coders) and a 'type' operation */
1091 image_info->monochrome=IsSetOption ? MagickTrue : MagickFalse;
1098 if (LocaleCompare("orient",option) == 0)
1100 /* Sets image attribute orientation via SyncImageSettings()
1101 Is not used when defining for new images.
1102 This makes it more of a 'operation' than a setting
1107 value = IfSetOption ? argv[1] : "undefined";
1108 (void) SetImageOption(image_info,option, value);
1109 image_info->orientation=(InterlaceType) ParseCommandOption(
1110 MagickOrientationOptions,MagickFalse,value);
1116 if (LocaleCompare("page",option) == 0)
1118 /* Only used for new images and image generators */
1121 page[MaxTextExtent];
1134 (void) DeleteImageOption(image_info,option);
1135 (void) CloneString(&image_info->page,(char *) NULL);
1138 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
1139 image_option=GetImageOption(image_info,"page");
1140 if (image_option != (const char *) NULL)
1141 flags=ParseAbsoluteGeometry(image_option,&geometry);
1142 canonical_page=GetPageGeometry(argv[1]);
1143 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1144 canonical_page=DestroyString(canonical_page);
1145 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1146 (unsigned long) geometry.width,(unsigned long) geometry.height);
1147 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1148 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1149 (unsigned long) geometry.width,(unsigned long) geometry.height,
1150 (long) geometry.x,(long) geometry.y);
1151 (void) SetImageOption(image_info,option,page);
1152 (void) CloneString(&image_info->page,page);
1155 if (LocaleCompare("ping",option) == 0)
1157 image_info->ping=(*argv[0] == '-') ? MagickTrue : MagickFalse;
1160 if (LocaleCompare("pointsize",option) == 0)
1166 InterpretLocaleValue(argv[1],(char **) NULL);
1167 image_info->pointsize=draw_info->pointsize=value;
1170 if (LocaleCompare("precision",option) == 0)
1172 (void) SetMagickPrecision(StringToInteger(argv[1]));
1175 /* FUTURE: Only the 'preview' coder appears to use this
1176 * Depreciate the coder? Leaving only the 'preview' operator.
1177 if (LocaleCompare("preview",option) == 0)
1179 image_info->preview_type=UndefinedPreview;
1181 image_info->preview_type=(PreviewType) ParseCommandOption(
1182 MagickPreviewOptions,MagickFalse,argv[1]);
1190 if (LocaleCompare("quality",option) == 0)
1194 image_info->quality=StringToUnsignedLong(argv[1]);
1195 (void) SetImageOption(image_info,option,argv[1]);
1198 image_info->quality=UndefinedCompressionQuality;
1199 (void) SetImageOption(image_info,option,"0");
1202 if (LocaleCompare("quantize",option) == 0)
1204 /* no image_info setting! Only set direct in quantize_info */
1205 quantize_info->colorspace=UndefinedColorspace;
1207 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
1208 MagickColorspaceOptions,MagickFalse,argv[1]);
1211 if (LocaleCompare("quiet",option) == 0)
1213 /* FUTURE: if two -quiet is performed you can not do +quiet! */
1214 static WarningHandler
1215 warning_handler = (WarningHandler) NULL;
1217 if (*argv[0] == '+')
1219 /* Restore error or warning messages. */
1220 warning_handler=SetWarningHandler(warning_handler);
1223 /* Suppress error or warning messages. */
1224 warning_handler=SetWarningHandler((WarningHandler) NULL);
1231 if (LocaleCompare("red-primary",option) == 0)
1233 /* Image chromaticity X,Y NB: Y=X if Y not defined
1236 (void) SetImageOption(image_info,option,
1237 IfSetOption ? argv[1] : "0" );
1244 if (LocaleCompare("sampling-factor",option) == 0)
1247 Set image sampling factor.
1249 if (*argv[0] == '+')
1251 if (image_info->sampling_factor != (char *) NULL)
1252 image_info->sampling_factor=DestroyString(
1253 image_info->sampling_factor);
1256 (void) CloneString(&image_info->sampling_factor,argv[1]);
1259 if (LocaleCompare("scene",option) == 0)
1264 if (*argv[0] == '+')
1266 image_info->scene=0;
1267 (void) SetImageOption(image_info,option,"0");
1270 image_info->scene=StringToUnsignedLong(argv[1]);
1271 (void) SetImageOption(image_info,option,argv[1]);
1274 if (LocaleCompare("seed",option) == 0)
1279 if (*argv[0] == '+')
1281 seed=(size_t) time((time_t *) NULL);
1282 SeedPseudoRandomGenerator(seed);
1285 seed=StringToUnsignedLong(argv[1]);
1286 SeedPseudoRandomGenerator(seed);
1289 if (LocaleCompare("size",option) == 0)
1291 /* FUTURE: convert to ImageOption
1292 Look at special handling for "size" in SetImageOption()
1294 if (*argv[0] == '+')
1296 if (image_info->size != (char *) NULL)
1297 image_info->size=DestroyString(image_info->size);
1300 (void) CloneString(&image_info->size,argv[1]);
1303 if (LocaleCompare("stroke",option) == 0)
1305 if (*argv[0] == '+')
1307 (void) SetImageOption(image_info,option,"none");
1310 (void) SetImageOption(image_info,option,argv[1]);
1313 if (LocaleCompare("strokewidth",option) == 0)
1315 if (*argv[0] == '+')
1317 (void) SetImageOption(image_info,option,"0");
1320 (void) SetImageOption(image_info,option,argv[1]);
1323 if (LocaleCompare("synchronize",option) == 0)
1325 if (*argv[0] == '+')
1327 image_info->synchronize=MagickFalse;
1330 image_info->synchronize=MagickTrue;
1337 if (LocaleCompare("taint",option) == 0)
1339 if (*argv[0] == '+')
1341 (void) SetImageOption(image_info,option,"false");
1344 (void) SetImageOption(image_info,option,"true");
1347 if (LocaleCompare("texture",option) == 0)
1349 if (*argv[0] == '+')
1351 if (image_info->texture != (char *) NULL)
1352 image_info->texture=DestroyString(image_info->texture);
1355 (void) CloneString(&image_info->texture,argv[1]);
1358 if (LocaleCompare("tile",option) == 0)
1360 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
1362 draw_info->fill_pattern=GetImageCache(image_info,argv[1],exception);
1365 if (LocaleCompare("tile-offset",option) == 0)
1367 if (*argv[0] == '+')
1369 (void) SetImageOption(image_info,option,"0");
1372 (void) SetImageOption(image_info,option,argv[1]);
1375 if (LocaleCompare("transparent-color",option) == 0)
1377 if (*argv[0] == '+')
1379 (void) QueryColorCompliance("none",AllCompliance,
1380 &image_info->transparent_color,exception);
1381 (void) SetImageOption(image_info,option,"none");
1384 (void) QueryColorCompliance("none",AllCompliance,
1385 &image_info->transparent_color,exception);
1386 (void) SetImageOption(image_info,option,argv[1]);
1389 if (LocaleCompare("type",option) == 0)
1391 if (*argv[0] == '+')
1393 image_info->type=UndefinedType;
1394 (void) SetImageOption(image_info,option,"undefined");
1397 image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
1398 MagickFalse,argv[1]);
1399 (void) SetImageOption(image_info,option,argv[1]);
1406 if (LocaleCompare("undercolor",option) == 0)
1408 if (*argv[0] == '+')
1410 (void) DeleteImageOption(image_info,option);
1413 (void) SetImageOption(image_info,option,argv[1]);
1416 if (LocaleCompare("units",option) == 0)
1418 if (*argv[0] == '+')
1420 image_info->units=UndefinedResolution;
1421 (void) SetImageOption(image_info,option,"undefined");
1424 image_info->units=(ResolutionType) ParseCommandOption(
1425 MagickResolutionOptions,MagickFalse,argv[1]);
1426 (void) SetImageOption(image_info,option,argv[1]);
1433 if (LocaleCompare("verbose",option) == 0)
1435 if (*argv[0] == '+')
1437 image_info->verbose=MagickFalse;
1440 image_info->verbose=MagickTrue;
1441 image_info->ping=MagickFalse;
1444 if (LocaleCompare("view",option) == 0)
1446 if (*argv[0] == '+')
1448 if (image_info->view != (char *) NULL)
1449 image_info->view=DestroyString(image_info->view);
1452 (void) CloneString(&image_info->view,argv[1]);
1455 if (LocaleCompare("virtual-pixel",option) == 0)
1457 if (*argv[0] == '+')
1459 image_info->virtual_pixel_method=UndefinedVirtualPixelMethod;
1460 (void) SetImageOption(image_info,option,"undefined");
1463 image_info->virtual_pixel_method=(VirtualPixelMethod)
1464 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,argv[1]);
1465 (void) SetImageOption(image_info,option,argv[1]);
1472 if (LocaleCompare("white-point",option) == 0)
1474 if (*argv[0] == '+')
1476 (void) SetImageOption(image_info,option,"0.0");
1479 (void) SetImageOption(image_info,option,argv[1]);
1491 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1495 + A p p l y I m a g e O p e r a t o r %
1499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1501 % ApplyImageOperator() apply one simple image operation to just the current
1504 % The image in the list may be modified in three different ways...
1506 % * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1507 % * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1508 % * replace by a list of images (-separate and -crop only!)
1510 % In each case the result is returned into the list, and the pointer to the
1511 % modified image (last image added if replaced by a list of images) is
1512 % returned. As the image pointed to may be replaced, the first image in the
1513 % list may also change. GetFirstImageInList() should be used by caller if
1514 % they wish return the Image pointer to the first image in list.
1516 % The format of the ApplyImageOperator method is:
1518 % MagickBooleanType ApplyImageOperator(MagickWand *wand,
1519 % const int argc,const char **argv)
1521 % A description of each parameter follows:
1523 % o wand: The CLI wand holding all the settings and pointer to image
1525 % o argc: Specifies a pointer to an integer describing the number of
1526 % elements in the argument vector.
1528 % o argv: Specifies a pointer to a text array containing the command line
1531 % o exception: return any errors or warnings in this structure.
1534 MagickExport MagickBooleanType ApplyImageOperator(MagickWand *wand,
1535 const int wand_unused(argc), const char **argv, ExceptionInfo *exception)
1570 assert(image_info != (const ImageInfo *) NULL);
1571 assert(image_info->signature == MagickSignature);
1572 assert(image != (Image **) NULL);
1573 assert((*image)->signature == MagickSignature);
1574 if ((*image)->debug != MagickFalse)
1575 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
1578 draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
1579 quantize_info=AcquireQuantizeInfo(image_info);
1580 SetGeometryInfo(&geometry_info);
1581 GetPixelInfo(*image,&fill);
1582 SetPixelInfoPacket(*image,&(*image)->background_color,&fill);
1583 channel=image_info->channel;
1584 format=GetImageOption(image_info,"format");
1586 new_image = (Image *)NULL;
1592 if (LocaleCompare("adaptive-blur",option) == 0)
1594 (void) SyncImageSettings(image_info,*image);
1595 flags=ParseGeometry(argv[1],&geometry_info);
1596 if ((flags & SigmaValue) == 0)
1597 geometry_info.sigma=1.0;
1598 if ((flags & XiValue) == 0)
1599 geometry_info.xi=0.0;
1600 new_image=AdaptiveBlurImage(*image,geometry_info.rho,
1601 geometry_info.sigma,geometry_info.xi,exception);
1604 if (LocaleCompare("adaptive-resize",option) == 0)
1606 /* FUTURE: this is really a "interpolate-resize" operator
1607 "adaptive-resize" uses a fixed "Mesh" interpolation
1609 (void) SyncImageSettings(image_info,*image);
1610 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
1611 new_image=AdaptiveResizeImage(*image,geometry.width,
1612 geometry.height,interpolate_method,exception);
1615 if (LocaleCompare("adaptive-sharpen",option) == 0)
1618 Adaptive sharpen image.
1620 (void) SyncImageSettings(image_info,*image);
1621 flags=ParseGeometry(argv[1],&geometry_info);
1622 if ((flags & SigmaValue) == 0)
1623 geometry_info.sigma=1.0;
1624 if ((flags & XiValue) == 0)
1625 geometry_info.xi=0.0;
1626 new_image=AdaptiveSharpenImage(*image,geometry_info.rho,
1627 geometry_info.sigma,geometry_info.xi,exception);
1630 if (LocaleCompare("alpha",option) == 0)
1635 (void) SyncImageSettings(image_info,*image);
1636 alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
1637 MagickFalse,argv[1]);
1638 (void) SetImageAlphaChannel(*image,alpha_type,exception);
1641 if (LocaleCompare("annotate",option) == 0)
1645 geometry[MaxTextExtent];
1647 (void) SyncImageSettings(image_info,*image);
1648 SetGeometryInfo(&geometry_info);
1649 flags=ParseGeometry(argv[1],&geometry_info);
1650 if ((flags & SigmaValue) == 0)
1651 geometry_info.sigma=geometry_info.rho;
1652 text=InterpretImageProperties(image_info,*image,argv[2],
1654 if (text == (char *) NULL)
1656 (void) CloneString(&draw_info->text,text);
1657 text=DestroyString(text);
1658 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1659 geometry_info.xi,geometry_info.psi);
1660 (void) CloneString(&draw_info->geometry,geometry);
1661 draw_info->affine.sx=cos(DegreesToRadians(
1662 fmod(geometry_info.rho,360.0)));
1663 draw_info->affine.rx=sin(DegreesToRadians(
1664 fmod(geometry_info.rho,360.0)));
1665 draw_info->affine.ry=(-sin(DegreesToRadians(
1666 fmod(geometry_info.sigma,360.0))));
1667 draw_info->affine.sy=cos(DegreesToRadians(
1668 fmod(geometry_info.sigma,360.0)));
1669 (void) AnnotateImage(*image,draw_info,exception);
1672 if (LocaleCompare("auto-gamma",option) == 0)
1675 Auto Adjust Gamma of image based on its mean
1677 (void) SyncImageSettings(image_info,*image);
1678 (void) AutoGammaImage(*image,exception);
1681 if (LocaleCompare("auto-level",option) == 0)
1684 Perfectly Normalize (max/min stretch) the image
1686 (void) SyncImageSettings(image_info,*image);
1687 (void) AutoLevelImage(*image,exception);
1690 if (LocaleCompare("auto-orient",option) == 0)
1692 (void) SyncImageSettings(image_info,*image);
1693 switch ((*image)->orientation)
1695 case TopRightOrientation:
1697 new_image=FlopImage(*image,exception);
1700 case BottomRightOrientation:
1702 new_image=RotateImage(*image,180.0,exception);
1705 case BottomLeftOrientation:
1707 new_image=FlipImage(*image,exception);
1710 case LeftTopOrientation:
1712 new_image=TransposeImage(*image,exception);
1715 case RightTopOrientation:
1717 new_image=RotateImage(*image,90.0,exception);
1720 case RightBottomOrientation:
1722 new_image=TransverseImage(*image,exception);
1725 case LeftBottomOrientation:
1727 new_image=RotateImage(*image,270.0,exception);
1733 if (new_image != (Image *) NULL)
1734 new_image->orientation=TopLeftOrientation;
1741 if (LocaleCompare("black-threshold",option) == 0)
1743 (void) SyncImageSettings(image_info,*image);
1744 (void) BlackThresholdImage(*image,argv[1],exception);
1747 if (LocaleCompare("blue-shift",option) == 0)
1749 (void) SyncImageSettings(image_info,*image);
1750 geometry_info.rho=1.5;
1751 if (*argv[0] == '-')
1752 flags=ParseGeometry(argv[1],&geometry_info);
1753 new_image=BlueShiftImage(*image,geometry_info.rho,exception);
1756 if (LocaleCompare("blur",option) == 0)
1758 /* FUTURE: use of "bias" in a blur is non-sensible */
1759 (void) SyncImageSettings(image_info,*image);
1760 flags=ParseGeometry(argv[1],&geometry_info);
1761 if ((flags & SigmaValue) == 0)
1762 geometry_info.sigma=1.0;
1763 if ((flags & XiValue) == 0)
1764 geometry_info.xi=0.0;
1765 new_image=BlurImage(*image,geometry_info.rho,
1766 geometry_info.sigma,geometry_info.xi,exception);
1769 if (LocaleCompare("border",option) == 0)
1778 value=GetImageOption(image_info,"compose");
1779 if (value != (const char *) NULL)
1780 compose=(CompositeOperator) ParseCommandOption(
1781 MagickComposeOptions,MagickFalse,value);
1783 compose=OverCompositeOp; /* use Over not image->compose */
1785 (void) SyncImageSettings(image_info,*image);
1786 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
1787 if ((flags & SigmaValue) == 0)
1788 geometry.height=geometry.width;
1789 new_image=BorderImage(*image,&geometry,compose,exception);
1792 if (LocaleCompare("brightness-contrast",option) == 0)
1804 (void) SyncImageSettings(image_info,*image);
1805 flags=ParseGeometry(argv[1],&geometry_info);
1806 brightness=geometry_info.rho;
1808 if ((flags & SigmaValue) != 0)
1809 contrast=geometry_info.sigma;
1810 (void) BrightnessContrastImage(*image,brightness,contrast,
1818 if (LocaleCompare("cdl",option) == 0)
1821 *color_correction_collection;
1824 Color correct with a color decision list.
1826 (void) SyncImageSettings(image_info,*image);
1827 color_correction_collection=FileToString(argv[1],~0,exception);
1828 if (color_correction_collection == (char *) NULL)
1830 (void) ColorDecisionListImage(*image,color_correction_collection,
1834 if (LocaleCompare("channel",option) == 0)
1836 /* The "channel" setting has already been set */
1837 SetPixelChannelMap(*image,image_info->channel);
1840 if (LocaleCompare("charcoal",option) == 0)
1842 (void) SyncImageSettings(image_info,*image);
1843 flags=ParseGeometry(argv[1],&geometry_info);
1844 if ((flags & SigmaValue) == 0)
1845 geometry_info.sigma=1.0;
1846 if ((flags & XiValue) == 0)
1847 geometry_info.xi=1.0;
1848 new_image=CharcoalImage(*image,geometry_info.rho,
1849 geometry_info.sigma,geometry_info.xi,exception);
1852 if (LocaleCompare("chop",option) == 0)
1854 (void) SyncImageSettings(image_info,*image);
1855 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
1856 new_image=ChopImage(*image,&geometry,exception);
1859 if (LocaleCompare("clamp",option) == 0)
1861 (void) SyncImageSettings(image_info,*image);
1862 (void) ClampImage(*image,exception);
1865 if (LocaleCompare("clip",option) == 0)
1867 (void) SyncImageSettings(image_info,*image);
1868 if (*argv[0] == '+')
1870 (void) SetImageClipMask(*image,(Image *) NULL,exception);
1873 (void) ClipImage(*image,exception);
1876 if (LocaleCompare("clip-mask",option) == 0)
1893 (void) SyncImageSettings(image_info,*image);
1894 if (*argv[0] == '+')
1896 /* Remove the write mask */
1897 (void) SetImageMask(*image,(Image *) NULL,exception);
1900 mask_image=GetImageCache(image_info,argv[1],exception);
1901 if (mask_image == (Image *) NULL)
1903 if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
1904 return(MagickFalse);
1905 /* create a write mask from clip-mask image */
1906 /* FUTURE: use Alpha operations instead */
1907 mask_view=AcquireCacheView(mask_image);
1908 for (y=0; y < (ssize_t) mask_image->rows; y++)
1910 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
1912 if (q == (Quantum *) NULL)
1914 for (x=0; x < (ssize_t) mask_image->columns; x++)
1916 if (mask_image->matte == MagickFalse)
1917 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1918 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1919 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1920 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1921 q+=GetPixelChannels(mask_image);
1923 if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
1926 /* set the write mask */
1927 mask_view=DestroyCacheView(mask_view);
1928 mask_image->matte=MagickTrue;
1929 (void) SetImageClipMask(*image,mask_image,exception);
1930 mask_image=DestroyImage(mask_image);
1933 if (LocaleCompare("clip-path",option) == 0)
1935 (void) SyncImageSettings(image_info,*image);
1936 (void) ClipImagePath(*image,argv[1],*argv[0] == '-' ? MagickTrue :
1937 MagickFalse,exception);
1940 if (LocaleCompare("colorize",option) == 0)
1942 (void) SyncImageSettings(image_info,*image);
1943 new_image=ColorizeImage(*image,argv[1],draw_info->fill,
1947 if (LocaleCompare("color-matrix",option) == 0)
1952 (void) SyncImageSettings(image_info,*image);
1953 kernel=AcquireKernelInfo(argv[1]);
1954 if (kernel == (KernelInfo *) NULL)
1956 new_image=ColorMatrixImage(*image,kernel,exception);
1957 kernel=DestroyKernelInfo(kernel);
1960 if (LocaleCompare("colors",option) == 0)
1962 /* Reduce the number of colors in the image. */
1963 (void) SyncImageSettings(image_info,*image);
1964 quantize_info->number_colors=StringToUnsignedLong(argv[1]);
1965 if (quantize_info->number_colors == 0)
1967 if (((*image)->storage_class == DirectClass) ||
1968 (*image)->colors > quantize_info->number_colors)
1969 (void) QuantizeImage(quantize_info,*image,exception);
1971 (void) CompressImageColormap(*image,exception);
1974 if (LocaleCompare("colorspace",option) == 0)
1976 /* This is a Image Setting, which should already been set */
1977 /* FUTURE: default colorspace should be sRGB!
1978 Unless some type of 'linear colorspace' mode is set.
1979 Note that +colorspace sets "undefined" or no effect on
1980 new images, but forces images already in memory back to RGB!
1982 (void) SyncImageSettings(image_info,*image);
1983 (void) TransformImageColorspace(*image,
1984 IfSetOption ? image_info->colorspace : RGBColorspace,
1988 if (LocaleCompare("contrast",option) == 0)
1990 (void) SyncImageSettings(image_info,*image);
1991 (void) ContrastImage(*image,(*argv[0] == '-') ? MagickTrue :
1992 MagickFalse,exception);
1995 if (LocaleCompare("contrast-stretch",option) == 0)
2005 Contrast stretch image.
2007 (void) SyncImageSettings(image_info,*image);
2008 flags=ParseGeometry(argv[1],&geometry_info);
2009 black_point=geometry_info.rho;
2010 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2012 if ((flags & PercentValue) != 0)
2014 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2015 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2017 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2019 (void) ContrastStretchImage(*image,black_point,white_point,
2023 if (LocaleCompare("convolve",option) == 0)
2028 (void) SyncImageSettings(image_info,*image);
2029 kernel_info=AcquireKernelInfo(argv[1]);
2030 if (kernel_info == (KernelInfo *) NULL)
2032 kernel_info->bias=(*image)->bias;
2033 new_image=ConvolveImage(*image,kernel_info,exception);
2034 kernel_info=DestroyKernelInfo(kernel_info);
2037 if (LocaleCompare("crop",option) == 0)
2040 Crop a image to a smaller size
2042 (void) SyncImageSettings(image_info,*image);
2043 new_image=CropImageToTiles(*image,argv[1],exception);
2046 if (LocaleCompare("cycle",option) == 0)
2049 Cycle an image colormap.
2051 (void) SyncImageSettings(image_info,*image);
2052 (void) CycleColormapImage(*image,(ssize_t) StringToLong(argv[1]),
2060 if (LocaleCompare("decipher",option) == 0)
2068 (void) SyncImageSettings(image_info,*image);
2069 passkey=FileToStringInfo(argv[1],~0,exception);
2070 if (passkey != (StringInfo *) NULL)
2072 (void) PasskeyDecipherImage(*image,passkey,exception);
2073 passkey=DestroyStringInfo(passkey);
2077 if (LocaleCompare("depth",option) == 0)
2079 /* the image_info->depth setting has already bee set
2080 * We just need to apply it to all images in current sequence */
2081 (void) SyncImageSettings(image_info,*image);
2082 (void) SetImageDepth(*image,image_info->depth);
2085 if (LocaleCompare("deskew",option) == 0)
2091 Straighten the image.
2093 (void) SyncImageSettings(image_info,*image);
2094 if (*argv[0] == '+')
2095 threshold=40.0*QuantumRange/100.0;
2097 threshold=SiPrefixToDouble(argv[1],QuantumRange);
2098 new_image=DeskewImage(*image,threshold,exception);
2101 if (LocaleCompare("despeckle",option) == 0)
2104 Reduce the speckles within an image.
2106 (void) SyncImageSettings(image_info,*image);
2107 new_image=DespeckleImage(*image,exception);
2110 if (LocaleCompare("display",option) == 0)
2112 (void) CloneString(&draw_info->server_name,argv[1]);
2115 if (LocaleCompare("distort",option) == 0)
2119 token[MaxTextExtent];
2139 (void) SyncImageSettings(image_info,*image);
2140 method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
2141 MagickFalse,argv[1]);
2142 if ( method == ResizeDistortion )
2144 /* Special Case - Argument is actually a resize geometry!
2145 ** Convert that to an appropriate distortion argument array.
2149 (void) ParseRegionGeometry(*image,argv[2],&geometry,
2151 resize_args[0]=(double)geometry.width;
2152 resize_args[1]=(double)geometry.height;
2153 new_image=DistortImage(*image,method,(size_t)2,
2154 resize_args,MagickTrue,exception);
2157 args=InterpretImageProperties(image_info,*image,argv[2],
2159 if (args == (char *) NULL)
2162 for (x=0; *p != '\0'; x++)
2164 GetMagickToken(p,&p,token);
2166 GetMagickToken(p,&p,token);
2168 number_arguments=(size_t) x;
2169 arguments=(double *) AcquireQuantumMemory(number_arguments,
2170 sizeof(*arguments));
2171 if (arguments == (double *) NULL)
2172 ThrowWandFatalException(ResourceLimitFatalError,
2173 "MemoryAllocationFailed",(*image)->filename);
2174 (void) ResetMagickMemory(arguments,0,number_arguments*
2175 sizeof(*arguments));
2177 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2179 GetMagickToken(p,&p,token);
2181 GetMagickToken(p,&p,token);
2182 arguments[x]=InterpretLocaleValue(token,(char **) NULL);
2184 args=DestroyString(args);
2185 new_image=DistortImage(*image,method,number_arguments,arguments,
2186 (*argv[0] == '+') ? MagickTrue : MagickFalse,exception);
2187 arguments=(double *) RelinquishMagickMemory(arguments);
2190 if (LocaleCompare("draw",option) == 0)
2192 (void) SyncImageSettings(image_info,*image);
2193 (void) CloneString(&draw_info->primitive,argv[1]);
2194 (void) DrawImage(*image,draw_info,exception);
2201 if (LocaleCompare("edge",option) == 0)
2203 (void) SyncImageSettings(image_info,*image);
2204 flags=ParseGeometry(argv[1],&geometry_info);
2205 if ((flags & SigmaValue) == 0)
2206 geometry_info.sigma=1.0;
2207 new_image=EdgeImage(*image,geometry_info.rho,
2208 geometry_info.sigma,exception);
2211 if (LocaleCompare("emboss",option) == 0)
2213 (void) SyncImageSettings(image_info,*image);
2214 flags=ParseGeometry(argv[1],&geometry_info);
2215 if ((flags & SigmaValue) == 0)
2216 geometry_info.sigma=1.0;
2217 new_image=EmbossImage(*image,geometry_info.rho,
2218 geometry_info.sigma,exception);
2221 if (LocaleCompare("encipher",option) == 0)
2226 (void) SyncImageSettings(image_info,*image);
2227 passkey=FileToStringInfo(argv[1],~0,exception);
2228 if (passkey != (StringInfo *) NULL)
2230 (void) PasskeyEncipherImage(*image,passkey,exception);
2231 passkey=DestroyStringInfo(passkey);
2235 if (LocaleCompare("enhance",option) == 0)
2237 (void) SyncImageSettings(image_info,*image);
2238 new_image=EnhanceImage(*image,exception);
2241 if (LocaleCompare("equalize",option) == 0)
2243 (void) SyncImageSettings(image_info,*image);
2244 (void) EqualizeImage(*image,exception);
2247 if (LocaleCompare("evaluate",option) == 0)
2252 MagickEvaluateOperator
2255 (void) SyncImageSettings(image_info,*image);
2256 op=(MagickEvaluateOperator) ParseCommandOption(
2257 MagickEvaluateOptions,MagickFalse,argv[1]);
2258 constant=SiPrefixToDouble(argv[2],QuantumRange);
2259 (void) EvaluateImage(*image,op,constant,exception);
2262 if (LocaleCompare("extent",option) == 0)
2264 (void) SyncImageSettings(image_info,*image);
2265 flags=ParseGravityGeometry(*image,argv[1],&geometry,exception);
2266 if (geometry.width == 0)
2267 geometry.width=(*image)->columns;
2268 if (geometry.height == 0)
2269 geometry.height=(*image)->rows;
2270 new_image=ExtentImage(*image,&geometry,exception);
2277 if (LocaleCompare("features",option) == 0)
2279 /* FUTURE: Assign Artifact to all images -- really a setting */
2280 (void) SetImageArtifact(*image,"identify:features",
2281 IfSetOption ? argv[1] : (const char *) NULL);
2284 if (LocaleCompare("flip",option) == 0)
2286 (void) SyncImageSettings(image_info,*image);
2287 new_image=FlipImage(*image,exception);
2290 if (LocaleCompare("flop",option) == 0)
2292 (void) SyncImageSettings(image_info,*image);
2293 new_image=FlopImage(*image,exception);
2296 if (LocaleCompare("floodfill",option) == 0)
2301 (void) SyncImageSettings(image_info,*image);
2302 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
2303 (void) QueryColorCompliance(argv[2],AllCompliance,&target,
2305 (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
2306 geometry.y,*argv[0] == '-' ? MagickFalse : MagickTrue,exception);
2309 if (LocaleCompare("frame",option) == 0)
2314 (void) SyncImageSettings(image_info,*image);
2315 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
2316 frame_info.width=geometry.width;
2317 frame_info.height=geometry.height;
2318 if ((flags & HeightValue) == 0)
2319 frame_info.height=geometry.width;
2320 frame_info.outer_bevel=geometry.x;
2321 frame_info.inner_bevel=geometry.y;
2322 frame_info.x=(ssize_t) frame_info.width;
2323 frame_info.y=(ssize_t) frame_info.height;
2324 frame_info.width=(*image)->columns+2*frame_info.width;
2325 frame_info.height=(*image)->rows+2*frame_info.height;
2326 new_image=FrameImage(*image,&frame_info,COMPOSE,exception);
2329 if (LocaleCompare("function",option) == 0)
2333 token[MaxTextExtent];
2350 (void) SyncImageSettings(image_info,*image);
2351 function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
2352 MagickFalse,argv[1]);
2353 arguments=InterpretImageProperties(image_info,*image,argv[2],
2355 if (arguments == (char *) NULL)
2357 p=(char *) arguments;
2358 for (x=0; *p != '\0'; x++)
2360 GetMagickToken(p,&p,token);
2362 GetMagickToken(p,&p,token);
2364 number_parameters=(size_t) x;
2365 parameters=(double *) AcquireQuantumMemory(number_parameters,
2366 sizeof(*parameters));
2367 if (parameters == (double *) NULL)
2368 ThrowWandFatalException(ResourceLimitFatalError,
2369 "MemoryAllocationFailed",(*image)->filename);
2370 (void) ResetMagickMemory(parameters,0,number_parameters*
2371 sizeof(*parameters));
2372 p=(char *) arguments;
2373 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
2375 GetMagickToken(p,&p,token);
2377 GetMagickToken(p,&p,token);
2378 parameters[x]=InterpretLocaleValue(token,(char **) NULL);
2380 arguments=DestroyString(arguments);
2381 (void) FunctionImage(*image,function,number_parameters,parameters,
2383 parameters=(double *) RelinquishMagickMemory(parameters);
2390 if (LocaleCompare("gamma",option) == 0)
2392 (void) SyncImageSettings(image_info,*image);
2393 if (*argv[0] == '+')
2394 (*image)->gamma=InterpretLocaleValue(argv[1],(char **) NULL);
2396 (void) GammaImage(*image,InterpretLocaleValue(argv[1],
2397 (char **) NULL),exception);
2400 if ((LocaleCompare("gaussian-blur",option) == 0) ||
2401 (LocaleCompare("gaussian",option) == 0))
2403 (void) SyncImageSettings(image_info,*image);
2404 flags=ParseGeometry(argv[1],&geometry_info);
2405 if ((flags & SigmaValue) == 0)
2406 geometry_info.sigma=1.0;
2407 if ((flags & XiValue) == 0)
2408 geometry_info.xi=0.0;
2409 new_image=GaussianBlurImage(*image,geometry_info.rho,
2410 geometry_info.sigma,geometry_info.xi,exception);
2413 if (LocaleCompare("geometry",option) == 0)
2416 Record Image offset for composition,
2417 Resize last image. -- FUTURE depreciate this aspect
2419 (void) SyncImageSettings(image_info,*image);
2420 if (*argv[0] == '+')
2422 if ((*image)->geometry != (char *) NULL)
2423 (*image)->geometry=DestroyString((*image)->geometry);
2426 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2427 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2428 (void) CloneString(&(*image)->geometry,argv[1]);
2430 new_image=ResizeImage(*image,geometry.width,geometry.height,
2431 (*image)->filter,(*image)->blur,exception);
2438 if (LocaleCompare("highlight-color",option) == 0)
2440 (void) SetImageArtifact(*image,option,argv[1]);
2447 if (LocaleCompare("identify",option) == 0)
2452 (void) SyncImageSettings(image_info,*image);
2453 if (format == (char *) NULL)
2455 (void) IdentifyImage(*image,stdout,image_info->verbose,
2459 text=InterpretImageProperties(image_info,*image,format,
2461 if (text == (char *) NULL)
2463 (void) fputs(text,stdout);
2464 (void) fputc('\n',stdout);
2465 text=DestroyString(text);
2468 if (LocaleCompare("implode",option) == 0)
2470 (void) SyncImageSettings(image_info,*image);
2471 (void) ParseGeometry(argv[1],&geometry_info);
2472 new_image=ImplodeImage(*image,geometry_info.rho,
2473 interpolate_method,exception);
2480 if (LocaleCompare("lat",option) == 0)
2483 Local adaptive threshold image.
2485 (void) SyncImageSettings(image_info,*image);
2486 flags=ParseGeometry(argv[1],&geometry_info);
2487 if ((flags & PercentValue) != 0)
2488 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2489 new_image=AdaptiveThresholdImage(*image,(size_t)
2490 geometry_info.rho,(size_t) geometry_info.sigma,(double)
2491 geometry_info.xi,exception);
2494 if (LocaleCompare("level",option) == 0)
2504 (void) SyncImageSettings(image_info,*image);
2505 flags=ParseGeometry(argv[1],&geometry_info);
2506 black_point=geometry_info.rho;
2507 white_point=(MagickRealType) QuantumRange;
2508 if ((flags & SigmaValue) != 0)
2509 white_point=geometry_info.sigma;
2511 if ((flags & XiValue) != 0)
2512 gamma=geometry_info.xi;
2513 if ((flags & PercentValue) != 0)
2515 black_point*=(MagickRealType) (QuantumRange/100.0);
2516 white_point*=(MagickRealType) (QuantumRange/100.0);
2518 if ((flags & SigmaValue) == 0)
2519 white_point=(MagickRealType) QuantumRange-black_point;
2520 if ((*argv[0] == '+') || ((flags & AspectValue) != 0))
2521 (void) LevelizeImage(*image,black_point,white_point,gamma,
2524 (void) LevelImage(*image,black_point,white_point,gamma,
2528 if (LocaleCompare("level-colors",option) == 0)
2531 token[MaxTextExtent];
2540 p=(const char *) argv[1];
2541 GetMagickToken(p,&p,token); /* get black point color */
2542 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2543 (void) QueryColorCompliance(token,AllCompliance,
2544 &black_point,exception);
2546 (void) QueryColorCompliance("#000000",AllCompliance,
2547 &black_point,exception);
2548 if (isalpha((int) token[0]) || (token[0] == '#'))
2549 GetMagickToken(p,&p,token);
2551 white_point=black_point; /* set everything to that color */
2554 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2555 GetMagickToken(p,&p,token); /* Get white point color. */
2556 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2557 (void) QueryColorCompliance(token,AllCompliance,
2558 &white_point,exception);
2560 (void) QueryColorCompliance("#ffffff",AllCompliance,
2561 &white_point,exception);
2563 (void) LevelImageColors(*image,&black_point,&white_point,
2564 *argv[0] == '+' ? MagickTrue : MagickFalse,exception);
2567 if (LocaleCompare("linear-stretch",option) == 0)
2576 (void) SyncImageSettings(image_info,*image);
2577 flags=ParseGeometry(argv[1],&geometry_info);
2578 black_point=geometry_info.rho;
2579 white_point=(MagickRealType) (*image)->columns*(*image)->rows;
2580 if ((flags & SigmaValue) != 0)
2581 white_point=geometry_info.sigma;
2582 if ((flags & PercentValue) != 0)
2584 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2585 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2587 if ((flags & SigmaValue) == 0)
2588 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2590 (void) LinearStretchImage(*image,black_point,white_point,exception);
2593 if (LocaleCompare("liquid-rescale",option) == 0)
2596 Liquid rescale image.
2598 (void) SyncImageSettings(image_info,*image);
2599 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2600 if ((flags & XValue) == 0)
2602 if ((flags & YValue) == 0)
2604 new_image=LiquidRescaleImage(*image,geometry.width,
2605 geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
2608 if (LocaleCompare("lowlight-color",option) == 0)
2610 (void) SetImageArtifact(*image,option,argv[1]);
2617 if (LocaleCompare("map",option) == 0)
2622 (void) SyncImageSettings(image_info,*image);
2623 if (*argv[0] == '+')
2625 remap_image=GetImageCache(image_info,argv[1],exception);
2626 if (remap_image == (Image *) NULL)
2628 (void) RemapImage(quantize_info,*image,remap_image,exception);
2629 remap_image=DestroyImage(remap_image);
2632 if (LocaleCompare("mask",option) == 0)
2637 (void) SyncImageSettings(image_info,*image);
2638 if (*argv[0] == '+')
2640 (void) SetImageMask(*image,(Image *) NULL,exception);
2643 mask=GetImageCache(image_info,argv[1],exception);
2644 if (mask == (Image *) NULL)
2646 (void) SetImageMask(*image,mask,exception);
2647 mask=DestroyImage(mask);
2650 if (LocaleCompare("matte",option) == 0)
2652 /* FUTURE: Obsoleted by -alpha not used by anything */
2653 (void) SetImageAlphaChannel(*image,IfSetOption ?
2654 SetAlphaChannel : DeactivateAlphaChannel,exception);
2657 if (LocaleCompare("median",option) == 0)
2659 (void) SyncImageSettings(image_info,*image);
2660 flags=ParseGeometry(argv[1],&geometry_info);
2661 if ((flags & SigmaValue) == 0)
2662 geometry_info.sigma=geometry_info.rho;
2663 new_image=StatisticImage(*image,MedianStatistic,(size_t)
2664 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2667 if (LocaleCompare("mode",option) == 0)
2670 Statistical Mode image
2672 (void) SyncImageSettings(image_info,*image);
2673 flags=ParseGeometry(argv[1],&geometry_info);
2674 if ((flags & SigmaValue) == 0)
2675 geometry_info.sigma=geometry_info.rho;
2676 new_image=StatisticImage(*image,ModeStatistic,(size_t)
2677 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2680 if (LocaleCompare("modulate",option) == 0)
2682 (void) SyncImageSettings(image_info,*image);
2683 (void) ModulateImage(*image,argv[1],exception);
2686 if (LocaleCompare("monitor",option) == 0)
2688 if (*argv[0] == '+')
2690 (void) SetImageProgressMonitor(*image,
2691 (MagickProgressMonitor) NULL,(void *) NULL);
2694 (void) SetImageProgressMonitor(*image,MonitorProgress,
2698 if (LocaleCompare("monochrome",option) == 0)
2700 /* A setting (for input coders) and a 'type' operation */
2701 (void) SyncImageSettings(image_info,*image);
2702 (void) SetImageType(*image,BilevelType,exception);
2705 if (LocaleCompare("morphology",option) == 0)
2708 token[MaxTextExtent];
2723 Morphological Image Operation
2725 (void) SyncImageSettings(image_info,*image);
2727 GetMagickToken(p,&p,token);
2728 method=(MorphologyMethod) ParseCommandOption(
2729 MagickMorphologyOptions,MagickFalse,token);
2731 GetMagickToken(p,&p,token);
2732 if ((*p == ':') || (*p == ','))
2733 GetMagickToken(p,&p,token);
2735 iterations=(ssize_t) StringToLong(p);
2736 kernel=AcquireKernelInfo(argv[2]);
2737 if (kernel == (KernelInfo *) NULL)
2739 (void) ThrowMagickException(exception,GetMagickModule(),
2740 OptionError,"UnabletoParseKernel","morphology");
2744 new_image=MorphologyImage(*image,method,iterations,kernel,
2746 kernel=DestroyKernelInfo(kernel);
2749 if (LocaleCompare("motion-blur",option) == 0)
2751 (void) SyncImageSettings(image_info,*image);
2752 flags=ParseGeometry(argv[1],&geometry_info);
2753 if ((flags & SigmaValue) == 0)
2754 geometry_info.sigma=1.0;
2755 new_image=MotionBlurImage(*image,geometry_info.rho,
2756 geometry_info.sigma,geometry_info.xi,geometry_info.psi,
2764 if (LocaleCompare("negate",option) == 0)
2766 (void) SyncImageSettings(image_info,*image);
2767 (void) NegateImage(*image,*argv[0] == '+' ? MagickTrue :
2768 MagickFalse,exception);
2771 if (LocaleCompare("noise",option) == 0)
2773 (void) SyncImageSettings(image_info,*image);
2774 if (*argv[0] == '-')
2776 flags=ParseGeometry(argv[1],&geometry_info);
2777 if ((flags & SigmaValue) == 0)
2778 geometry_info.sigma=geometry_info.rho;
2779 new_image=StatisticImage(*image,NonpeakStatistic,(size_t)
2780 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2787 noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
2788 MagickFalse,argv[1]);
2789 new_image=AddNoiseImage(*image,noise,exception);
2793 if (LocaleCompare("normalize",option) == 0)
2795 (void) SyncImageSettings(image_info,*image);
2796 (void) NormalizeImage(*image,exception);
2803 if (LocaleCompare("opaque",option) == 0)
2808 (void) SyncImageSettings(image_info,*image);
2809 (void) QueryColorCompliance(argv[1],AllCompliance,&target,
2811 (void) OpaquePaintImage(*image,&target,&fill,*argv[0] == '-' ?
2812 MagickFalse : MagickTrue,exception);
2815 if (LocaleCompare("ordered-dither",option) == 0)
2817 (void) SyncImageSettings(image_info,*image);
2818 (void) OrderedPosterizeImage(*image,argv[1],exception);
2825 if (LocaleCompare("paint",option) == 0)
2827 (void) SyncImageSettings(image_info,*image);
2828 (void) ParseGeometry(argv[1],&geometry_info);
2829 new_image=OilPaintImage(*image,geometry_info.rho,
2830 geometry_info.sigma,exception);
2833 if (LocaleCompare("polaroid",option) == 0)
2841 (void) SyncImageSettings(image_info,*image);
2842 random_info=AcquireRandomInfo();
2843 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2844 random_info=DestroyRandomInfo(random_info);
2845 if (*argv[0] == '-')
2847 SetGeometryInfo(&geometry_info);
2848 flags=ParseGeometry(argv[1],&geometry_info);
2849 angle=geometry_info.rho;
2851 new_image=PolaroidImage(*image,draw_info,angle,
2852 interpolate_method,exception);
2855 if (LocaleCompare("posterize",option) == 0)
2857 (void) SyncImageSettings(image_info,*image);
2858 (void) PosterizeImage(*image,StringToUnsignedLong(argv[1]),
2859 quantize_info->dither,exception);
2862 if (LocaleCompare("preview",option) == 0)
2865 preview_type=UndefinedPreview;
2867 (void) SyncImageSettings(image_info,*image);
2869 preview_type=(PreviewType) ParseCommandOption(
2870 MagickPreviewOptions,MagickFalse,argv[1]);
2871 new_image=PreviewImage(*image,preview_type,exception);
2874 if (LocaleCompare("profile",option) == 0)
2888 (void) SyncImageSettings(image_info,*image);
2891 (void) ProfileImage(*image,argv[1],(const unsigned char *)
2895 profile_info=CloneImageInfo(image_info);
2896 profile=GetImageProfile(*image,"iptc");
2897 if (profile != (StringInfo *) NULL)
2898 profile_info->profile=(void *) CloneStringInfo(profile);
2899 profile_image=GetImageCache(profile_info,argv[1],exception);
2900 profile_info=DestroyImageInfo(profile_info);
2901 if (profile_image == (Image *) NULL)
2906 profile_info=CloneImageInfo(image_info);
2907 (void) CopyMagickString(profile_info->filename,argv[1],
2909 profile=FileToStringInfo(profile_info->filename,~0UL,exception);
2910 if (profile != (StringInfo *) NULL)
2912 (void) ProfileImage(*image,profile_info->magick,
2913 GetStringInfoDatum(profile),(size_t)
2914 GetStringInfoLength(profile),exception);
2915 profile=DestroyStringInfo(profile);
2917 profile_info=DestroyImageInfo(profile_info);
2920 ResetImageProfileIterator(profile_image);
2921 name=GetNextImageProfile(profile_image);
2922 while (name != (const char *) NULL)
2924 profile=GetImageProfile(profile_image,name);
2925 if (profile != (StringInfo *) NULL)
2926 (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
2927 (size_t) GetStringInfoLength(profile),exception);
2928 name=GetNextImageProfile(profile_image);
2930 profile_image=DestroyImage(profile_image);
2937 if (LocaleCompare("radial-blur",option) == 0)
2942 (void) SyncImageSettings(image_info,*image);
2943 flags=ParseGeometry(argv[1],&geometry_info);
2944 new_image=RadialBlurImage(*image,geometry_info.rho,
2945 geometry_info.sigma,exception);
2948 if (LocaleCompare("raise",option) == 0)
2951 Surround image with a raise of solid color.
2953 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
2954 if ((flags & SigmaValue) == 0)
2955 geometry.height=geometry.width;
2956 (void) RaiseImage(*image,&geometry,*argv[0] == '-' ? MagickTrue :
2957 MagickFalse,exception);
2960 if (LocaleCompare("random-threshold",option) == 0)
2965 (void) SyncImageSettings(image_info,*image);
2966 (void) RandomThresholdImage(*image,argv[1],exception);
2969 if (LocaleCompare("recolor",option) == 0)
2974 (void) SyncImageSettings(image_info,*image);
2975 kernel=AcquireKernelInfo(argv[1]);
2976 if (kernel == (KernelInfo *) NULL)
2978 new_image=ColorMatrixImage(*image,kernel,exception);
2979 kernel=DestroyKernelInfo(kernel);
2982 if (LocaleCompare("render",option) == 0)
2984 (void) SyncImageSettings(image_info,*image);
2985 draw_info->render=(*argv[0] == '+') ? MagickTrue : MagickFalse;
2988 if (LocaleCompare("remap",option) == 0)
2994 Transform image colors to match this set of colors.
2996 (void) SyncImageSettings(image_info,*image);
2997 if (*argv[0] == '+')
2999 remap_image=GetImageCache(image_info,argv[1],exception);
3000 if (remap_image == (Image *) NULL)
3002 (void) RemapImage(quantize_info,*image,remap_image,exception);
3003 remap_image=DestroyImage(remap_image);
3006 if (LocaleCompare("repage",option) == 0)
3008 if (*argv[0] == '+')
3010 (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
3013 (void) ResetImagePage(*image,argv[1]);
3016 if (LocaleCompare("resample",option) == 0)
3021 (void) SyncImageSettings(image_info,*image);
3022 flags=ParseGeometry(argv[1],&geometry_info);
3023 if ((flags & SigmaValue) == 0)
3024 geometry_info.sigma=geometry_info.rho;
3025 new_image=ResampleImage(*image,geometry_info.rho,
3026 geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
3029 if (LocaleCompare("resize",option) == 0)
3034 (void) SyncImageSettings(image_info,*image);
3035 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3036 new_image=ResizeImage(*image,geometry.width,geometry.height,
3037 (*image)->filter,(*image)->blur,exception);
3040 if (LocaleCompare("roll",option) == 0)
3045 (void) SyncImageSettings(image_info,*image);
3046 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
3047 new_image=RollImage(*image,geometry.x,geometry.y,exception);
3050 if (LocaleCompare("rotate",option) == 0)
3056 Check for conditional image rotation.
3058 (void) SyncImageSettings(image_info,*image);
3059 if (strchr(argv[1],'>') != (char *) NULL)
3060 if ((*image)->columns <= (*image)->rows)
3062 if (strchr(argv[1],'<') != (char *) NULL)
3063 if ((*image)->columns >= (*image)->rows)
3068 geometry=ConstantString(argv[1]);
3069 (void) SubstituteString(&geometry,">","");
3070 (void) SubstituteString(&geometry,"<","");
3071 (void) ParseGeometry(geometry,&geometry_info);
3072 geometry=DestroyString(geometry);
3073 new_image=RotateImage(*image,geometry_info.rho,exception);
3080 if (LocaleCompare("sample",option) == 0)
3083 Sample image with pixel replication.
3085 (void) SyncImageSettings(image_info,*image);
3086 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3087 new_image=SampleImage(*image,geometry.width,geometry.height,
3091 if (LocaleCompare("scale",option) == 0)
3096 (void) SyncImageSettings(image_info,*image);
3097 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3098 new_image=ScaleImage(*image,geometry.width,geometry.height,
3102 if (LocaleCompare("selective-blur",option) == 0)
3105 Selectively blur pixels within a contrast threshold.
3107 (void) SyncImageSettings(image_info,*image);
3108 flags=ParseGeometry(argv[1],&geometry_info);
3109 if ((flags & PercentValue) != 0)
3110 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3111 new_image=SelectiveBlurImage(*image,geometry_info.rho,
3112 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3115 if (LocaleCompare("separate",option) == 0)
3118 Break channels into separate images.
3119 WARNING: This can generate multiple images!
3121 (void) SyncImageSettings(image_info,*image);
3122 new_image=SeparateImages(*image,exception);
3125 if (LocaleCompare("sepia-tone",option) == 0)
3133 (void) SyncImageSettings(image_info,*image);
3134 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3135 new_image=SepiaToneImage(*image,threshold,exception);
3138 if (LocaleCompare("segment",option) == 0)
3143 (void) SyncImageSettings(image_info,*image);
3144 flags=ParseGeometry(argv[1],&geometry_info);
3145 if ((flags & SigmaValue) == 0)
3146 geometry_info.sigma=1.0;
3147 (void) SegmentImage(*image,(*image)->colorspace,
3148 image_info->verbose,geometry_info.rho,geometry_info.sigma,
3152 if (LocaleCompare("set",option) == 0)
3157 if (*argv[0] == '+')
3159 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3160 (void) DeleteImageRegistry(argv[1]+9);
3162 if (LocaleNCompare(argv[1],"argv[0]:",7) == 0)
3164 (void) DeleteImageOption(image_info,argv[1]+7);
3165 (void) DeleteImageArtifact(*image,argv[1]+7);
3168 (void) DeleteImageProperty(*image,argv[1]);
3171 value=InterpretImageProperties(image_info,*image,argv[2],
3173 if (value == (char *) NULL)
3175 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3176 (void) SetImageRegistry(StringRegistryType,argv[1]+9,value,
3179 if (LocaleNCompare(argv[1],"option:",7) == 0)
3181 (void) SetImageOption(image_info,argv[1]+7,value);
3182 (void) SetImageArtifact(*image,argv[1]+7,value);
3185 (void) SetImageProperty(*image,argv[1],value,exception);
3186 value=DestroyString(value);
3189 if (LocaleCompare("shade",option) == 0)
3194 (void) SyncImageSettings(image_info,*image);
3195 flags=ParseGeometry(argv[1],&geometry_info);
3196 if ((flags & SigmaValue) == 0)
3197 geometry_info.sigma=1.0;
3198 new_image=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue :
3199 MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
3202 if (LocaleCompare("shadow",option) == 0)
3207 (void) SyncImageSettings(image_info,*image);
3208 flags=ParseGeometry(argv[1],&geometry_info);
3209 if ((flags & SigmaValue) == 0)
3210 geometry_info.sigma=1.0;
3211 if ((flags & XiValue) == 0)
3212 geometry_info.xi=4.0;
3213 if ((flags & PsiValue) == 0)
3214 geometry_info.psi=4.0;
3215 new_image=ShadowImage(*image,geometry_info.rho,
3216 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3217 ceil(geometry_info.psi-0.5),exception);
3220 if (LocaleCompare("sharpen",option) == 0)
3225 (void) SyncImageSettings(image_info,*image);
3226 flags=ParseGeometry(argv[1],&geometry_info);
3227 if ((flags & SigmaValue) == 0)
3228 geometry_info.sigma=1.0;
3229 if ((flags & XiValue) == 0)
3230 geometry_info.xi=0.0;
3231 new_image=SharpenImage(*image,geometry_info.rho,
3232 geometry_info.sigma,geometry_info.xi,exception);
3235 if (LocaleCompare("shave",option) == 0)
3238 Shave the image edges.
3240 (void) SyncImageSettings(image_info,*image);
3241 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3242 new_image=ShaveImage(*image,&geometry,exception);
3245 if (LocaleCompare("shear",option) == 0)
3250 (void) SyncImageSettings(image_info,*image);
3251 flags=ParseGeometry(argv[1],&geometry_info);
3252 if ((flags & SigmaValue) == 0)
3253 geometry_info.sigma=geometry_info.rho;
3254 new_image=ShearImage(*image,geometry_info.rho,
3255 geometry_info.sigma,exception);
3258 if (LocaleCompare("sigmoidal-contrast",option) == 0)
3261 Sigmoidal non-linearity contrast control.
3263 (void) SyncImageSettings(image_info,*image);
3264 flags=ParseGeometry(argv[1],&geometry_info);
3265 if ((flags & SigmaValue) == 0)
3266 geometry_info.sigma=(double) QuantumRange/2.0;
3267 if ((flags & PercentValue) != 0)
3268 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3270 (void) SigmoidalContrastImage(*image,(*argv[0] == '-') ?
3271 MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
3275 if (LocaleCompare("sketch",option) == 0)
3280 (void) SyncImageSettings(image_info,*image);
3281 flags=ParseGeometry(argv[1],&geometry_info);
3282 if ((flags & SigmaValue) == 0)
3283 geometry_info.sigma=1.0;
3284 new_image=SketchImage(*image,geometry_info.rho,
3285 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3288 if (LocaleCompare("solarize",option) == 0)
3293 (void) SyncImageSettings(image_info,*image);
3294 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3295 (void) SolarizeImage(*image,threshold,exception);
3298 if (LocaleCompare("sparse-color",option) == 0)
3307 Sparse Color Interpolated Gradient
3309 (void) SyncImageSettings(image_info,*image);
3310 method=(SparseColorMethod) ParseCommandOption(
3311 MagickSparseColorOptions,MagickFalse,argv[1]);
3312 arguments=InterpretImageProperties(image_info,*image,argv[2],
3314 if (arguments == (char *) NULL)
3316 new_image=SparseColorOption(*image,method,arguments,
3317 argv[0][0] == '+' ? MagickTrue : MagickFalse,exception);
3318 arguments=DestroyString(arguments);
3321 if (LocaleCompare("splice",option) == 0)
3324 Splice a solid color into the image.
3326 (void) SyncImageSettings(image_info,*image);
3327 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
3328 new_image=SpliceImage(*image,&geometry,exception);
3331 if (LocaleCompare("spread",option) == 0)
3336 (void) SyncImageSettings(image_info,*image);
3337 (void) ParseGeometry(argv[1],&geometry_info);
3338 new_image=SpreadImage(*image,geometry_info.rho,
3339 interpolate_method,exception);
3342 if (LocaleCompare("statistic",option) == 0)
3347 (void) SyncImageSettings(image_info,*image);
3348 type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
3349 MagickFalse,argv[1]);
3350 (void) ParseGeometry(argv[2],&geometry_info);
3351 new_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
3352 (size_t) geometry_info.sigma,exception);
3355 if (LocaleCompare("stretch",option) == 0)
3357 if (*argv[0] == '+')
3359 draw_info->stretch=UndefinedStretch;
3362 draw_info->stretch=(StretchType) ParseCommandOption(
3363 MagickStretchOptions,MagickFalse,argv[1]);
3366 if (LocaleCompare("strip",option) == 0)
3369 Strip image of profiles and comments.
3371 (void) SyncImageSettings(image_info,*image);
3372 (void) StripImage(*image,exception);
3375 if (LocaleCompare("stroke",option) == 0)
3380 if (*argv[0] == '+')
3382 (void) QueryColorCompliance("none",AllCompliance,&draw_info->stroke,
3384 if (draw_info->stroke_pattern != (Image *) NULL)
3385 draw_info->stroke_pattern=DestroyImage(
3386 draw_info->stroke_pattern);
3389 sans=AcquireExceptionInfo();
3390 status=QueryColorCompliance(argv[1],AllCompliance,&draw_info->stroke,sans);
3391 sans=DestroyExceptionInfo(sans);
3392 if (status == MagickFalse)
3393 draw_info->stroke_pattern=GetImageCache(image_info,argv[1],
3397 if (LocaleCompare("strokewidth",option) == 0)
3399 draw_info->stroke_width=InterpretLocaleValue(argv[1],
3403 if (LocaleCompare("style",option) == 0)
3405 if (*argv[0] == '+')
3407 draw_info->style=UndefinedStyle;
3410 draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
3411 MagickFalse,argv[1]);
3414 if (LocaleCompare("swirl",option) == 0)
3419 (void) SyncImageSettings(image_info,*image);
3420 (void) ParseGeometry(argv[1],&geometry_info);
3421 new_image=SwirlImage(*image,geometry_info.rho,
3422 interpolate_method,exception);
3429 if (LocaleCompare("threshold",option) == 0)
3437 (void) SyncImageSettings(image_info,*image);
3438 if (*argv[0] == '+')
3439 threshold=(double) QuantumRange/2;
3441 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3442 (void) BilevelImage(*image,threshold,exception);
3445 if (LocaleCompare("thumbnail",option) == 0)
3450 (void) SyncImageSettings(image_info,*image);
3451 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3452 new_image=ThumbnailImage(*image,geometry.width,geometry.height,
3456 if (LocaleCompare("tint",option) == 0)
3461 (void) SyncImageSettings(image_info,*image);
3462 new_image=TintImage(*image,argv[1],&fill,exception);
3465 if (LocaleCompare("transform",option) == 0)
3468 Affine transform image.
3470 (void) SyncImageSettings(image_info,*image);
3471 new_image=AffineTransformImage(*image,&draw_info->affine,
3475 if (LocaleCompare("transparent",option) == 0)
3480 (void) SyncImageSettings(image_info,*image);
3481 (void) QueryColorCompliance(argv[1],AllCompliance,&target,
3483 (void) TransparentPaintImage(*image,&target,(Quantum)
3484 TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue,
3488 if (LocaleCompare("transpose",option) == 0)
3491 Transpose image scanlines.
3493 (void) SyncImageSettings(image_info,*image);
3494 new_image=TransposeImage(*image,exception);
3497 if (LocaleCompare("transverse",option) == 0)
3500 Transverse image scanlines.
3502 (void) SyncImageSettings(image_info,*image);
3503 new_image=TransverseImage(*image,exception);
3506 if (LocaleCompare("treedepth",option) == 0)
3508 quantize_info->tree_depth=StringToUnsignedLong(argv[1]);
3511 if (LocaleCompare("trim",option) == 0)
3516 (void) SyncImageSettings(image_info,*image);
3517 new_image=TrimImage(*image,exception);
3520 if (LocaleCompare("type",option) == 0)
3525 (void) SyncImageSettings(image_info,*image);
3526 if (*argv[0] == '+')
3529 type=(ImageType) ParseCommandOption(MagickTypeOptions,MagickFalse,
3531 (*image)->type=UndefinedType;
3532 (void) SetImageType(*image,type,exception);
3539 if (LocaleCompare("undercolor",option) == 0)
3541 (void) QueryColorCompliance(argv[1],AllCompliance,&draw_info->undercolor,
3545 if (LocaleCompare("unique",option) == 0)
3547 if (*argv[0] == '+')
3549 (void) DeleteImageArtifact(*image,"identify:unique-colors");
3552 (void) SetImageArtifact(*image,"identify:unique-colors","true");
3553 (void) SetImageArtifact(*image,"verbose","true");
3556 if (LocaleCompare("unique-colors",option) == 0)
3559 Unique image colors.
3561 (void) SyncImageSettings(image_info,*image);
3562 new_image=UniqueImageColors(*image,exception);
3565 if (LocaleCompare("unsharp",option) == 0)
3570 (void) SyncImageSettings(image_info,*image);
3571 flags=ParseGeometry(argv[1],&geometry_info);
3572 if ((flags & SigmaValue) == 0)
3573 geometry_info.sigma=1.0;
3574 if ((flags & XiValue) == 0)
3575 geometry_info.xi=1.0;
3576 if ((flags & PsiValue) == 0)
3577 geometry_info.psi=0.05;
3578 new_image=UnsharpMaskImage(*image,geometry_info.rho,
3579 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3586 if (LocaleCompare("verbose",option) == 0)
3588 (void) SetImageArtifact(*image,option,
3589 *argv[0] == '+' ? "false" : "true");
3592 if (LocaleCompare("vignette",option) == 0)
3597 (void) SyncImageSettings(image_info,*image);
3598 flags=ParseGeometry(argv[1],&geometry_info);
3599 if ((flags & SigmaValue) == 0)
3600 geometry_info.sigma=1.0;
3601 if ((flags & XiValue) == 0)
3602 geometry_info.xi=0.1*(*image)->columns;
3603 if ((flags & PsiValue) == 0)
3604 geometry_info.psi=0.1*(*image)->rows;
3605 new_image=VignetteImage(*image,geometry_info.rho,
3606 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3607 ceil(geometry_info.psi-0.5),exception);
3610 if (LocaleCompare("virtual-pixel",option) == 0)
3612 if (*argv[0] == '+')
3614 (void) SetImageVirtualPixelMethod(*image,
3615 UndefinedVirtualPixelMethod);
3618 (void) SetImageVirtualPixelMethod(*image,(VirtualPixelMethod)
3619 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
3627 if (LocaleCompare("wave",option) == 0)
3632 (void) SyncImageSettings(image_info,*image);
3633 flags=ParseGeometry(argv[1],&geometry_info);
3634 if ((flags & SigmaValue) == 0)
3635 geometry_info.sigma=1.0;
3636 new_image=WaveImage(*image,geometry_info.rho,
3637 geometry_info.sigma,interpolate_method,exception);
3640 if (LocaleCompare("weight",option) == 0)
3642 draw_info->weight=StringToUnsignedLong(argv[1]);
3643 if (LocaleCompare(argv[1],"all") == 0)
3644 draw_info->weight=0;
3645 if (LocaleCompare(argv[1],"bold") == 0)
3646 draw_info->weight=700;
3647 if (LocaleCompare(argv[1],"bolder") == 0)
3648 if (draw_info->weight <= 800)
3649 draw_info->weight+=100;
3650 if (LocaleCompare(argv[1],"lighter") == 0)
3651 if (draw_info->weight >= 100)
3652 draw_info->weight-=100;
3653 if (LocaleCompare(argv[1],"normal") == 0)
3654 draw_info->weight=400;
3657 if (LocaleCompare("white-threshold",option) == 0)
3659 (void) SyncImageSettings(image_info,*image);
3660 (void) WhiteThresholdImage(*image,argv[1],exception);
3669 Replace current image with any image that was generated
3671 if (new_image != (Image *) NULL)
3672 ReplaceImageInListReturnLast(image,new_image);
3677 quantize_info=DestroyQuantizeInfo(quantize_info);
3678 draw_info=DestroyDrawInfo(draw_info);
3679 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
3680 return(status == 0 ? MagickFalse : MagickTrue);
3684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3688 + S e q u e n c e O p e r a t i o n I m a g e s %
3692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3694 % SequenceOperationImages() applies a single operation that apply to the
3695 % entire image list (e.g. -append, -layers, -coalesce, etc.).
3697 % The format of the MogrifyImage method is:
3699 % MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3700 % const int argc, const char **argv,Image **images,
3701 % ExceptionInfo *exception)
3703 % A description of each parameter follows:
3705 % o image_info: the image info..
3707 % o argc: Specifies a pointer to an integer describing the number of
3708 % elements in the argument vector.
3710 % o argv: Specifies a pointer to a text array containing the command line
3713 % o images: pointer to pointer of the first image in image list.
3715 % o exception: return any errors or warnings in this structure.
3718 WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3719 const int argc,const char **argv,Image **images,ExceptionInfo *exception)
3728 assert(image_info != (ImageInfo *) NULL);
3729 assert(image_info->signature == MagickSignature);
3730 assert(images != (Image **) NULL);
3731 assert((*images)->previous == (Image *) NULL);
3732 assert((*images)->signature == MagickSignature);
3733 if ((*images)->debug != MagickFalse)
3734 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3735 (*images)->filename);
3736 if ((argc <= 0) || (*argv == (char *) NULL))
3740 switch (*(argv[0]+1))
3744 if (LocaleCompare("affinity",argv[0]+1) == 0)
3746 (void) SyncImagesSettings(image_info,*images);
3747 if (*argv[0] == '+')
3749 (void) RemapImages(quantize_info,*images,(Image *) NULL,
3755 if (LocaleCompare("append",argv[0]+1) == 0)
3760 (void) SyncImagesSettings(image_info,*images);
3761 append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue :
3762 MagickFalse,exception);
3763 if (append_image == (Image *) NULL)
3768 *images=DestroyImageList(*images);
3769 *images=append_image;
3772 if (LocaleCompare("average",argv[0]+1) == 0)
3778 Average an image sequence (deprecated).
3780 (void) SyncImagesSettings(image_info,*images);
3781 average_image=EvaluateImages(*images,MeanEvaluateOperator,
3783 if (average_image == (Image *) NULL)
3788 *images=DestroyImageList(*images);
3789 *images=average_image;
3796 if (LocaleCompare("channel",argv[0]+1) == 0)
3801 if (*argv[0] == '+')
3803 channel=DefaultChannels;
3806 channel=(ChannelType) ParseChannelOption(argv[1]);
3807 SetPixelChannelMap(*images,channel);
3810 if (LocaleCompare("clut",argv[0]+1) == 0)
3816 (void) SyncImagesSettings(image_info,*images);
3817 image=RemoveFirstImageFromList(images);
3818 clut_image=RemoveFirstImageFromList(images);
3819 if (clut_image == (Image *) NULL)
3824 (void) ClutImage(image,clut_image,interpolate_method,exception);
3825 clut_image=DestroyImage(clut_image);
3826 *images=DestroyImageList(*images);
3830 if (LocaleCompare("coalesce",argv[0]+1) == 0)
3835 (void) SyncImagesSettings(image_info,*images);
3836 coalesce_image=CoalesceImages(*images,exception);
3837 if (coalesce_image == (Image *) NULL)
3842 *images=DestroyImageList(*images);
3843 *images=coalesce_image;
3846 if (LocaleCompare("combine",argv[0]+1) == 0)
3851 (void) SyncImagesSettings(image_info,*images);
3852 combine_image=CombineImages(*images,exception);
3853 if (combine_image == (Image *) NULL)
3858 *images=DestroyImageList(*images);
3859 *images=combine_image;
3862 if (LocaleCompare("composite",argv[0]+1) == 0)
3878 value=GetImageOption(image_info,"compose");
3879 if (value != (const char *) NULL)
3880 compose=(CompositeOperator) ParseCommandOption(
3881 MagickComposeOptions,MagickFalse,value);
3883 compose=OverCompositeOp; /* use Over not image->compose */
3886 value=GetImageOption(image_info,"compose");
3888 if (value != (const char *) NULL)
3889 compose=(CompositeOperator) ParseCommandOption(
3890 MagickComposeOptions,MagickFalse,value);
3892 compose=OverCompositeOp; /* use Over not image->compose */
3895 (void) SyncImagesSettings(image_info,*images);
3896 image=RemoveFirstImageFromList(images);
3897 composite_image=RemoveFirstImageFromList(images);
3898 if (composite_image == (Image *) NULL)
3903 (void) TransformImage(&composite_image,(char *) NULL,
3904 composite_image->geometry,exception);
3905 SetGeometry(composite_image,&geometry);
3906 (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
3907 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
3909 mask_image=RemoveFirstImageFromList(images);
3910 if (mask_image != (Image *) NULL)
3912 if ((compose == DisplaceCompositeOp) ||
3913 (compose == DistortCompositeOp))
3916 Merge Y displacement into X displacement image.
3918 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
3919 mask_image,0,0,exception);
3920 mask_image=DestroyImage(mask_image);
3925 Set a blending mask for the composition.
3926 Posible error, what if image->mask already set.
3928 image->mask=mask_image;
3929 (void) NegateImage(image->mask,MagickFalse,exception);
3932 (void) CompositeImage(image,compose,composite_image,
3933 geometry.x,geometry.y,exception);
3934 if (mask_image != (Image *) NULL)
3935 mask_image=image->mask=DestroyImage(image->mask);
3936 composite_image=DestroyImage(composite_image);
3937 *images=DestroyImageList(*images);
3945 if (LocaleCompare("deconstruct",argv[0]+1) == 0)
3950 (void) SyncImagesSettings(image_info,*images);
3951 deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
3953 if (deconstruct_image == (Image *) NULL)
3958 *images=DestroyImageList(*images);
3959 *images=deconstruct_image;
3962 if (LocaleCompare("delete",argv[0]+1) == 0)
3964 if (*argv[0] == '+')
3965 DeleteImages(images,"-1",exception);
3967 DeleteImages(images,argv[1],exception);
3970 if (LocaleCompare("dither",argv[0]+1) == 0)
3972 if (*argv[0] == '+')
3974 quantize_info->dither=MagickFalse;
3977 quantize_info->dither=MagickTrue;
3978 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
3979 MagickDitherOptions,MagickFalse,argv[1]);
3982 if (LocaleCompare("duplicate",argv[0]+1) == 0)
3987 if (*argv[0] == '+')
3988 duplicate_images=DuplicateImages(*images,1,"-1",exception);
3997 number_duplicates=(size_t) StringToLong(argv[1]);
3998 p=strchr(argv[1],',');
3999 if (p == (const char *) NULL)
4000 duplicate_images=DuplicateImages(*images,number_duplicates,
4003 duplicate_images=DuplicateImages(*images,number_duplicates,p,
4006 AppendImageToList(images, duplicate_images);
4007 (void) SyncImagesSettings(image_info,*images);
4014 if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0)
4019 MagickEvaluateOperator
4022 (void) SyncImageSettings(image_info,*images);
4023 op=(MagickEvaluateOperator) ParseCommandOption(
4024 MagickEvaluateOptions,MagickFalse,argv[1]);
4025 evaluate_image=EvaluateImages(*images,op,exception);
4026 if (evaluate_image == (Image *) NULL)
4031 *images=DestroyImageList(*images);
4032 *images=evaluate_image;
4039 if (LocaleCompare("fft",argv[0]+1) == 0)
4045 Implements the discrete Fourier transform (DFT).
4047 (void) SyncImageSettings(image_info,*images);
4048 fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ?
4049 MagickTrue : MagickFalse,exception);
4050 if (fourier_image == (Image *) NULL)
4052 *images=DestroyImage(*images);
4053 *images=fourier_image;
4056 if (LocaleCompare("flatten",argv[0]+1) == 0)
4061 (void) SyncImagesSettings(image_info,*images);
4062 flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
4063 if (flatten_image == (Image *) NULL)
4065 *images=DestroyImageList(*images);
4066 *images=flatten_image;
4069 if (LocaleCompare("fx",argv[0]+1) == 0)
4074 (void) SyncImagesSettings(image_info,*images);
4075 fx_image=FxImage(*images,argv[1],exception);
4076 if (fx_image == (Image *) NULL)
4081 *images=DestroyImageList(*images);
4089 if (LocaleCompare("hald-clut",argv[0]+1) == 0)
4095 (void) SyncImagesSettings(image_info,*images);
4096 image=RemoveFirstImageFromList(images);
4097 hald_image=RemoveFirstImageFromList(images);
4098 if (hald_image == (Image *) NULL)
4103 (void) HaldClutImage(image,hald_image,exception);
4104 hald_image=DestroyImage(hald_image);
4105 if (*images != (Image *) NULL)
4106 *images=DestroyImageList(*images);
4114 if (LocaleCompare("ift",argv[0]+1) == 0)
4122 Implements the inverse fourier discrete Fourier transform (DFT).
4124 (void) SyncImagesSettings(image_info,*images);
4125 magnitude_image=RemoveFirstImageFromList(images);
4126 phase_image=RemoveFirstImageFromList(images);
4127 if (phase_image == (Image *) NULL)
4132 fourier_image=InverseFourierTransformImage(magnitude_image,
4133 phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception);
4134 if (fourier_image == (Image *) NULL)
4136 if (*images != (Image *) NULL)
4137 *images=DestroyImage(*images);
4138 *images=fourier_image;
4141 if (LocaleCompare("insert",argv[0]+1) == 0)
4148 if (*argv[0] != '+')
4149 index=(ssize_t) StringToLong(argv[1]);
4150 p=RemoveLastImageFromList(images);
4151 if (p == (Image *) NULL)
4153 (void) ThrowMagickException(exception,GetMagickModule(),
4154 OptionError,"NoSuchImage","`%s'",argv[1]);
4160 PrependImageToList(images,q);
4162 if (index == (ssize_t) GetImageListLength(*images))
4163 AppendImageToList(images,q);
4166 q=GetImageFromList(*images,index-1);
4167 if (q == (Image *) NULL)
4169 (void) ThrowMagickException(exception,GetMagickModule(),
4170 OptionError,"NoSuchImage","`%s'",argv[1]);
4174 InsertImageInList(&q,p);
4176 *images=GetFirstImageInList(q);
4179 if (LocaleCompare("interpolate",argv[0]+1) == 0)
4181 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
4182 MagickInterpolateOptions,MagickFalse,argv[1]);
4189 if (LocaleCompare("layers",argv[0]+1) == 0)
4197 (void) SyncImagesSettings(image_info,*images);
4198 layers=(Image *) NULL;
4199 method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
4200 MagickFalse,argv[1]);
4205 layers=CoalesceImages(*images,exception);
4208 case CompareAnyLayer:
4209 case CompareClearLayer:
4210 case CompareOverlayLayer:
4213 layers=CompareImagesLayers(*images,method,exception);
4219 case TrimBoundsLayer:
4221 layers=MergeImageLayers(*images,method,exception);
4226 layers=DisposeImages(*images,exception);
4229 case OptimizeImageLayer:
4231 layers=OptimizeImageLayers(*images,exception);
4234 case OptimizePlusLayer:
4236 layers=OptimizePlusImageLayers(*images,exception);
4239 case OptimizeTransLayer:
4241 OptimizeImageTransparency(*images,exception);
4244 case RemoveDupsLayer:
4246 RemoveDuplicateLayers(images,exception);
4249 case RemoveZeroLayer:
4251 RemoveZeroDelayLayers(images,exception);
4257 General Purpose, GIF Animation Optimizer.
4259 layers=CoalesceImages(*images,exception);
4260 if (layers == (Image *) NULL)
4265 *images=DestroyImageList(*images);
4267 layers=OptimizeImageLayers(*images,exception);
4268 if (layers == (Image *) NULL)
4273 *images=DestroyImageList(*images);
4275 layers=(Image *) NULL;
4276 OptimizeImageTransparency(*images,exception);
4277 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4281 case CompositeLayer:
4295 value=GetImageOption(image_info,"compose");
4296 if (value != (const char *) NULL)
4297 compose=(CompositeOperator) ParseCommandOption(
4298 MagickComposeOptions,MagickFalse,value);
4300 compose=OverCompositeOp; /* use Over not image->compose */
4303 Split image sequence at the first 'NULL:' image.
4306 while (source != (Image *) NULL)
4308 source=GetNextImageInList(source);
4309 if ((source != (Image *) NULL) &&
4310 (LocaleCompare(source->magick,"NULL") == 0))
4313 if (source != (Image *) NULL)
4315 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4316 (GetNextImageInList(source) == (Image *) NULL))
4317 source=(Image *) NULL;
4321 Separate the two lists, junk the null: image.
4323 source=SplitImageList(source->previous);
4324 DeleteImageFromList(&source);
4327 if (source == (Image *) NULL)
4329 (void) ThrowMagickException(exception,GetMagickModule(),
4330 OptionError,"MissingNullSeparator","layers Composite");
4335 Adjust offset with gravity and virtual canvas.
4337 SetGeometry(*images,&geometry);
4338 (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
4339 geometry.width=source->page.width != 0 ?
4340 source->page.width : source->columns;
4341 geometry.height=source->page.height != 0 ?
4342 source->page.height : source->rows;
4343 GravityAdjustGeometry((*images)->page.width != 0 ?
4344 (*images)->page.width : (*images)->columns,
4345 (*images)->page.height != 0 ? (*images)->page.height :
4346 (*images)->rows,(*images)->gravity,&geometry);
4349 Compose the two image sequences together
4351 CompositeLayers(*images,compose,source,geometry.x,geometry.y,
4353 source=DestroyImageList(source);
4357 if (layers == (Image *) NULL)
4359 *images=DestroyImageList(*images);
4367 if (LocaleCompare("map",argv[0]+1) == 0)
4369 (void) SyncImagesSettings(image_info,*images);
4370 if (*argv[0] == '+')
4372 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4378 if (LocaleCompare("maximum",argv[0]+1) == 0)
4384 Maximum image sequence (deprecated).
4386 (void) SyncImagesSettings(image_info,*images);
4387 maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
4388 if (maximum_image == (Image *) NULL)
4393 *images=DestroyImageList(*images);
4394 *images=maximum_image;
4397 if (LocaleCompare("minimum",argv[0]+1) == 0)
4403 Minimum image sequence (deprecated).
4405 (void) SyncImagesSettings(image_info,*images);
4406 minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
4407 if (minimum_image == (Image *) NULL)
4412 *images=DestroyImageList(*images);
4413 *images=minimum_image;
4416 if (LocaleCompare("morph",argv[0]+1) == 0)
4421 (void) SyncImagesSettings(image_info,*images);
4422 morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]),
4424 if (morph_image == (Image *) NULL)
4429 *images=DestroyImageList(*images);
4430 *images=morph_image;
4433 if (LocaleCompare("mosaic",argv[0]+1) == 0)
4438 (void) SyncImagesSettings(image_info,*images);
4439 mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
4440 if (mosaic_image == (Image *) NULL)
4445 *images=DestroyImageList(*images);
4446 *images=mosaic_image;
4453 if (LocaleCompare("print",argv[0]+1) == 0)
4458 (void) SyncImagesSettings(image_info,*images);
4459 string=InterpretImageProperties(image_info,*images,argv[1],
4461 if (string == (char *) NULL)
4463 (void) FormatLocaleFile(stdout,"%s",string);
4464 string=DestroyString(string);
4466 if (LocaleCompare("process",argv[0]+1) == 0)
4475 (void) SyncImagesSettings(image_info,*images);
4476 arguments=StringToArgv(argv[1],&number_arguments);
4477 if (arguments == (char **) NULL)
4479 if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
4500 Support old style syntax, filter="-option arg".
4502 length=strlen(argv[1]);
4503 token=(char *) NULL;
4504 if (~length >= (MaxTextExtent-1))
4505 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4507 if (token == (char *) NULL)
4511 token_info=AcquireTokenInfo();
4512 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4513 "\"",'\0',&breaker,&next,"e);
4514 token_info=DestroyTokenInfo(token_info);
4520 argv=(&(arguments[next]));
4521 (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
4524 token=DestroyString(token);
4527 (void) SubstituteString(&arguments[1],"-","");
4528 (void) InvokeDynamicImageFilter(arguments[1],&(*images),
4529 number_arguments-2,(const char **) arguments+2,exception);
4530 for (j=0; j < number_arguments; j++)
4531 arguments[j]=DestroyString(arguments[j]);
4532 arguments=(char **) RelinquishMagickMemory(arguments);
4539 if (LocaleCompare("reverse",argv[0]+1) == 0)
4541 ReverseImageList(images);
4548 if (LocaleCompare("smush",argv[0]+1) == 0)
4556 (void) SyncImagesSettings(image_info,*images);
4557 offset=(ssize_t) StringToLong(argv[1]);
4558 smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue :
4559 MagickFalse,offset,exception);
4560 if (smush_image == (Image *) NULL)
4565 *images=DestroyImageList(*images);
4566 *images=smush_image;
4569 if (LocaleCompare("swap",argv[0]+1) == 0)
4581 if (*argv[0] != '+')
4590 flags=ParseGeometry(argv[1],&geometry_info);
4591 index=(ssize_t) geometry_info.rho;
4592 if ((flags & SigmaValue) != 0)
4593 swap_index=(ssize_t) geometry_info.sigma;
4595 p=GetImageFromList(*images,index);
4596 q=GetImageFromList(*images,swap_index);
4597 if ((p == (Image *) NULL) || (q == (Image *) NULL))
4599 (void) ThrowMagickException(exception,GetMagickModule(),
4600 OptionError,"NoSuchImage","`%s'",(*images)->filename);
4606 swap=CloneImage(p,0,0,MagickTrue,exception);
4607 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
4608 ReplaceImageInList(&q,swap);
4609 *images=GetFirstImageInList(q);
4616 if (LocaleCompare("write",argv[0]+1) == 0)
4627 (void) SyncImagesSettings(image_info,*images);
4628 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]);
4629 (void) DeleteImageRegistry(key);
4630 write_images=(*images);
4631 if (*argv[0] == '+')
4632 write_images=CloneImageList(*images,exception);
4633 write_info=CloneImageInfo(image_info);
4634 status&=WriteImages(write_info,write_images,argv[1],exception);
4635 write_info=DestroyImageInfo(write_info);
4636 if (*argv[0] == '+')
4637 write_images=DestroyImageList(write_images);
4645 quantize_info=DestroyQuantizeInfo(quantize_info);
4647 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
4648 return(status != 0 ? MagickTrue : MagickFalse);