blob: a133773ff5976edf652b6643c9166c199779573c [file] [log] [blame]
anthony805a2d42011-09-25 08:25:12 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% OOO PPPP EEEE RRRR AA TTTTTT III OOO N N %
7% O O P P E R R A A TT I O O NN N %
8% O O PPPP EEE RRRR AAAA TT I O O N N N %
9% O O P E R R A A TT I O O N NN %
10% OOO P EEEE R RR A A TT III OOO N N %
11% %
12% %
13% MagickWand Module Methods %
14% %
15% Software Design %
16% John Cristy %
cristy0a0ca4f2011-09-28 01:15:28 +000017% September 2011 %
anthony805a2d42011-09-25 08:25:12 +000018% %
19% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
anthony805a2d42011-09-25 08:25:12 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% Apply the given options (settings, and simple, or sequence operations) to
37% the given image(s) according to the current "image_info" and "draw_info"
38% settings.
39%
40% The final goal is to allow the execution in a strict one option at a time
41% manner that is needed for 'pipelining and file scripting' of options in
42% IMv7.
43%
44% Anthony Thyssen, Sept 2011
45*/
cristyc689f1f2011-10-05 21:13:24 +000046#if 0
anthony805a2d42011-09-25 08:25:12 +000047
48/*
49 Include declarations.
50*/
51#include "MagickWand/studio.h"
52#include "MagickWand/MagickWand.h"
53#include "MagickWand/mogrify-private.h"
54#include "MagickCore/monitor-private.h"
55#include "MagickCore/thread-private.h"
56#include "MagickCore/string-private.h"
57
58/*
59 Define declarations.
60*/
61#define UndefinedCompressionQuality 0UL
62/*
63 Constant declaration. (temporary exports)
64*/
65static const char
66 BackgroundColor[] = "#fff", /* white */
67 BorderColor[] = "#dfdfdf", /* gray */
68 MatteColor[] = "#bdbdbd"; /* gray */
69
70/*
71** Function to report on the progress of image operations
72*/
73static MagickBooleanType MonitorProgress(const char *text,
74 const MagickOffsetType offset,const MagickSizeType extent,
75 void *wand_unused(client_data))
76{
77 char
78 message[MaxTextExtent],
79 tag[MaxTextExtent];
80
81 const char
82 *locale_message;
83
84 register char
85 *p;
86
87 if (extent < 2)
88 return(MagickTrue);
89 (void) CopyMagickMemory(tag,text,MaxTextExtent);
90 p=strrchr(tag,'/');
91 if (p != (char *) NULL)
92 *p='\0';
93 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
94 locale_message=GetLocaleMessage(message);
95 if (locale_message == message)
96 locale_message=tag;
97 if (p == (char *) NULL)
98 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
99 locale_message,(long) offset,(unsigned long) extent,(long)
100 (100L*offset/(extent-1)));
101 else
102 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
103 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
104 (100L*offset/(extent-1)));
105 if (offset == (MagickOffsetType) (extent-1))
106 (void) FormatLocaleFile(stderr,"\n");
107 (void) fflush(stderr);
108 return(MagickTrue);
109}
110
111/*
112** GetImageCache() will read an image into a image cache if not already
113** present then return the image that is in the cache under that filename.
114*/
115static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
116 ExceptionInfo *exception)
117{
118 char
119 key[MaxTextExtent];
120
121 ExceptionInfo
122 *sans_exception;
123
124 Image
125 *image;
126
127 ImageInfo
128 *read_info;
129
130 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
131 sans_exception=AcquireExceptionInfo();
132 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
133 sans_exception=DestroyExceptionInfo(sans_exception);
134 if (image != (Image *) NULL)
135 return(image);
136 read_info=CloneImageInfo(image_info);
137 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
138 image=ReadImage(read_info,exception);
139 read_info=DestroyImageInfo(read_info);
140 if (image != (Image *) NULL)
141 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
142 return(image);
143}
144
145/*
anthonya89dd172011-10-04 13:29:35 +0000146 SparseColorOption() parse the complex -sparse-color argument into an
147 an array of floating point values than call SparseColorImage().
148 Argument is a complex mix of floating-point pixel coodinates, and color
149 specifications (or direct floating point numbers). The number of floats
150 needed to represent a color varies depending on teh current channel
151 setting.
anthony805a2d42011-09-25 08:25:12 +0000152*/
153static Image *SparseColorOption(const Image *image,
154 const SparseColorMethod method,const char *arguments,
155 const MagickBooleanType color_from_image,ExceptionInfo *exception)
156{
157 char
158 token[MaxTextExtent];
159
160 const char
161 *p;
162
163 double
164 *sparse_arguments;
165
166 Image
167 *sparse_image;
168
169 PixelInfo
170 color;
171
172 MagickBooleanType
173 error;
174
175 register size_t
176 x;
177
178 size_t
179 number_arguments,
180 number_colors;
181
182 assert(image != (Image *) NULL);
183 assert(image->signature == MagickSignature);
184 if (image->debug != MagickFalse)
185 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
186 assert(exception != (ExceptionInfo *) NULL);
187 assert(exception->signature == MagickSignature);
188 /*
189 Limit channels according to image - and add up number of color channel.
190 */
191 number_colors=0;
192 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
193 number_colors++;
194 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
195 number_colors++;
196 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
197 number_colors++;
198 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
199 (image->colorspace == CMYKColorspace))
200 number_colors++;
201 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
202 (image->matte != MagickFalse))
203 number_colors++;
204
205 /*
206 Read string, to determine number of arguments needed,
207 */
208 p=arguments;
209 x=0;
210 while( *p != '\0' )
211 {
212 GetMagickToken(p,&p,token);
213 if ( token[0] == ',' ) continue;
214 if ( isalpha((int) token[0]) || token[0] == '#' ) {
215 if ( color_from_image ) {
216 (void) ThrowMagickException(exception,GetMagickModule(),
217 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
218 "Color arg given, when colors are coming from image");
219 return( (Image *)NULL);
220 }
221 x += number_colors; /* color argument */
222 }
223 else {
224 x++; /* floating point argument */
225 }
226 }
227 error=MagickTrue;
228 if ( color_from_image ) {
229 /* just the control points are being given */
230 error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse;
231 number_arguments=(x/2)*(2+number_colors);
232 }
233 else {
234 /* control points and color values */
235 error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
236 number_arguments=x;
237 }
238 if ( error ) {
239 (void) ThrowMagickException(exception,GetMagickModule(),
240 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
241 "Invalid number of Arguments");
242 return( (Image *)NULL);
243 }
244
245 /* Allocate and fill in the floating point arguments */
246 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
247 sizeof(*sparse_arguments));
248 if (sparse_arguments == (double *) NULL) {
249 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
250 "MemoryAllocationFailed","%s","SparseColorOption");
251 return( (Image *)NULL);
252 }
253 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
254 sizeof(*sparse_arguments));
255 p=arguments;
256 x=0;
257 while( *p != '\0' && x < number_arguments ) {
258 /* X coordinate */
259 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
260 if ( token[0] == '\0' ) break;
261 if ( isalpha((int) token[0]) || token[0] == '#' ) {
262 (void) ThrowMagickException(exception,GetMagickModule(),
263 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
264 "Color found, instead of X-coord");
265 error = MagickTrue;
266 break;
267 }
cristydbdd0e32011-11-04 23:29:40 +0000268 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000269 /* Y coordinate */
270 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
271 if ( token[0] == '\0' ) break;
272 if ( isalpha((int) token[0]) || token[0] == '#' ) {
273 (void) ThrowMagickException(exception,GetMagickModule(),
274 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
275 "Color found, instead of Y-coord");
276 error = MagickTrue;
277 break;
278 }
cristydbdd0e32011-11-04 23:29:40 +0000279 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000280 /* color values for this control point */
281#if 0
282 if ( (color_from_image ) {
283 /* get color from image */
284 /* HOW??? */
285 }
286 else
287#endif
288 {
289 /* color name or function given in string argument */
290 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
291 if ( token[0] == '\0' ) break;
292 if ( isalpha((int) token[0]) || token[0] == '#' ) {
293 /* Color string given */
cristy269c9412011-10-13 23:41:15 +0000294 (void) QueryColorCompliance(token,AllCompliance,&color,
anthonya89dd172011-10-04 13:29:35 +0000295 exception);
anthony805a2d42011-09-25 08:25:12 +0000296 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;
308 }
309 else {
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)
313 {
314 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
315 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
316 break;
cristydbdd0e32011-11-04 23:29:40 +0000317 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000318 token[0] = ','; /* used this token - get another */
319 }
320 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
321 {
322 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
323 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
324 break;
cristydbdd0e32011-11-04 23:29:40 +0000325 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000326 token[0] = ','; /* used this token - get another */
327 }
328 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
329 {
330 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
331 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
332 break;
cristydbdd0e32011-11-04 23:29:40 +0000333 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000334 token[0] = ','; /* used this token - get another */
335 }
336 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
337 (image->colorspace == CMYKColorspace))
338 {
339 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
340 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
341 break;
cristydbdd0e32011-11-04 23:29:40 +0000342 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000343 token[0] = ','; /* used this token - get another */
344 }
345 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
346 (image->matte != MagickFalse))
347 {
348 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
349 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
350 break;
cristydbdd0e32011-11-04 23:29:40 +0000351 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000352 token[0] = ','; /* used this token - get another */
353 }
354 }
355 }
356 }
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);
362 }
363 if ( error )
364 return( (Image *)NULL);
365
366 /* Call the Interpolation function with the parsed arguments */
367 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
368 exception);
369 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
370 return( sparse_image );
371}
372
373/*
374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375% %
376% %
377% %
anthony1afdc7a2011-10-05 11:54:28 +0000378+ A p p l y S e t t i n g O p t i o n %
anthony805a2d42011-09-25 08:25:12 +0000379% %
380% %
381% %
382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
383%
anthonydcf510d2011-10-30 13:51:40 +0000384% ApplySettingOption() applies a single settings option into a CLI wand
385% holding the image_info, draw_info, quantize_info structures that will be
386% later used when processing images.
anthony805a2d42011-09-25 08:25:12 +0000387%
anthony80c37752012-01-16 01:03:11 +0000388% These options do no require images to be present in the wand for them to be
389% able to be set. That is they may be used without any image in memory.
390%
391% Options handled by this function are listed in CommandOptions[] of
392% "option.c" that is one of "SettingInfoOption" option flags.
anthony805a2d42011-09-25 08:25:12 +0000393%
anthony1afdc7a2011-10-05 11:54:28 +0000394% The format of the ApplySettingOption method is:
395%
396% MagickBooleanType ApplySettingOption(MagickWand *wand,
anthonydcf510d2011-10-30 13:51:40 +0000397% const char *option, const MagickBooleanType set_option, const char
398% **args, ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000399%
400% A description of each parameter follows:
401%
anthony1afdc7a2011-10-05 11:54:28 +0000402% o wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +0000403%
anthonydcf510d2011-10-30 13:51:40 +0000404% o option: The option string to be set
anthony805a2d42011-09-25 08:25:12 +0000405%
anthony80c37752012-01-16 01:03:11 +0000406% o set_option: is the option being set (-), or reset (+) to some default
anthonydcf510d2011-10-30 13:51:40 +0000407%
408% o arg: the single argument (if needed) to set this option.
anthony805a2d42011-09-25 08:25:12 +0000409%
410% o exception: return any errors or warnings in this structure.
411%
anthonydcf510d2011-10-30 13:51:40 +0000412%
413% Example usage (FUTURE)
414%
415% argc,argv
416% i=index in argv
417%
418% count=ParseCommandOption(MagickCommandOptions,MagickFalse,argv[i]);
419% flags=GetCommandOptionFlags(MagickCommandOptions,MagickFalse,argv[i]);
420% if ( flags == MagickCommandOptions )
421% ApplySettingsOption(wand, argv[i]+1,
422% (*argv[i])=='-' ? MagickTrue : MagickFalse,
423% (count>0)? argv[i+1]:(char *)NULL,
424% exception);
425% i += count+1;
426%
anthony805a2d42011-09-25 08:25:12 +0000427*/
anthonydcf510d2011-10-30 13:51:40 +0000428WandExport MagickBooleanType ApplySettingsOption(MagickWand *wand,
429 const char *option, const MagickBooleanType set_option, const char *arg,
430 ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000431{
anthony1afdc7a2011-10-05 11:54:28 +0000432 assert(wand != (MagickWand *) NULL);
433 assert(wand->signature == WandSignature);
434 assert(wand->draw_info != (DrawInfo *) NULL); /* ensure it is a CLI wand */
anthony1afdc7a2011-10-05 11:54:28 +0000435 if (wand->debug != MagickFalse)
436 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
anthony1afdc7a2011-10-05 11:54:28 +0000437
anthonydcf510d2011-10-30 13:51:40 +0000438#define image_info (wand->image_info)
439#define draw_info (wand->draw_info)
440#define quantize_info (wand->quantize_info)
441#define IfSetOption (set_option != MagickFalse)
442#define IfArgOption (IfSetOption?arg:(char *)NULL)
anthony74b1cfc2011-10-06 12:44:16 +0000443
444 switch (*option)
anthony805a2d42011-09-25 08:25:12 +0000445 {
446 case 'a':
447 {
anthony74b1cfc2011-10-06 12:44:16 +0000448 if (LocaleCompare("adjoin",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000449 {
anthonydcf510d2011-10-30 13:51:40 +0000450 image_info->adjoin = set_option;
anthony805a2d42011-09-25 08:25:12 +0000451 break;
452 }
anthony74b1cfc2011-10-06 12:44:16 +0000453 if (LocaleCompare("affine",option) == 0)
anthony1afdc7a2011-10-05 11:54:28 +0000454 {
anthonyafbaed72011-10-26 12:05:04 +0000455 /* draw_info setting only */
anthony74b1cfc2011-10-06 12:44:16 +0000456 if (IfSetOption)
anthonydcf510d2011-10-30 13:51:40 +0000457 (void) ParseAffineGeometry(arg,draw_info->affine,exception);
anthony74b1cfc2011-10-06 12:44:16 +0000458 else
459 GetAffineMatrix(draw_info->affine);
anthony1afdc7a2011-10-05 11:54:28 +0000460 break;
461 }
anthony74b1cfc2011-10-06 12:44:16 +0000462 if (LocaleCompare("antialias",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000463 {
anthony1afdc7a2011-10-05 11:54:28 +0000464 image_info->antialias =
465 draw_info->stroke_antialias =
anthonydcf510d2011-10-30 13:51:40 +0000466 draw_info->text_antialias = set_option;
anthony805a2d42011-09-25 08:25:12 +0000467 break;
468 }
anthony74b1cfc2011-10-06 12:44:16 +0000469 if (LocaleCompare("authenticate",option) == 0)
anthonydcf510d2011-10-30 13:51:40 +0000470 {
471 (void) SetImageOption(image_info,option,IfArgOption);
anthony805a2d42011-09-25 08:25:12 +0000472 break;
473 }
474 break;
475 }
476 case 'b':
477 {
anthony74b1cfc2011-10-06 12:44:16 +0000478 if (LocaleCompare("background",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000479 {
anthony74b1cfc2011-10-06 12:44:16 +0000480 /* FUTURE: both image_info attribute & ImageOption in use!
anthonyafbaed72011-10-26 12:05:04 +0000481 image_info only used for generating new images.
482 Note that +background, means fall-back to image
483 attribute so ImageOption is deleted, not set to a default.
anthony74b1cfc2011-10-06 12:44:16 +0000484 */
485 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000486 {
anthonydcf510d2011-10-30 13:51:40 +0000487 (void) SetImageOption(image_info,option,arg);
488 (void) QueryColorCompliance(arg,AllCompliance,
anthonyafbaed72011-10-26 12:05:04 +0000489 image_info->background_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000490 break;
491 }
anthonyafbaed72011-10-26 12:05:04 +0000492 (void) DeleteImageOption(image_info,option);
493 (void) QueryColorCompliance("none",AllCompliance,
494 image_info->background_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000495 break;
496 }
anthony74b1cfc2011-10-06 12:44:16 +0000497 if (LocaleCompare("bias",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000498 {
anthony74b1cfc2011-10-06 12:44:16 +0000499 /* FUTURE: bias OBSOLETED, replaced by "convolve:bias"
500 as it is actually rarely used except in direct convolve
501 Usage outside direct convolve is actally non-sensible!
502 */
503 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000504 IfSetOption ? arg : "0");
anthony805a2d42011-09-25 08:25:12 +0000505 break;
506 }
anthony74b1cfc2011-10-06 12:44:16 +0000507 if (LocaleCompare("black-point-compensation",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000508 {
anthonyafbaed72011-10-26 12:05:04 +0000509 /* Used as a image chromaticity setting */
anthony74b1cfc2011-10-06 12:44:16 +0000510 (void) SetImageOption(image_info,option,
511 IfSetOption ? "true" : "false" );
anthony805a2d42011-09-25 08:25:12 +0000512 break;
513 }
anthony74b1cfc2011-10-06 12:44:16 +0000514 if (LocaleCompare("blue-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000515 {
anthonyafbaed72011-10-26 12:05:04 +0000516 /* Image chromaticity X,Y NB: Y=X if Y not defined
517 Used by many coders including PNG
518 */
anthony74b1cfc2011-10-06 12:44:16 +0000519 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000520 IfSetOption ? arg : "0" );
anthony805a2d42011-09-25 08:25:12 +0000521 break;
522 }
anthony74b1cfc2011-10-06 12:44:16 +0000523 if (LocaleCompare("bordercolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000524 {
anthony74b1cfc2011-10-06 12:44:16 +0000525 /* FUTURE: both image_info attribute & ImageOption in use! */
526 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000527 {
anthonydcf510d2011-10-30 13:51:40 +0000528 (void) SetImageOption(image_info,option,arg);
529 (void) QueryColorCompliance(arg,AllCompliece,
anthony74b1cfc2011-10-06 12:44:16 +0000530 &image_info->border_color,exception);
anthonydcf510d2011-10-30 13:51:40 +0000531 (void) QueryColorCompliance(arg,AllCompliance,
anthony74b1cfc2011-10-06 12:44:16 +0000532 &draw_info->border_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000533 break;
534 }
anthony74b1cfc2011-10-06 12:44:16 +0000535 (void) DeleteImageOption(image_info,option);
536 (void) QueryColorCompliance(BorderColor,AllCompliance,
537 &image_info->border_color,exception);
538 (void) QueryColorCompliance(BorderColor,AllCompliance,
539 &draw_info->border_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000540 break;
541 }
anthony74b1cfc2011-10-06 12:44:16 +0000542 if (LocaleCompare("box",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000543 {
anthonyafbaed72011-10-26 12:05:04 +0000544 /* Only used to set draw_info for text drawing */
anthony74b1cfc2011-10-06 12:44:16 +0000545 const char
anthonydcf510d2011-10-30 13:51:40 +0000546 *value = IfSetOption ? arg : "none";
anthony74b1cfc2011-10-06 12:44:16 +0000547 (void) SetImageOption(image_info,option,value);
548 (void) QueryColorCompliance(value,AllCompliance,
549 &draw_info->undercolor,exception);
anthony805a2d42011-09-25 08:25:12 +0000550 break;
551 }
552 break;
553 }
554 case 'c':
555 {
anthony74b1cfc2011-10-06 12:44:16 +0000556 if (LocaleCompare("cache",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000557 {
558 MagickSizeType
559 limit;
560
561 limit=MagickResourceInfinity;
anthonydcf510d2011-10-30 13:51:40 +0000562 if (LocaleCompare("unlimited",arg) != 0)
cristy9b34e302011-11-05 02:15:45 +0000563 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg,100.0);
anthony805a2d42011-09-25 08:25:12 +0000564 (void) SetMagickResourceLimit(MemoryResource,limit);
565 (void) SetMagickResourceLimit(MapResource,2*limit);
566 break;
567 }
anthony74b1cfc2011-10-06 12:44:16 +0000568 if (LocaleCompare("caption",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000569 {
anthony80c37752012-01-16 01:03:11 +0000570 (void) SetImageOption(image_info,option,
571 IfSetOption ? arg : (const char*)NULL);
anthony805a2d42011-09-25 08:25:12 +0000572 break;
573 }
anthony74b1cfc2011-10-06 12:44:16 +0000574 if (LocaleCompare("channel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000575 {
anthonyafbaed72011-10-26 12:05:04 +0000576 /* FUTURE: This is also a SimpleImageOperator!!! */
anthony74b1cfc2011-10-06 12:44:16 +0000577 image_info->channel=(ChannelType) (
anthonydcf510d2011-10-30 13:51:40 +0000578 IfSetOption ? ParseChannelOption(arg) : DefaultChannels );
cristy947cb4c2011-10-20 18:41:46 +0000579 /* This is also a SimpleImageOperator */
anthony805a2d42011-09-25 08:25:12 +0000580 break;
581 }
anthony74b1cfc2011-10-06 12:44:16 +0000582 if (LocaleCompare("colorspace",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000583 {
anthonyafbaed72011-10-26 12:05:04 +0000584 /* Setting used for new images via AquireImage()
585 But also used as a SimpleImageOperator
586 Undefined colorspace means don't modify images on
587 read or as a operation */
anthony965524b2011-10-07 12:34:14 +0000588 image_info->colorspace=UndefinedColorspace;
anthonyd2cdc862011-10-07 14:07:17 +0000589 if (IfSetOption)
590 image_info->colorspace=(ColorspaceType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +0000591 MagickColorspaceOptions,MagickFalse,arg)
anthony805a2d42011-09-25 08:25:12 +0000592 break;
593 }
anthony74b1cfc2011-10-06 12:44:16 +0000594 if (LocaleCompare("comment",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000595 {
anthony965524b2011-10-07 12:34:14 +0000596 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000597 IfSetOption ? arg : (const char*)NULL);
anthony805a2d42011-09-25 08:25:12 +0000598 break;
599 }
anthony74b1cfc2011-10-06 12:44:16 +0000600 if (LocaleCompare("compose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000601 {
anthonyafbaed72011-10-26 12:05:04 +0000602 /* FUTURE: image_info should be used, but Option kept escapes
603 This setting should NOT be used to set image 'compose'
604 which is used by "-layer" operators is image_info is undefined
anthony965524b2011-10-07 12:34:14 +0000605 */
anthony5f867ae2011-10-09 10:28:34 +0000606 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000607 IfSetOption ? arg : (const char*)NULL);
anthony965524b2011-10-07 12:34:14 +0000608 image_info->compose=(CompositeOperator) ParseCommandOption(
anthony5f867ae2011-10-09 10:28:34 +0000609 MagickComposeOptions,MagickFalse,
anthonydcf510d2011-10-30 13:51:40 +0000610 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000611 break;
612 }
anthony74b1cfc2011-10-06 12:44:16 +0000613 if (LocaleCompare("compress",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000614 {
anthony5f867ae2011-10-09 10:28:34 +0000615 /* FUTURE: What should be used? image_info or ImageOption ???
616 The former is more efficent, but Crisy prefers the latter!
617
618 The coders appears to use image_info, not Image_Option
619 however the image attribute (for save) is set from the
620 ImageOption!
621 */
622 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000623 {
anthony5f867ae2011-10-09 10:28:34 +0000624 image_info->compression=(CompressionType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +0000625 MagickCompressOptions,MagickFalse,arg);
626 (void) SetImageOption(image_info,option,arg);
anthony805a2d42011-09-25 08:25:12 +0000627 break;
628 }
anthony5f867ae2011-10-09 10:28:34 +0000629 image_info->compression=UndefinedCompression;
630 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000631 break;
632 }
633 break;
634 }
635 case 'd':
636 {
anthony74b1cfc2011-10-06 12:44:16 +0000637 if (LocaleCompare("debug",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000638 {
anthony5f867ae2011-10-09 10:28:34 +0000639 if (IfSetOption)
anthonydcf510d2011-10-30 13:51:40 +0000640 (void) SetLogEventMask(IfSetOption?arg:"none");
anthony5f867ae2011-10-09 10:28:34 +0000641 image_info->debug=IsEventLogging(); /* extract logging*/
642 wand->debug=IsEventLogging();
anthony805a2d42011-09-25 08:25:12 +0000643 break;
644 }
anthony74b1cfc2011-10-06 12:44:16 +0000645 if (LocaleCompare("define",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000646 {
anthony5f867ae2011-10-09 10:28:34 +0000647 /* FUTURE both -set and -define sets ImageOption
anthonyafbaed72011-10-26 12:05:04 +0000648 But differs in that -set tries to set image properity (attributes)
anthony5f867ae2011-10-09 10:28:34 +0000649 */
anthonydcf510d2011-10-30 13:51:40 +0000650 if (LocaleNCompare(arg,"registry:",9) == 0)
anthony805a2d42011-09-25 08:25:12 +0000651 {
anthony5f867ae2011-10-09 10:28:34 +0000652 if (IfSetOption)
anthonydcf510d2011-10-30 13:51:40 +0000653 (void) DefineImageRegistry(StringRegistryType,arg+9,
anthony5f867ae2011-10-09 10:28:34 +0000654 exception);
655 else
anthonydcf510d2011-10-30 13:51:40 +0000656 (void) DefineImageOption(image_info,arg,exception);
anthony805a2d42011-09-25 08:25:12 +0000657 break;
658 }
anthony5f867ae2011-10-09 10:28:34 +0000659 if (IfSetOption)
anthonydcf510d2011-10-30 13:51:40 +0000660 (void) DefineImageOption(image_info,arg,exception);
anthony5f867ae2011-10-09 10:28:34 +0000661 else
anthonydcf510d2011-10-30 13:51:40 +0000662 (void) DeleteImageOption(image_info,arg,exception);
anthony805a2d42011-09-25 08:25:12 +0000663 break;
664 }
anthony74b1cfc2011-10-06 12:44:16 +0000665 if (LocaleCompare("delay",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000666 {
anthonyafbaed72011-10-26 12:05:04 +0000667 /* Only used for new images via AcquireImage()
668 FUTURE: Option should also be used for "-morph" (color morphing)
anthony5f867ae2011-10-09 10:28:34 +0000669 */
670 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000671 IfSetOption ? arg : "0");
anthony805a2d42011-09-25 08:25:12 +0000672 break;
673 }
anthony74b1cfc2011-10-06 12:44:16 +0000674 if (LocaleCompare("density",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000675 {
anthonyafbaed72011-10-26 12:05:04 +0000676 /* FUTURE: string in image_info - moved into Option ??? */
677 /* Used by both draw_info and in images via SyncImageSettings() */
678 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000679 {
anthonydcf510d2011-10-30 13:51:40 +0000680 (void) CloneString(&image_info->density,arg);
681 (void) CloneString(&draw_info->density,arg);
682 (void) SetImageOption(image_info,option,arg);
anthony805a2d42011-09-25 08:25:12 +0000683 break;
684 }
anthony5f867ae2011-10-09 10:28:34 +0000685 if (image_info->density != (char *) NULL)
686 image_info->density=DestroyString(image_info->density);
687 if (draw_info->density != (char *) NULL)
688 draw_info->density=DestroyString(draw_info->density);
689 (void) SetImageOption(image_info,option,"72");
anthony805a2d42011-09-25 08:25:12 +0000690 break;
691 }
anthony74b1cfc2011-10-06 12:44:16 +0000692 if (LocaleCompare("depth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000693 {
anthonydcf510d2011-10-30 13:51:40 +0000694 /* This is also a SimpleImageOperator! to set depth across images */
695 image_info->depth=IfSetOption?StringToUnsignedLong(arg)
anthony5f867ae2011-10-09 10:28:34 +0000696 :MAGICKCORE_QUANTUM_DEPTH;
anthony805a2d42011-09-25 08:25:12 +0000697 break;
698 }
anthony74b1cfc2011-10-06 12:44:16 +0000699 if (LocaleCompare("direction",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000700 {
anthony6dc09cd2011-10-12 08:56:49 +0000701 /* Image Option is only used to set draw_info */
anthony5f867ae2011-10-09 10:28:34 +0000702 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000703 IfSetOption ? arg : "undefined");
anthony5f867ae2011-10-09 10:28:34 +0000704 draw_info->direction=(DirectionType) ParseCommandOption(
705 MagickDirectionOptions,MagickFalse,
anthonydcf510d2011-10-30 13:51:40 +0000706 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000707 break;
708 }
anthony74b1cfc2011-10-06 12:44:16 +0000709 if (LocaleCompare("display",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000710 {
anthonyafbaed72011-10-26 12:05:04 +0000711 /* FUTURE: string in image_info - moved into Option ??? */
712 (void) CloneString(&image_info->server_name,
anthonydcf510d2011-10-30 13:51:40 +0000713 IfSetOption ? arg :(char *) NULL);
anthony805a2d42011-09-25 08:25:12 +0000714 break;
715 }
anthony74b1cfc2011-10-06 12:44:16 +0000716 if (LocaleCompare("dispose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000717 {
anthony5f867ae2011-10-09 10:28:34 +0000718 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000719 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000720 break;
721 }
anthony74b1cfc2011-10-06 12:44:16 +0000722 if (LocaleCompare("dither",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000723 {
anthonyafbaed72011-10-26 12:05:04 +0000724 /* FUTURE: merge all options to just Option and quantize_info! */
anthony5f867ae2011-10-09 10:28:34 +0000725 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000726 IfSetOption ? arg : "none");
anthony5f867ae2011-10-09 10:28:34 +0000727 image_info->dither = quantize_info->dither =
anthony6dc09cd2011-10-12 08:56:49 +0000728 IfSetOption ? MagickTrue : MagickFalse;
anthony5f867ae2011-10-09 10:28:34 +0000729 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
anthony6dc09cd2011-10-12 08:56:49 +0000730 MagickDitherOptions,MagickFalse,
anthonydcf510d2011-10-30 13:51:40 +0000731 IfSetOption ? arg : "none");
anthony5f867ae2011-10-09 10:28:34 +0000732 if (quantize_info->dither_method == NoDitherMethod)
anthony6dc09cd2011-10-12 08:56:49 +0000733 image_info->dither = quantize_info->dither = MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000734 break;
735 }
736 break;
737 }
738 case 'e':
739 {
anthony74b1cfc2011-10-06 12:44:16 +0000740 if (LocaleCompare("encoding",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000741 {
anthony6dc09cd2011-10-12 08:56:49 +0000742 (void) CloneString(&draw_info->encoding,
anthonydcf510d2011-10-30 13:51:40 +0000743 IfSetOption ? arg : "undefined");
anthony6dc09cd2011-10-12 08:56:49 +0000744 (void) SetImageOption(image_info,option,&draw_info->encoding);
anthony805a2d42011-09-25 08:25:12 +0000745 break;
746 }
anthony74b1cfc2011-10-06 12:44:16 +0000747 if (LocaleCompare("endian",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000748 {
anthony6dc09cd2011-10-12 08:56:49 +0000749 const char
750 value;
751
anthonydcf510d2011-10-30 13:51:40 +0000752 value=IfSetOption?arg:"undefined";
anthony6dc09cd2011-10-12 08:56:49 +0000753 (void) SetImageOption(image_info,option,value);
anthony805a2d42011-09-25 08:25:12 +0000754 image_info->endian=(EndianType) ParseCommandOption(
anthony6dc09cd2011-10-12 08:56:49 +0000755 MagickEndianOptions,MagickFalse,value);
anthony805a2d42011-09-25 08:25:12 +0000756 break;
757 }
anthony74b1cfc2011-10-06 12:44:16 +0000758 if (LocaleCompare("extract",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000759 {
anthony6dc09cd2011-10-12 08:56:49 +0000760 (void) CloneString(&image_info->extract,
anthonydcf510d2011-10-30 13:51:40 +0000761 IfSetOption?arg:(const char *) NULL);
anthony805a2d42011-09-25 08:25:12 +0000762 break;
763 }
764 break;
765 }
766 case 'f':
767 {
anthony6dc09cd2011-10-12 08:56:49 +0000768 if (LocaleCompare("family",argv[0]+1) == 0)
769 {
770 (void) CloneString(&draw_info->family,
anthonydcf510d2011-10-30 13:51:40 +0000771 IfSetOption ? arg : (const char *) NULL);
anthony6dc09cd2011-10-12 08:56:49 +0000772 break;
773 }
anthony74b1cfc2011-10-06 12:44:16 +0000774 if (LocaleCompare("fill",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000775 {
anthonyafbaed72011-10-26 12:05:04 +0000776 /* set fill OR a fill-pattern
777 color is only used by draw_info
778 but draw_info is only initialsed using the color not the pattern
779 */
anthony6dc09cd2011-10-12 08:56:49 +0000780 const char
781 value;
782
783 ExceptionInfo
784 *sans;
785
anthonydcf510d2011-10-30 13:51:40 +0000786 value = IfSetOption ? arg : "none";
anthony6dc09cd2011-10-12 08:56:49 +0000787 (void) SetImageOption(image_info,option,value);
788
789 sans=AcquireExceptionInfo();
anthony6dc09cd2011-10-12 08:56:49 +0000790 status=QueryColorCompliance(value,AllCompliance,&draw_info->fill,sans);
791 sans=DestroyExceptionInfo(sans);
792
793 if (draw_info->fill_pattern != (Image *) NULL)
794 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
795 if (status == MagickFalse)
796 draw_info->fill_pattern=GetImageCache(image_info,value,
797 exception);
anthony805a2d42011-09-25 08:25:12 +0000798 break;
799 }
anthony74b1cfc2011-10-06 12:44:16 +0000800 if (LocaleCompare("filter",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000801 {
anthony6dc09cd2011-10-12 08:56:49 +0000802 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000803 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000804 break;
805 }
anthonydcf510d2011-10-30 13:51:40 +0000806 if (LocaleCompare("font",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000807 {
anthony6dc09cd2011-10-12 08:56:49 +0000808 (void) CloneString(&draw_info->font,
anthonydcf510d2011-10-30 13:51:40 +0000809 IfSetOption ? arg : (const char *) NULL);
anthony6dc09cd2011-10-12 08:56:49 +0000810 (void) CloneString(&image_info->font,draw_info->font);
anthony805a2d42011-09-25 08:25:12 +0000811 break;
812 }
anthony74b1cfc2011-10-06 12:44:16 +0000813 if (LocaleCompare("format",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000814 {
anthonydcf510d2011-10-30 13:51:40 +0000815 /* FUTURE: why the ping test, you could set ping after this! */
816 /*
anthony805a2d42011-09-25 08:25:12 +0000817 register const char
818 *q;
819
anthonydcf510d2011-10-30 13:51:40 +0000820 for (q=strchr(arg,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
anthony805a2d42011-09-25 08:25:12 +0000821 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
822 image_info->ping=MagickFalse;
anthonydcf510d2011-10-30 13:51:40 +0000823 */
824 (void) SetImageOption(image_info,option,
825 IfSetOption ? arg : (const char *) NULL);
anthony805a2d42011-09-25 08:25:12 +0000826 break;
827 }
anthony74b1cfc2011-10-06 12:44:16 +0000828 if (LocaleCompare("fuzz",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000829 {
anthony6613bf32011-10-15 07:24:44 +0000830 /* FUTURE: image_info and ImageOption!
831 Option used to set image fuzz! unless blank canvas (from color)
anthonydcf510d2011-10-30 13:51:40 +0000832 Image attribute used for color compare operations
833 image->fuzz is being set by SyncImageSettings()
cristy947cb4c2011-10-20 18:41:46 +0000834 Can't find anything using image_info->fuzz (except cloning)!
anthony6613bf32011-10-15 07:24:44 +0000835 */
836 if (IfSetOption)
cristy947cb4c2011-10-20 18:41:46 +0000837 {
anthony80c37752012-01-16 01:03:11 +0000838 image_info->fuzz=StringToDoubleInterval(arg,(double)
839 QuantumRange+1.0);
anthonydcf510d2011-10-30 13:51:40 +0000840 (void) SetImageOption(image_info,option,arg);
cristy947cb4c2011-10-20 18:41:46 +0000841 break;
842 }
843 image_info->fuzz=0.0;
844 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +0000845 break;
846 }
847 break;
848 }
849 case 'g':
850 {
anthony74b1cfc2011-10-06 12:44:16 +0000851 if (LocaleCompare("gravity",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000852 {
anthonydcf510d2011-10-30 13:51:40 +0000853 /* FUTURE gravity also set in image via SyncImageSettings() */
854 const char
855 value;
856
857 value = IfSetOption ? arg : "none";
858 (void) SetImageOption(image_info,option,value);
anthony6dc09cd2011-10-12 08:56:49 +0000859 draw_info->gravity=(GravityType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +0000860 MagickGravityOptions,MagickFalse,value);
anthony805a2d42011-09-25 08:25:12 +0000861 break;
862 }
anthony74b1cfc2011-10-06 12:44:16 +0000863 if (LocaleCompare("green-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000864 {
anthonydcf510d2011-10-30 13:51:40 +0000865 /* Image chromaticity X,Y NB: Y=X if Y not defined
866 Used by many coders
867 */
868 (void) SetImageOption(image_info,option,
869 IfSetOption ? arg : "0.0");
anthony805a2d42011-09-25 08:25:12 +0000870 break;
871 }
872 break;
873 }
874 case 'i':
875 {
anthony74b1cfc2011-10-06 12:44:16 +0000876 if (LocaleCompare("intent",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000877 {
anthonydcf510d2011-10-30 13:51:40 +0000878 /* FUTURE: sets image->rendering_intent in SyncImagesSettings
879 Which is only used by coders: MIFF, MPC, BMP, PNG
880 and for image profile call to AcquireTransformThreadSet()
881 */
882 (void) SetImageOption(image_info,option,
883 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000884 break;
885 }
anthony74b1cfc2011-10-06 12:44:16 +0000886 if (LocaleCompare("interlace",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000887 {
anthonydcf510d2011-10-30 13:51:40 +0000888 /* sets image attibute interlace via SyncImageSettings()
889 Also image_info is directly used by coders
890 */
891 const char
892 value;
893
894 value = IfSetOption ? arg : "undefined";
895 (void) SetImageOption(image_info,option, value);
anthony805a2d42011-09-25 08:25:12 +0000896 image_info->interlace=(InterlaceType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +0000897 MagickInterlaceOptions,MagickFalse,arg);
898 (void) SetImageOption(image_info,option,arg);
anthony805a2d42011-09-25 08:25:12 +0000899 break;
900 }
anthony74b1cfc2011-10-06 12:44:16 +0000901 if (LocaleCompare("interline-spacing",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000902 {
anthonydcf510d2011-10-30 13:51:40 +0000903 const char
904 value;
905
906 value = IfSetOption ? arg : "0"; /* undefined? */
907 (void) SetImageOption(image_info,option, value);
cristy9b34e302011-11-05 02:15:45 +0000908 draw_info->interline_spacing=StringToDouble(value,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000909 break;
910 }
anthony74b1cfc2011-10-06 12:44:16 +0000911 if (LocaleCompare("interpolate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000912 {
anthonydcf510d2011-10-30 13:51:40 +0000913 /* FUTURE: sets image interpolate value via SyncImageSettings()
914 It is NOT used by coders, only in image processing,
915 so shoud really be a image_info attribute.
916 */
917 (void) SetImageOption(image_info,option,
918 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000919 break;
920 }
cristy947cb4c2011-10-20 18:41:46 +0000921 if (LocaleCompare("interword-spacing",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000922 {
anthonydcf510d2011-10-30 13:51:40 +0000923 const char
924 value;
925
926 value = IfSetOption ? arg : "0"; /* undefined? */
927 (void) SetImageOption(image_info,option, value);
cristy9b34e302011-11-05 02:15:45 +0000928 draw_info->interword_spacing=StringToDouble(value,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000929 break;
930 }
931 break;
932 }
933 case 'k':
934 {
anthony74b1cfc2011-10-06 12:44:16 +0000935 if (LocaleCompare("kerning",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000936 {
anthonydcf510d2011-10-30 13:51:40 +0000937 const char
938 value;
939
940 value = IfSetOption ? arg : "0"; /* undefined? */
941 (void) SetImageOption(image_info,option, value);
cristydbdd0e32011-11-04 23:29:40 +0000942 draw_info->kerning=StringToDouble(value,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000943 break;
944 }
945 break;
946 }
947 case 'l':
948 {
anthony74b1cfc2011-10-06 12:44:16 +0000949 if (LocaleCompare("label",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000950 {
anthonydcf510d2011-10-30 13:51:40 +0000951 /* only used for new images */
952 (void) SetImageOption(image_info,option,
953 IfSetOption ? arg : (char *)NULL);
anthony805a2d42011-09-25 08:25:12 +0000954 break;
955 }
anthony74b1cfc2011-10-06 12:44:16 +0000956 if (LocaleCompare("limit",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000957 {
958 MagickSizeType
959 limit;
960
961 ResourceType
962 type;
963
anthonydcf510d2011-10-30 13:51:40 +0000964 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000965 break;
966 type=(ResourceType) ParseCommandOption(MagickResourceOptions,
anthonydcf510d2011-10-30 13:51:40 +0000967 MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +0000968 limit=MagickResourceInfinity;
969 if (LocaleCompare("unlimited",argv[2]) != 0)
cristy9b34e302011-11-05 02:15:45 +0000970 limit=(MagickSizeType) SiPrefixToDoubleInterval(argv[2],
971 100.0);
anthony805a2d42011-09-25 08:25:12 +0000972 (void) SetMagickResourceLimit(type,limit);
973 break;
974 }
anthony74b1cfc2011-10-06 12:44:16 +0000975 if (LocaleCompare("list",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000976 {
977 ssize_t
978 list;
979
anthonydcf510d2011-10-30 13:51:40 +0000980 list=ParseCommandOption(MagickListOptions,MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +0000981 switch (list)
982 {
983 case MagickCoderOptions:
984 {
985 (void) ListCoderInfo((FILE *) NULL,exception);
986 break;
987 }
988 case MagickColorOptions:
989 {
990 (void) ListColorInfo((FILE *) NULL,exception);
991 break;
992 }
993 case MagickConfigureOptions:
994 {
995 (void) ListConfigureInfo((FILE *) NULL,exception);
996 break;
997 }
998 case MagickDelegateOptions:
999 {
1000 (void) ListDelegateInfo((FILE *) NULL,exception);
1001 break;
1002 }
1003 case MagickFontOptions:
1004 {
1005 (void) ListTypeInfo((FILE *) NULL,exception);
1006 break;
1007 }
1008 case MagickFormatOptions:
1009 {
1010 (void) ListMagickInfo((FILE *) NULL,exception);
1011 break;
1012 }
1013 case MagickLocaleOptions:
1014 {
1015 (void) ListLocaleInfo((FILE *) NULL,exception);
1016 break;
1017 }
1018 case MagickLogOptions:
1019 {
1020 (void) ListLogInfo((FILE *) NULL,exception);
1021 break;
1022 }
1023 case MagickMagicOptions:
1024 {
1025 (void) ListMagicInfo((FILE *) NULL,exception);
1026 break;
1027 }
1028 case MagickMimeOptions:
1029 {
1030 (void) ListMimeInfo((FILE *) NULL,exception);
1031 break;
1032 }
1033 case MagickModuleOptions:
1034 {
1035 (void) ListModuleInfo((FILE *) NULL,exception);
1036 break;
1037 }
1038 case MagickPolicyOptions:
1039 {
1040 (void) ListPolicyInfo((FILE *) NULL,exception);
1041 break;
1042 }
1043 case MagickResourceOptions:
1044 {
1045 (void) ListMagickResourceInfo((FILE *) NULL,exception);
1046 break;
1047 }
1048 case MagickThresholdOptions:
1049 {
1050 (void) ListThresholdMaps((FILE *) NULL,exception);
1051 break;
1052 }
1053 default:
1054 {
1055 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
1056 exception);
1057 break;
1058 }
1059 }
1060 break;
1061 }
anthony74b1cfc2011-10-06 12:44:16 +00001062 if (LocaleCompare("log",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001063 {
anthonydcf510d2011-10-30 13:51:40 +00001064 if (IfSetOption)
1065 (void) SetLogFormat(arg);
anthony805a2d42011-09-25 08:25:12 +00001066 break;
1067 }
anthony74b1cfc2011-10-06 12:44:16 +00001068 if (LocaleCompare("loop",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001069 {
anthonydcf510d2011-10-30 13:51:40 +00001070 /* Sets image attibutes iterations via SyncImageSettings() */
1071 (void) SetImageOption(image_info,option,
1072 IfSetOption ? arg : "0");
anthony805a2d42011-09-25 08:25:12 +00001073 break;
1074 }
1075 break;
1076 }
1077 case 'm':
1078 {
cristy947cb4c2011-10-20 18:41:46 +00001079 if (LocaleCompare("matte",option) == 0)
1080 {
1081 if (*argv[0] == '+')
1082 {
1083 (void) SetImageOption(image_info,option,"false");
1084 break;
1085 }
1086 (void) SetImageOption(image_info,option,"true");
1087 break;
1088 }
anthony74b1cfc2011-10-06 12:44:16 +00001089 if (LocaleCompare("mattecolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001090 {
cristy947cb4c2011-10-20 18:41:46 +00001091 if (*argv[0] == '+')
1092 {
anthonydcf510d2011-10-30 13:51:40 +00001093 (void) SetImageOption(image_info,option,arg);
cristy947cb4c2011-10-20 18:41:46 +00001094 (void) QueryColorCompliance(MatteColor,AllCompliance,
1095 &image_info->matte_color,exception);
1096 break;
1097 }
anthonydcf510d2011-10-30 13:51:40 +00001098 (void) SetImageOption(image_info,option,arg);
1099 (void) QueryColorCompliance(arg,AllCompliance,&image_info->matte_color,
cristy947cb4c2011-10-20 18:41:46 +00001100 exception);
anthony805a2d42011-09-25 08:25:12 +00001101 break;
1102 }
anthony74b1cfc2011-10-06 12:44:16 +00001103 if (LocaleCompare("monitor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001104 {
1105 (void) SetImageInfoProgressMonitor(image_info,MonitorProgress,
1106 (void *) NULL);
1107 break;
1108 }
anthony74b1cfc2011-10-06 12:44:16 +00001109 if (LocaleCompare("monochrome",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001110 {
anthonydcf510d2011-10-30 13:51:40 +00001111 /* Setting (for input coders) and a 'type' operation */
1112 image_info->monochrome=IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +00001113 break;
1114 }
1115 break;
1116 }
1117 case 'o':
1118 {
anthony74b1cfc2011-10-06 12:44:16 +00001119 if (LocaleCompare("orient",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001120 {
anthonydcf510d2011-10-30 13:51:40 +00001121 /* Sets image attribute orientation via SyncImageSettings()
1122 Is not used when defining for new images.
1123 This makes it more of a 'operation' than a setting
1124 */
1125 const char
1126 value;
1127
1128 value = IfSetOption ? arg : "undefined";
1129 (void) SetImageOption(image_info,option, value);
1130 image_info->orientation=(InterlaceType) ParseCommandOption(
1131 MagickOrientationOptions,MagickFalse,value);
anthony805a2d42011-09-25 08:25:12 +00001132 break;
1133 }
1134 }
1135 case 'p':
1136 {
anthony74b1cfc2011-10-06 12:44:16 +00001137 if (LocaleCompare("page",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001138 {
anthonydcf510d2011-10-30 13:51:40 +00001139 /* Only used for new images and image generators */
anthony805a2d42011-09-25 08:25:12 +00001140 char
1141 *canonical_page,
1142 page[MaxTextExtent];
1143
1144 const char
1145 *image_option;
1146
1147 MagickStatusType
1148 flags;
1149
1150 RectangleInfo
1151 geometry;
1152
anthonydcf510d2011-10-30 13:51:40 +00001153 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001154 {
anthony74b1cfc2011-10-06 12:44:16 +00001155 (void) DeleteImageOption(image_info,option);
anthony805a2d42011-09-25 08:25:12 +00001156 (void) CloneString(&image_info->page,(char *) NULL);
1157 break;
1158 }
1159 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
1160 image_option=GetImageOption(image_info,"page");
1161 if (image_option != (const char *) NULL)
1162 flags=ParseAbsoluteGeometry(image_option,&geometry);
anthonydcf510d2011-10-30 13:51:40 +00001163 canonical_page=GetPageGeometry(arg);
anthony805a2d42011-09-25 08:25:12 +00001164 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1165 canonical_page=DestroyString(canonical_page);
1166 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1167 (unsigned long) geometry.width,(unsigned long) geometry.height);
1168 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1169 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1170 (unsigned long) geometry.width,(unsigned long) geometry.height,
1171 (long) geometry.x,(long) geometry.y);
anthony74b1cfc2011-10-06 12:44:16 +00001172 (void) SetImageOption(image_info,option,page);
anthony805a2d42011-09-25 08:25:12 +00001173 (void) CloneString(&image_info->page,page);
1174 break;
1175 }
anthony74b1cfc2011-10-06 12:44:16 +00001176 if (LocaleCompare("ping",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001177 {
anthonydcf510d2011-10-30 13:51:40 +00001178 image_info->ping= IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +00001179 break;
1180 }
anthony74b1cfc2011-10-06 12:44:16 +00001181 if (LocaleCompare("pointsize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001182 {
anthonydcf510d2011-10-30 13:51:40 +00001183 double
1184 value=12.0;
1185
1186 if (IfSetOption)
cristydbdd0e32011-11-04 23:29:40 +00001187 StringToDouble(arg,(char **) NULL);
anthonydcf510d2011-10-30 13:51:40 +00001188 image_info->pointsize=draw_info->pointsize=value;
anthony805a2d42011-09-25 08:25:12 +00001189 break;
1190 }
anthony74b1cfc2011-10-06 12:44:16 +00001191 if (LocaleCompare("precision",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001192 {
anthonydcf510d2011-10-30 13:51:40 +00001193 (void) SetMagickPrecision(StringToInteger(arg));
anthony805a2d42011-09-25 08:25:12 +00001194 break;
1195 }
anthonydcf510d2011-10-30 13:51:40 +00001196 /* FUTURE: Only the 'preview' coder appears to use this
1197 * Depreciate the coder? Leaving only the 'preview' operator.
anthony74b1cfc2011-10-06 12:44:16 +00001198 if (LocaleCompare("preview",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001199 {
anthonydcf510d2011-10-30 13:51:40 +00001200 image_info->preview_type=UndefinedPreview;
1201 if (IfSetOption)
1202 image_info->preview_type=(PreviewType) ParseCommandOption(
1203 MagickPreviewOptions,MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +00001204 break;
1205 }
anthonydcf510d2011-10-30 13:51:40 +00001206 */
anthony805a2d42011-09-25 08:25:12 +00001207 break;
1208 }
1209 case 'q':
1210 {
anthony74b1cfc2011-10-06 12:44:16 +00001211 if (LocaleCompare("quality",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001212 {
anthonydcf510d2011-10-30 13:51:40 +00001213 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001214 {
anthonydcf510d2011-10-30 13:51:40 +00001215 image_info->quality=StringToUnsignedLong(arg);
1216 (void) SetImageOption(image_info,option,arg);
anthony805a2d42011-09-25 08:25:12 +00001217 break;
1218 }
anthonydcf510d2011-10-30 13:51:40 +00001219 image_info->quality=UndefinedCompressionQuality;
1220 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001221 break;
1222 }
anthonyafbaed72011-10-26 12:05:04 +00001223 if (LocaleCompare("quantize",option) == 0)
1224 {
1225 /* no image_info setting! Only set direct in quantize_info */
1226 quantize_info->colorspace=UndefinedColorspace;
1227 if (IfSetOption)
1228 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00001229 MagickColorspaceOptions,MagickFalse,arg);
anthonyafbaed72011-10-26 12:05:04 +00001230 break;
1231 }
anthony74b1cfc2011-10-06 12:44:16 +00001232 if (LocaleCompare("quiet",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001233 {
anthonydcf510d2011-10-30 13:51:40 +00001234 /* FUTURE: if two -quiet is performed you can not do +quiet! */
anthony805a2d42011-09-25 08:25:12 +00001235 static WarningHandler
1236 warning_handler = (WarningHandler) NULL;
anthonyafbaed72011-10-26 12:05:04 +00001237 WarningHandler
1238 tmp = SetWarningHandler((WarningHandler) NULL);
anthony805a2d42011-09-25 08:25:12 +00001239
anthonyafbaed72011-10-26 12:05:04 +00001240 if ( tmp != (WarningHandler) NULL)
1241 warning_handler = tmp; /* remember the old handler */
1242 if (!IfSetOption) /* set the old handler */
1243 warning_handler=SetWarningHandler(warning_handler);
anthony805a2d42011-09-25 08:25:12 +00001244 break;
1245 }
1246 break;
1247 }
1248 case 'r':
1249 {
anthony74b1cfc2011-10-06 12:44:16 +00001250 if (LocaleCompare("red-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001251 {
anthonydcf510d2011-10-30 13:51:40 +00001252 /* Image chromaticity X,Y NB: Y=X if Y not defined
1253 Used by many coders
1254 */
1255 (void) SetImageOption(image_info,option,
1256 IfSetOption ? arg : "0" );
anthony805a2d42011-09-25 08:25:12 +00001257 break;
1258 }
anthonyafbaed72011-10-26 12:05:04 +00001259 if (LocaleCompare("render",option) == 0)
1260 {
1261 /* draw_info only setting */
1262 draw_info->render= IfSetOption ? MagickFalse : MagickTrue;
1263 break;
1264 }
anthony805a2d42011-09-25 08:25:12 +00001265 break;
1266 }
1267 case 's':
1268 {
anthony74b1cfc2011-10-06 12:44:16 +00001269 if (LocaleCompare("sampling-factor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001270 {
anthonyafbaed72011-10-26 12:05:04 +00001271 /* FUTURE: should be converted to jpeg:sampling_factor */
1272 (void) CloneString(&image_info->sampling_factor,
anthonydcf510d2011-10-30 13:51:40 +00001273 IfSetOption ? arg : (char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001274 break;
1275 }
anthony74b1cfc2011-10-06 12:44:16 +00001276 if (LocaleCompare("scene",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001277 {
anthonyafbaed72011-10-26 12:05:04 +00001278 char
anthonydcf510d2011-10-30 13:51:40 +00001279 *value = IfSetOption ? arg : "0";
anthonyafbaed72011-10-26 12:05:04 +00001280
1281 (void) SetImageOption(image_info,option,value);
1282 image_info->scene=StringToUnsignedLong(value);
anthony805a2d42011-09-25 08:25:12 +00001283 break;
1284 }
anthony74b1cfc2011-10-06 12:44:16 +00001285 if (LocaleCompare("seed",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001286 {
anthonyafbaed72011-10-26 12:05:04 +00001287 SeedPseudoRandomGenerator(
anthonydcf510d2011-10-30 13:51:40 +00001288 IfSetOption ? (size_t) StringToUnsignedLong(arg)
anthonyafbaed72011-10-26 12:05:04 +00001289 : (size_t) time((time_t *) NULL) );
anthony805a2d42011-09-25 08:25:12 +00001290 break;
1291 }
anthony74b1cfc2011-10-06 12:44:16 +00001292 if (LocaleCompare("size",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001293 {
anthonyafbaed72011-10-26 12:05:04 +00001294 /* FUTURE: string in image_info -- convert to Option ???
1295 Look at the special handling for "size" in SetImageOption()
anthony74b1cfc2011-10-06 12:44:16 +00001296 */
anthonyafbaed72011-10-26 12:05:04 +00001297 (void) CloneString(&image_info->size,
anthonydcf510d2011-10-30 13:51:40 +00001298 IfSetOption ? arg : (char *) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001299 break;
1300 }
1301 if (LocaleCompare("stretch",option) == 0)
1302 {
1303 draw_info->stretch=UndefinedStretch;
1304 if (IfSetOption)
1305 draw_info->stretch=(StretchType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00001306 MagickStretchOptions,MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +00001307 break;
1308 }
anthony74b1cfc2011-10-06 12:44:16 +00001309 if (LocaleCompare("stroke",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001310 {
anthonyafbaed72011-10-26 12:05:04 +00001311 /* set stroke color OR stroke-pattern
1312 color is only used by draw_info
1313 but draw_info is only initialsed using the color not the pattern
1314 */
1315 const char
anthonydcf510d2011-10-30 13:51:40 +00001316 *value = IfSetOption ? arg : "none";
anthonyafbaed72011-10-26 12:05:04 +00001317
1318 ExceptionInfo
1319 *sans;
1320
1321 (void) SetImageOption(image_info,option,value);
1322
1323 sans=AcquireExceptionInfo();
1324 status=QueryColorCompliance(value,AllCompliance,&draw_info->stroke,
1325 sans);
1326 sans=DestroyExceptionInfo(sans);
1327
1328 if (draw_info->stroke_pattern != (Image *) NULL)
1329 draw_info->stroke_pattern=DestroyImage(draw_info->stroke_pattern);
1330 if (status == MagickFalse)
1331 draw_info->stroke_pattern=GetImageCache(image_info,value,
1332 exception);
anthony805a2d42011-09-25 08:25:12 +00001333 break;
1334 }
anthony74b1cfc2011-10-06 12:44:16 +00001335 if (LocaleCompare("strokewidth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001336 {
anthonyafbaed72011-10-26 12:05:04 +00001337 const char
anthonydcf510d2011-10-30 13:51:40 +00001338 *value = IfSetOption ? arg : "1.0";
anthonyafbaed72011-10-26 12:05:04 +00001339 (void) SetImageOption(image_info,option,value);
cristydbdd0e32011-11-04 23:29:40 +00001340 draw_info->stroke_width=StringToDouble(value,(char **) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001341 break;
1342 }
1343 if (LocaleCompare("style",option) == 0)
1344 {
1345 draw_info->style=UndefinedStyle;
1346 if (IfSetOption)
1347 draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
anthonydcf510d2011-10-30 13:51:40 +00001348 MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +00001349 break;
1350 }
anthony74b1cfc2011-10-06 12:44:16 +00001351 if (LocaleCompare("synchronize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001352 {
anthonyafbaed72011-10-26 12:05:04 +00001353 image_info->synchronize=IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +00001354 break;
1355 }
1356 break;
1357 }
1358 case 't':
1359 {
anthony74b1cfc2011-10-06 12:44:16 +00001360 if (LocaleCompare("taint",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001361 {
anthonyafbaed72011-10-26 12:05:04 +00001362 (void) SetImageOption(image_info,option,
1363 IfSetOption ? "true" : "false");
anthony805a2d42011-09-25 08:25:12 +00001364 break;
1365 }
anthony74b1cfc2011-10-06 12:44:16 +00001366 if (LocaleCompare("texture",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001367 {
anthonyafbaed72011-10-26 12:05:04 +00001368 /* FUTURE: move image_info string to option splay-tree */
1369 (void) CloneString(&image_info->texture,
anthonydcf510d2011-10-30 13:51:40 +00001370 IfSetOption ? arg : (char *) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001371 break;
1372 }
1373 if (LocaleCompare("tile",option) == 0)
1374 {
1375 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
1376 if (IfSetOption)
anthonydcf510d2011-10-30 13:51:40 +00001377 draw_info->fill_pattern=GetImageCache(image_info,arg,exception);
anthony805a2d42011-09-25 08:25:12 +00001378 break;
1379 }
anthony74b1cfc2011-10-06 12:44:16 +00001380 if (LocaleCompare("tile-offset",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001381 {
anthonyafbaed72011-10-26 12:05:04 +00001382 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +00001383 IfSetOption ? arg : "0");
anthony805a2d42011-09-25 08:25:12 +00001384 break;
1385 }
anthony74b1cfc2011-10-06 12:44:16 +00001386 if (LocaleCompare("transparent-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001387 {
anthonyafbaed72011-10-26 12:05:04 +00001388 /* FUTURE: both image_info attribute & ImageOption in use!
1389 image_info only used for generating new images.
1390 Note that +transparent-color, means fall-back to image
1391 attribute so ImageOption is deleted, not set to a default.
1392 */
1393 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001394 {
anthonydcf510d2011-10-30 13:51:40 +00001395 (void) SetImageOption(image_info,option,arg);
1396 (void) QueryColorCompliance(arg,AllCompliance,
anthonyafbaed72011-10-26 12:05:04 +00001397 image_info->transparent_color,exception);
anthony805a2d42011-09-25 08:25:12 +00001398 break;
1399 }
anthonyafbaed72011-10-26 12:05:04 +00001400 (void) DeleteImageOption(image_info,option);
1401 (void) QueryColorCompliance("none",AllCompliance,
1402 image_info->transparent_color,exception);
anthony805a2d42011-09-25 08:25:12 +00001403 break;
1404 }
anthony74b1cfc2011-10-06 12:44:16 +00001405 if (LocaleCompare("type",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001406 {
anthonyab3a50c2011-10-27 11:48:57 +00001407 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +00001408 IfSetOption ? arg : (char) NULL);
anthonyab3a50c2011-10-27 11:48:57 +00001409 image_info->type=UndefinedType;
1410 if (IfSetOption)
1411 image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
anthonydcf510d2011-10-30 13:51:40 +00001412 MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +00001413 break;
1414 }
1415 break;
1416 }
1417 case 'u':
1418 {
anthony74b1cfc2011-10-06 12:44:16 +00001419 if (LocaleCompare("undercolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001420 {
anthonyab3a50c2011-10-27 11:48:57 +00001421 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +00001422 IfSetOption ? arg : (char) NULL);
1423 (void) QueryColorCompliance(arg,AllCompliance,
anthonyab3a50c2011-10-27 11:48:57 +00001424 draw_info->undercolor,exception);
anthony805a2d42011-09-25 08:25:12 +00001425 break;
1426 }
anthony74b1cfc2011-10-06 12:44:16 +00001427 if (LocaleCompare("units",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001428 {
anthonyab3a50c2011-10-27 11:48:57 +00001429 /* Set in images via SyncImageSettings() */
1430 /* Should this effect draw_info X and Y resolution? */
1431 /* FUTURE: this probably should be part of the density setting */
1432 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +00001433 IfSetOption ? arg : (char) NULL);
anthonyab3a50c2011-10-27 11:48:57 +00001434 image_info->units=UndefinedResolution;
1435 if (IfSetOption)
1436 image_info->units=(ResolutionType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00001437 MagickResolutionOptions,MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +00001438 break;
1439 }
1440 break;
1441 }
1442 case 'v':
1443 {
anthony74b1cfc2011-10-06 12:44:16 +00001444 if (LocaleCompare("verbose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001445 {
anthonyab3a50c2011-10-27 11:48:57 +00001446 /* FUTURE: Also an image artifact, set in Simple Operators.
1447 But artifact is only used in verbose output.
1448 */
1449 image_info->verbose= IfSetOption ? MagickTrue : MagickFalse;
1450 image_info->ping=MagickFalse; /* verbose can't be a ping */
anthony805a2d42011-09-25 08:25:12 +00001451 break;
1452 }
anthony74b1cfc2011-10-06 12:44:16 +00001453 if (LocaleCompare("view",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001454 {
anthonyab3a50c2011-10-27 11:48:57 +00001455 /* FUTURE: Convert from image_info to Option
1456 Only used by coder FPX
1457 */
1458 (void) CloneString(&image_info->view,
anthonydcf510d2011-10-30 13:51:40 +00001459 IfSetOption ? arg : (char) NULL);
anthony805a2d42011-09-25 08:25:12 +00001460 break;
1461 }
anthony74b1cfc2011-10-06 12:44:16 +00001462 if (LocaleCompare("virtual-pixel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001463 {
anthonyab3a50c2011-10-27 11:48:57 +00001464 /* Also used as a 'image' option deep in image structure */
1465 const char
anthonydcf510d2011-10-30 13:51:40 +00001466 *value = IfSetOption ? arg : "undefined";
anthonyab3a50c2011-10-27 11:48:57 +00001467
1468 (void) SetImageOption(image_info,option,value);
anthony805a2d42011-09-25 08:25:12 +00001469 image_info->virtual_pixel_method=(VirtualPixelMethod)
anthonyab3a50c2011-10-27 11:48:57 +00001470 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,value);
anthony805a2d42011-09-25 08:25:12 +00001471 break;
1472 }
1473 break;
1474 }
1475 case 'w':
1476 {
anthonydcf510d2011-10-30 13:51:40 +00001477 if (LocaleCompare("weight",option) == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001478 {
1479 /* FUTURE: relative weights not sensical due to first assignment!
1480 Also just what is actually using font 'weight' ???
anthonydcf510d2011-10-30 13:51:40 +00001481 There is no "-list weight" output (reference manual says there is)
anthonyab3a50c2011-10-27 11:48:57 +00001482 */
anthonydcf510d2011-10-30 13:51:40 +00001483 draw_info->weight=StringToUnsignedLong(arg);
1484 if (LocaleCompare(arg,"all") == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001485 draw_info->weight=0;
anthonydcf510d2011-10-30 13:51:40 +00001486 if (LocaleCompare(arg,"bold") == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001487 draw_info->weight=700;
anthonydcf510d2011-10-30 13:51:40 +00001488 if (LocaleCompare(arg,"bolder") == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001489 if (draw_info->weight <= 800)
1490 draw_info->weight+=100;
anthonydcf510d2011-10-30 13:51:40 +00001491 if (LocaleCompare(arg,"lighter") == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001492 if (draw_info->weight >= 100)
1493 draw_info->weight-=100;
anthonydcf510d2011-10-30 13:51:40 +00001494 if (LocaleCompare(arg,"normal") == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001495 draw_info->weight=400;
1496 break;
1497 }
anthony74b1cfc2011-10-06 12:44:16 +00001498 if (LocaleCompare("white-point",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001499 {
anthonydcf510d2011-10-30 13:51:40 +00001500 /* Used as a image chromaticity setting */
1501 (void) SetImageOption(image_info,option,
1502 IfSetOption ? arg : "0.0" );
anthony805a2d42011-09-25 08:25:12 +00001503 break;
1504 }
1505 break;
1506 }
1507 default:
1508 break;
1509 }
1510 return(MagickTrue);
1511}
1512
1513/*
1514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1515% %
1516% %
1517% %
anthony74b1cfc2011-10-06 12:44:16 +00001518+ A p p l y I m a g e O p e r a t o r %
anthony805a2d42011-09-25 08:25:12 +00001519% %
1520% %
1521% %
1522%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1523%
anthonydcf510d2011-10-30 13:51:40 +00001524% ApplyImageOperator() apply one simple image operation to the current
1525% image pointed to by the CLI wand, with the settings that are saved in the
1526% CLI wand.
anthony805a2d42011-09-25 08:25:12 +00001527%
1528% The image in the list may be modified in three different ways...
1529%
1530% * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1531% * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1532% * replace by a list of images (-separate and -crop only!)
1533%
anthonydcf510d2011-10-30 13:51:40 +00001534% In each case the result replaces the original image in the list, as well as
1535% the pointer to the modified image (last image added if replaced by a list
1536% of images) is returned. As the image pointed to may be replaced, the first
1537% image in the list may also change. GetFirstImageInList() should be used by
1538% caller if they wish return the Image pointer to the first image in list.
1539%
1540% It is assumed that any per-image settings are up-to-date with respect to
1541% extra settings that have been saved in the wand.
anthony805a2d42011-09-25 08:25:12 +00001542%
anthony74b1cfc2011-10-06 12:44:16 +00001543% The format of the ApplyImageOperator method is:
anthony805a2d42011-09-25 08:25:12 +00001544%
anthony74b1cfc2011-10-06 12:44:16 +00001545% MagickBooleanType ApplyImageOperator(MagickWand *wand,
anthonydcf510d2011-10-30 13:51:40 +00001546% const char *option, const MagickBooleanType set_option, const char
1547% **args, ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +00001548%
1549% A description of each parameter follows:
1550%
anthonydcf510d2011-10-30 13:51:40 +00001551% o wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +00001552%
anthonydcf510d2011-10-30 13:51:40 +00001553% o option: The option string to be set
anthony805a2d42011-09-25 08:25:12 +00001554%
anthonydcf510d2011-10-30 13:51:40 +00001555% o set_option: is the option being set, or reset to some default
1556%
1557% o arg: the single argument (if needed) to set this option.
anthony805a2d42011-09-25 08:25:12 +00001558%
anthony805a2d42011-09-25 08:25:12 +00001559% o exception: return any errors or warnings in this structure.
1560%
anthonydcf510d2011-10-30 13:51:40 +00001561%
1562% Example usage (FUTURE)
1563%
1564% argc,argv
1565% i=index in argv
1566%
1567% count=ParseCommandOption(MagickCommandOptions,MagickFalse,argv[i]);
1568% flags=GetCommandOptionFlags(MagickCommandOptions,MagickFalse,argv[i]);
1569% if ( flags == MagickCommandOptions )
1570% ApplySettingsOption(wand, argv[i]+1,
1571% (*argv[i])=='-' ? MagickTrue : MagickFalse,
1572% argv+i+1, exception);
1573% i += count+1;
1574%
anthony805a2d42011-09-25 08:25:12 +00001575*/
anthonydcf510d2011-10-30 13:51:40 +00001576WandExport MagickBooleanType ApplySettingsOption(MagickWand *wand,
1577 const char *option, const MagickBooleanType set_option, const char **args,
1578 ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +00001579{
1580 Image *
1581 new_image;
1582
anthony805a2d42011-09-25 08:25:12 +00001583 GeometryInfo
1584 geometry_info;
1585
1586 RectangleInfo
1587 geometry;
1588
1589 MagickStatusType
1590 status;
1591
anthony805a2d42011-09-25 08:25:12 +00001592 MagickStatusType
1593 flags;
1594
anthony805a2d42011-09-25 08:25:12 +00001595 assert(image_info != (const ImageInfo *) NULL);
1596 assert(image_info->signature == MagickSignature);
anthonydcf510d2011-10-30 13:51:40 +00001597 assert(wand->draw_info != (DrawInfo *) NULL); /* ensure it is a CLI wand */
1598 assert(image != (Image **) NULL); /* there is an image */
anthony805a2d42011-09-25 08:25:12 +00001599 assert((*image)->signature == MagickSignature);
anthonydcf510d2011-10-30 13:51:40 +00001600
1601 if (wand->debug != MagickFalse)
1602 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1603
anthony805a2d42011-09-25 08:25:12 +00001604 SetGeometryInfo(&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001605
anthonydcf510d2011-10-30 13:51:40 +00001606 new_image = (Image *)NULL; /* the replacement image, if not null at end */
anthony805a2d42011-09-25 08:25:12 +00001607
anthonydcf510d2011-10-30 13:51:40 +00001608 /* We need somthing more optimized than this! */
1609 (void) SyncImageSettings(image_info,*image,exception);
1610
1611 switch (*option)
anthony805a2d42011-09-25 08:25:12 +00001612 {
1613 case 'a':
1614 {
anthonydcf510d2011-10-30 13:51:40 +00001615 if (LocaleCompare("adaptive-blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001616 {
anthonydcf510d2011-10-30 13:51:40 +00001617 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001618 if ((flags & SigmaValue) == 0)
1619 geometry_info.sigma=1.0;
1620 if ((flags & XiValue) == 0)
1621 geometry_info.xi=0.0;
1622 new_image=AdaptiveBlurImage(*image,geometry_info.rho,
1623 geometry_info.sigma,geometry_info.xi,exception);
1624 break;
1625 }
anthonydcf510d2011-10-30 13:51:40 +00001626 if (LocaleCompare("adaptive-resize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001627 {
anthony1afdc7a2011-10-05 11:54:28 +00001628 /* FUTURE: this is really a "interpolate-resize" operator
1629 "adaptive-resize" uses a fixed "Mesh" interpolation
anthony805a2d42011-09-25 08:25:12 +00001630 */
anthonydcf510d2011-10-30 13:51:40 +00001631 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00001632 new_image=AdaptiveResizeImage(*image,geometry.width,
anthonya89dd172011-10-04 13:29:35 +00001633 geometry.height,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00001634 break;
1635 }
anthonydcf510d2011-10-30 13:51:40 +00001636 if (LocaleCompare("adaptive-sharpen",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001637 {
1638 /*
1639 Adaptive sharpen image.
1640 */
cristy6fccee12011-10-20 18:43:18 +00001641 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001642 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001643 if ((flags & SigmaValue) == 0)
1644 geometry_info.sigma=1.0;
1645 if ((flags & XiValue) == 0)
1646 geometry_info.xi=0.0;
1647 new_image=AdaptiveSharpenImage(*image,geometry_info.rho,
1648 geometry_info.sigma,geometry_info.xi,exception);
1649 break;
1650 }
anthonydcf510d2011-10-30 13:51:40 +00001651 if (LocaleCompare("alpha",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001652 {
1653 AlphaChannelType
1654 alpha_type;
1655
cristy6fccee12011-10-20 18:43:18 +00001656 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001657 alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
anthonydcf510d2011-10-30 13:51:40 +00001658 MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00001659 (void) SetImageAlphaChannel(*image,alpha_type,exception);
1660 break;
1661 }
anthonydcf510d2011-10-30 13:51:40 +00001662 if (LocaleCompare("annotate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001663 {
1664 char
1665 *text,
1666 geometry[MaxTextExtent];
1667
cristy6fccee12011-10-20 18:43:18 +00001668 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001669 SetGeometryInfo(&geometry_info);
anthonydcf510d2011-10-30 13:51:40 +00001670 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001671 if ((flags & SigmaValue) == 0)
1672 geometry_info.sigma=geometry_info.rho;
1673 text=InterpretImageProperties(image_info,*image,argv[2],
1674 exception);
1675 if (text == (char *) NULL)
1676 break;
1677 (void) CloneString(&draw_info->text,text);
1678 text=DestroyString(text);
1679 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1680 geometry_info.xi,geometry_info.psi);
1681 (void) CloneString(&draw_info->geometry,geometry);
1682 draw_info->affine.sx=cos(DegreesToRadians(
1683 fmod(geometry_info.rho,360.0)));
1684 draw_info->affine.rx=sin(DegreesToRadians(
1685 fmod(geometry_info.rho,360.0)));
1686 draw_info->affine.ry=(-sin(DegreesToRadians(
1687 fmod(geometry_info.sigma,360.0))));
1688 draw_info->affine.sy=cos(DegreesToRadians(
1689 fmod(geometry_info.sigma,360.0)));
1690 (void) AnnotateImage(*image,draw_info,exception);
1691 break;
1692 }
anthonydcf510d2011-10-30 13:51:40 +00001693 if (LocaleCompare("auto-gamma",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001694 {
1695 /*
1696 Auto Adjust Gamma of image based on its mean
1697 */
cristy6fccee12011-10-20 18:43:18 +00001698 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001699 (void) AutoGammaImage(*image,exception);
1700 break;
1701 }
anthonydcf510d2011-10-30 13:51:40 +00001702 if (LocaleCompare("auto-level",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001703 {
1704 /*
1705 Perfectly Normalize (max/min stretch) the image
1706 */
cristy6fccee12011-10-20 18:43:18 +00001707 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001708 (void) AutoLevelImage(*image,exception);
1709 break;
1710 }
anthonydcf510d2011-10-30 13:51:40 +00001711 if (LocaleCompare("auto-orient",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001712 {
cristy6fccee12011-10-20 18:43:18 +00001713 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001714 switch ((*image)->orientation)
1715 {
1716 case TopRightOrientation:
1717 {
1718 new_image=FlopImage(*image,exception);
1719 break;
1720 }
1721 case BottomRightOrientation:
1722 {
1723 new_image=RotateImage(*image,180.0,exception);
1724 break;
1725 }
1726 case BottomLeftOrientation:
1727 {
1728 new_image=FlipImage(*image,exception);
1729 break;
1730 }
1731 case LeftTopOrientation:
1732 {
1733 new_image=TransposeImage(*image,exception);
1734 break;
1735 }
1736 case RightTopOrientation:
1737 {
1738 new_image=RotateImage(*image,90.0,exception);
1739 break;
1740 }
1741 case RightBottomOrientation:
1742 {
1743 new_image=TransverseImage(*image,exception);
1744 break;
1745 }
1746 case LeftBottomOrientation:
1747 {
1748 new_image=RotateImage(*image,270.0,exception);
1749 break;
1750 }
1751 default:
1752 break;
1753 }
1754 if (new_image != (Image *) NULL)
1755 new_image->orientation=TopLeftOrientation;
1756 break;
1757 }
1758 break;
1759 }
1760 case 'b':
1761 {
anthonydcf510d2011-10-30 13:51:40 +00001762 if (LocaleCompare("black-threshold",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001763 {
cristy6fccee12011-10-20 18:43:18 +00001764 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001765 (void) BlackThresholdImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00001766 break;
1767 }
anthonydcf510d2011-10-30 13:51:40 +00001768 if (LocaleCompare("blue-shift",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001769 {
cristy6fccee12011-10-20 18:43:18 +00001770 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001771 geometry_info.rho=1.5;
1772 if (*argv[0] == '-')
anthonydcf510d2011-10-30 13:51:40 +00001773 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001774 new_image=BlueShiftImage(*image,geometry_info.rho,exception);
1775 break;
1776 }
anthonydcf510d2011-10-30 13:51:40 +00001777 if (LocaleCompare("blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001778 {
anthony74b1cfc2011-10-06 12:44:16 +00001779 /* FUTURE: use of "bias" in a blur is non-sensible */
cristy6fccee12011-10-20 18:43:18 +00001780 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001781 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001782 if ((flags & SigmaValue) == 0)
1783 geometry_info.sigma=1.0;
1784 if ((flags & XiValue) == 0)
1785 geometry_info.xi=0.0;
1786 new_image=BlurImage(*image,geometry_info.rho,
1787 geometry_info.sigma,geometry_info.xi,exception);
1788 break;
1789 }
anthonydcf510d2011-10-30 13:51:40 +00001790 if (LocaleCompare("border",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001791 {
anthony5f867ae2011-10-09 10:28:34 +00001792 ComposeOperator
1793 compose;
1794
1795 const char*
1796 const char*
1797 value;
1798
1799 value=GetImageOption(image_info,"compose");
1800 if (value != (const char *) NULL)
1801 compose=(CompositeOperator) ParseCommandOption(
1802 MagickComposeOptions,MagickFalse,value);
1803 else
1804 compose=OverCompositeOp; /* use Over not image->compose */
1805
cristy6fccee12011-10-20 18:43:18 +00001806 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001807 flags=ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00001808 if ((flags & SigmaValue) == 0)
1809 geometry.height=geometry.width;
anthonya89dd172011-10-04 13:29:35 +00001810 new_image=BorderImage(*image,&geometry,compose,exception);
anthony805a2d42011-09-25 08:25:12 +00001811 break;
1812 }
anthonydcf510d2011-10-30 13:51:40 +00001813 if (LocaleCompare("brightness-contrast",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001814 {
1815 double
1816 brightness,
1817 contrast;
1818
1819 GeometryInfo
1820 geometry_info;
1821
1822 MagickStatusType
1823 flags;
1824
cristy6fccee12011-10-20 18:43:18 +00001825 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001826 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001827 brightness=geometry_info.rho;
1828 contrast=0.0;
1829 if ((flags & SigmaValue) != 0)
1830 contrast=geometry_info.sigma;
1831 (void) BrightnessContrastImage(*image,brightness,contrast,
1832 exception);
anthony805a2d42011-09-25 08:25:12 +00001833 break;
1834 }
1835 break;
1836 }
1837 case 'c':
1838 {
anthonydcf510d2011-10-30 13:51:40 +00001839 if (LocaleCompare("cdl",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001840 {
1841 char
1842 *color_correction_collection;
1843
1844 /*
1845 Color correct with a color decision list.
1846 */
cristy6fccee12011-10-20 18:43:18 +00001847 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001848 color_correction_collection=FileToString(args[0],~0,exception);
anthony805a2d42011-09-25 08:25:12 +00001849 if (color_correction_collection == (char *) NULL)
1850 break;
1851 (void) ColorDecisionListImage(*image,color_correction_collection,
1852 exception);
anthony805a2d42011-09-25 08:25:12 +00001853 break;
1854 }
anthonydcf510d2011-10-30 13:51:40 +00001855 if (LocaleCompare("channel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001856 {
anthony74b1cfc2011-10-06 12:44:16 +00001857 /* The "channel" setting has already been set */
anthony80c37752012-01-16 01:03:11 +00001858 SetPixelChannelMapMask(*image,image_info->channel);
anthony805a2d42011-09-25 08:25:12 +00001859 break;
1860 }
anthonydcf510d2011-10-30 13:51:40 +00001861 if (LocaleCompare("charcoal",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001862 {
cristy6fccee12011-10-20 18:43:18 +00001863 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001864 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001865 if ((flags & SigmaValue) == 0)
1866 geometry_info.sigma=1.0;
1867 if ((flags & XiValue) == 0)
1868 geometry_info.xi=1.0;
1869 new_image=CharcoalImage(*image,geometry_info.rho,
1870 geometry_info.sigma,geometry_info.xi,exception);
1871 break;
1872 }
anthonydcf510d2011-10-30 13:51:40 +00001873 if (LocaleCompare("chop",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001874 {
cristy6fccee12011-10-20 18:43:18 +00001875 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001876 (void) ParseGravityGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00001877 new_image=ChopImage(*image,&geometry,exception);
1878 break;
1879 }
anthonydcf510d2011-10-30 13:51:40 +00001880 if (LocaleCompare("clamp",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001881 {
cristy6fccee12011-10-20 18:43:18 +00001882 (void) SyncImageSettings(image_info,*image,exception);
cristy092d71c2011-10-14 18:01:29 +00001883 (void) ClampImage(*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001884 break;
1885 }
anthonydcf510d2011-10-30 13:51:40 +00001886 if (LocaleCompare("clip",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001887 {
cristy6fccee12011-10-20 18:43:18 +00001888 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001889 if (*argv[0] == '+')
1890 {
1891 (void) SetImageClipMask(*image,(Image *) NULL,exception);
1892 break;
1893 }
1894 (void) ClipImage(*image,exception);
1895 break;
1896 }
anthonydcf510d2011-10-30 13:51:40 +00001897 if (LocaleCompare("clip-mask",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001898 {
1899 CacheView
1900 *mask_view;
1901
1902 Image
1903 *mask_image;
1904
1905 register Quantum
1906 *restrict q;
1907
1908 register ssize_t
1909 x;
1910
1911 ssize_t
1912 y;
1913
cristy6fccee12011-10-20 18:43:18 +00001914 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001915 if (*argv[0] == '+')
1916 {
anthony74b1cfc2011-10-06 12:44:16 +00001917 /* Remove the write mask */
anthony805a2d42011-09-25 08:25:12 +00001918 (void) SetImageMask(*image,(Image *) NULL,exception);
1919 break;
1920 }
anthonydcf510d2011-10-30 13:51:40 +00001921 mask_image=GetImageCache(image_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00001922 if (mask_image == (Image *) NULL)
1923 break;
1924 if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
1925 return(MagickFalse);
anthony74b1cfc2011-10-06 12:44:16 +00001926 /* create a write mask from clip-mask image */
1927 /* FUTURE: use Alpha operations instead */
anthony805a2d42011-09-25 08:25:12 +00001928 mask_view=AcquireCacheView(mask_image);
1929 for (y=0; y < (ssize_t) mask_image->rows; y++)
1930 {
1931 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
1932 exception);
1933 if (q == (Quantum *) NULL)
1934 break;
1935 for (x=0; x < (ssize_t) mask_image->columns; x++)
1936 {
1937 if (mask_image->matte == MagickFalse)
1938 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1939 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1940 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1941 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1942 q+=GetPixelChannels(mask_image);
1943 }
1944 if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
1945 break;
1946 }
anthony74b1cfc2011-10-06 12:44:16 +00001947 /* set the write mask */
anthony805a2d42011-09-25 08:25:12 +00001948 mask_view=DestroyCacheView(mask_view);
1949 mask_image->matte=MagickTrue;
anthonya89dd172011-10-04 13:29:35 +00001950 (void) SetImageClipMask(*image,mask_image,exception);
anthony805a2d42011-09-25 08:25:12 +00001951 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00001952 break;
1953 }
anthonydcf510d2011-10-30 13:51:40 +00001954 if (LocaleCompare("clip-path",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001955 {
cristy6fccee12011-10-20 18:43:18 +00001956 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001957 (void) ClipImagePath(*image,args[0],*argv[0] == '-' ? MagickTrue :
anthony805a2d42011-09-25 08:25:12 +00001958 MagickFalse,exception);
1959 break;
1960 }
anthonydcf510d2011-10-30 13:51:40 +00001961 if (LocaleCompare("colorize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001962 {
cristy6fccee12011-10-20 18:43:18 +00001963 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001964 new_image=ColorizeImage(*image,args[0],draw_info->fill,
anthony805a2d42011-09-25 08:25:12 +00001965 exception);
1966 break;
1967 }
anthonydcf510d2011-10-30 13:51:40 +00001968 if (LocaleCompare("color-matrix",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001969 {
1970 KernelInfo
1971 *kernel;
1972
cristy6fccee12011-10-20 18:43:18 +00001973 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001974 kernel=AcquireKernelInfo(args[0]);
anthony805a2d42011-09-25 08:25:12 +00001975 if (kernel == (KernelInfo *) NULL)
1976 break;
1977 new_image=ColorMatrixImage(*image,kernel,exception);
1978 kernel=DestroyKernelInfo(kernel);
1979 break;
1980 }
anthonydcf510d2011-10-30 13:51:40 +00001981 if (LocaleCompare("colors",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001982 {
anthony74b1cfc2011-10-06 12:44:16 +00001983 /* Reduce the number of colors in the image. */
cristy6fccee12011-10-20 18:43:18 +00001984 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001985 quantize_info->number_colors=StringToUnsignedLong(args[0]);
anthony805a2d42011-09-25 08:25:12 +00001986 if (quantize_info->number_colors == 0)
1987 break;
1988 if (((*image)->storage_class == DirectClass) ||
1989 (*image)->colors > quantize_info->number_colors)
1990 (void) QuantizeImage(quantize_info,*image,exception);
1991 else
1992 (void) CompressImageColormap(*image,exception);
1993 break;
1994 }
anthonydcf510d2011-10-30 13:51:40 +00001995 if (LocaleCompare("colorspace",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001996 {
anthonyd2cdc862011-10-07 14:07:17 +00001997 /* This is a Image Setting, which should already been set */
1998 /* FUTURE: default colorspace should be sRGB!
1999 Unless some type of 'linear colorspace' mode is set.
2000 Note that +colorspace sets "undefined" or no effect on
2001 new images, but forces images already in memory back to RGB!
2002 */
cristy6fccee12011-10-20 18:43:18 +00002003 (void) SyncImageSettings(image_info,*image,exception);
anthonyd2cdc862011-10-07 14:07:17 +00002004 (void) TransformImageColorspace(*image,
anthony6613bf32011-10-15 07:24:44 +00002005 IfSetOption ? image_info->colorspace : RGBColorspace,
2006 exception);
anthony805a2d42011-09-25 08:25:12 +00002007 break;
2008 }
anthonydcf510d2011-10-30 13:51:40 +00002009 if (LocaleCompare("contrast",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002010 {
cristy6fccee12011-10-20 18:43:18 +00002011 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002012 (void) ContrastImage(*image,(*argv[0] == '-') ? MagickTrue :
2013 MagickFalse,exception);
2014 break;
2015 }
anthonydcf510d2011-10-30 13:51:40 +00002016 if (LocaleCompare("contrast-stretch",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002017 {
2018 double
2019 black_point,
2020 white_point;
2021
2022 MagickStatusType
2023 flags;
2024
2025 /*
2026 Contrast stretch image.
2027 */
cristy6fccee12011-10-20 18:43:18 +00002028 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002029 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002030 black_point=geometry_info.rho;
2031 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2032 black_point;
2033 if ((flags & PercentValue) != 0)
2034 {
2035 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2036 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2037 }
2038 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2039 white_point;
2040 (void) ContrastStretchImage(*image,black_point,white_point,
2041 exception);
anthony805a2d42011-09-25 08:25:12 +00002042 break;
2043 }
anthonydcf510d2011-10-30 13:51:40 +00002044 if (LocaleCompare("convolve",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002045 {
2046 KernelInfo
2047 *kernel_info;
2048
cristy6fccee12011-10-20 18:43:18 +00002049 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002050 kernel_info=AcquireKernelInfo(args[0]);
anthony805a2d42011-09-25 08:25:12 +00002051 if (kernel_info == (KernelInfo *) NULL)
2052 break;
2053 kernel_info->bias=(*image)->bias;
2054 new_image=ConvolveImage(*image,kernel_info,exception);
2055 kernel_info=DestroyKernelInfo(kernel_info);
2056 break;
2057 }
anthonydcf510d2011-10-30 13:51:40 +00002058 if (LocaleCompare("crop",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002059 {
2060 /*
2061 Crop a image to a smaller size
2062 */
cristy6fccee12011-10-20 18:43:18 +00002063 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002064 new_image=CropImageToTiles(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00002065 break;
2066 }
anthonydcf510d2011-10-30 13:51:40 +00002067 if (LocaleCompare("cycle",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002068 {
2069 /*
2070 Cycle an image colormap.
2071 */
cristy6fccee12011-10-20 18:43:18 +00002072 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002073 (void) CycleColormapImage(*image,(ssize_t) StringToLong(args[0]),
anthony805a2d42011-09-25 08:25:12 +00002074 exception);
2075 break;
2076 }
2077 break;
2078 }
2079 case 'd':
2080 {
anthonydcf510d2011-10-30 13:51:40 +00002081 if (LocaleCompare("decipher",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002082 {
2083 StringInfo
2084 *passkey;
2085
2086 /*
2087 Decipher pixels.
2088 */
cristy6fccee12011-10-20 18:43:18 +00002089 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002090 passkey=FileToStringInfo(args[0],~0,exception);
anthony805a2d42011-09-25 08:25:12 +00002091 if (passkey != (StringInfo *) NULL)
2092 {
2093 (void) PasskeyDecipherImage(*image,passkey,exception);
2094 passkey=DestroyStringInfo(passkey);
2095 }
2096 break;
2097 }
anthonydcf510d2011-10-30 13:51:40 +00002098 if (LocaleCompare("depth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002099 {
anthonydcf510d2011-10-30 13:51:40 +00002100 /* The image_info->depth setting has already been set
2101 We just need to apply it to all images in current sequence
2102 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2103 That is it really is an operation, not a setting! Arrgghhh
2104 */
cristy6fccee12011-10-20 18:43:18 +00002105 (void) SyncImageSettings(image_info,*image,exception);
anthony5f867ae2011-10-09 10:28:34 +00002106 (void) SetImageDepth(*image,image_info->depth);
anthony805a2d42011-09-25 08:25:12 +00002107 break;
2108 }
anthonydcf510d2011-10-30 13:51:40 +00002109 if (LocaleCompare("deskew",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002110 {
2111 double
2112 threshold;
2113
2114 /*
2115 Straighten the image.
2116 */
cristy6fccee12011-10-20 18:43:18 +00002117 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002118 if (*argv[0] == '+')
2119 threshold=40.0*QuantumRange/100.0;
2120 else
cristy9b34e302011-11-05 02:15:45 +00002121 threshold=StringToDoubleInterval(args[0],(double) QuantumRange+1.0);
anthony805a2d42011-09-25 08:25:12 +00002122 new_image=DeskewImage(*image,threshold,exception);
2123 break;
2124 }
anthonydcf510d2011-10-30 13:51:40 +00002125 if (LocaleCompare("despeckle",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002126 {
2127 /*
2128 Reduce the speckles within an image.
2129 */
cristy6fccee12011-10-20 18:43:18 +00002130 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002131 new_image=DespeckleImage(*image,exception);
2132 break;
2133 }
anthonydcf510d2011-10-30 13:51:40 +00002134 if (LocaleCompare("display",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002135 {
anthonydcf510d2011-10-30 13:51:40 +00002136 (void) CloneString(&draw_info->server_name,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002137 break;
2138 }
anthonydcf510d2011-10-30 13:51:40 +00002139 if (LocaleCompare("distort",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002140 {
2141 char
2142 *args,
2143 token[MaxTextExtent];
2144
2145 const char
2146 *p;
2147
2148 DistortImageMethod
2149 method;
2150
2151 double
2152 *arguments;
2153
2154 register ssize_t
2155 x;
2156
2157 size_t
2158 number_arguments;
2159
2160 /*
2161 Distort image.
2162 */
cristy6fccee12011-10-20 18:43:18 +00002163 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002164 method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
anthonydcf510d2011-10-30 13:51:40 +00002165 MagickFalse,args[0]);
anthony80c37752012-01-16 01:03:11 +00002166 if (method == ResizeDistortion)
anthony805a2d42011-09-25 08:25:12 +00002167 {
anthony80c37752012-01-16 01:03:11 +00002168 double
2169 resize_args[2];
anthony805a2d42011-09-25 08:25:12 +00002170 /* Special Case - Argument is actually a resize geometry!
2171 ** Convert that to an appropriate distortion argument array.
2172 */
anthony805a2d42011-09-25 08:25:12 +00002173 (void) ParseRegionGeometry(*image,argv[2],&geometry,
anthony80c37752012-01-16 01:03:11 +00002174 exception);
2175 resize_args[0]=(double) geometry.width;
2176 resize_args[1]=(double) geometry.height;
anthony805a2d42011-09-25 08:25:12 +00002177 new_image=DistortImage(*image,method,(size_t)2,
anthony80c37752012-01-16 01:03:11 +00002178 resize_args,MagickTrue,exception);
anthony805a2d42011-09-25 08:25:12 +00002179 break;
2180 }
2181 args=InterpretImageProperties(image_info,*image,argv[2],
2182 exception);
2183 if (args == (char *) NULL)
2184 break;
2185 p=(char *) args;
2186 for (x=0; *p != '\0'; x++)
2187 {
2188 GetMagickToken(p,&p,token);
2189 if (*token == ',')
2190 GetMagickToken(p,&p,token);
2191 }
2192 number_arguments=(size_t) x;
2193 arguments=(double *) AcquireQuantumMemory(number_arguments,
2194 sizeof(*arguments));
2195 if (arguments == (double *) NULL)
2196 ThrowWandFatalException(ResourceLimitFatalError,
2197 "MemoryAllocationFailed",(*image)->filename);
2198 (void) ResetMagickMemory(arguments,0,number_arguments*
2199 sizeof(*arguments));
2200 p=(char *) args;
2201 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2202 {
2203 GetMagickToken(p,&p,token);
2204 if (*token == ',')
2205 GetMagickToken(p,&p,token);
cristydbdd0e32011-11-04 23:29:40 +00002206 arguments[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002207 }
2208 args=DestroyString(args);
2209 new_image=DistortImage(*image,method,number_arguments,arguments,
2210 (*argv[0] == '+') ? MagickTrue : MagickFalse,exception);
2211 arguments=(double *) RelinquishMagickMemory(arguments);
2212 break;
2213 }
anthonydcf510d2011-10-30 13:51:40 +00002214 if (LocaleCompare("draw",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002215 {
cristy6fccee12011-10-20 18:43:18 +00002216 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002217 (void) CloneString(&draw_info->primitive,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002218 (void) DrawImage(*image,draw_info,exception);
2219 break;
2220 }
2221 break;
2222 }
2223 case 'e':
2224 {
anthonydcf510d2011-10-30 13:51:40 +00002225 if (LocaleCompare("edge",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002226 {
cristy6fccee12011-10-20 18:43:18 +00002227 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002228 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002229 if ((flags & SigmaValue) == 0)
2230 geometry_info.sigma=1.0;
2231 new_image=EdgeImage(*image,geometry_info.rho,
2232 geometry_info.sigma,exception);
2233 break;
2234 }
anthonydcf510d2011-10-30 13:51:40 +00002235 if (LocaleCompare("emboss",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002236 {
cristy6fccee12011-10-20 18:43:18 +00002237 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002238 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002239 if ((flags & SigmaValue) == 0)
2240 geometry_info.sigma=1.0;
2241 new_image=EmbossImage(*image,geometry_info.rho,
2242 geometry_info.sigma,exception);
2243 break;
2244 }
anthonydcf510d2011-10-30 13:51:40 +00002245 if (LocaleCompare("encipher",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002246 {
2247 StringInfo
2248 *passkey;
2249
cristy6fccee12011-10-20 18:43:18 +00002250 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002251 passkey=FileToStringInfo(args[0],~0,exception);
anthony805a2d42011-09-25 08:25:12 +00002252 if (passkey != (StringInfo *) NULL)
2253 {
2254 (void) PasskeyEncipherImage(*image,passkey,exception);
2255 passkey=DestroyStringInfo(passkey);
2256 }
2257 break;
2258 }
anthonydcf510d2011-10-30 13:51:40 +00002259 if (LocaleCompare("enhance",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002260 {
cristy6fccee12011-10-20 18:43:18 +00002261 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002262 new_image=EnhanceImage(*image,exception);
2263 break;
2264 }
anthonydcf510d2011-10-30 13:51:40 +00002265 if (LocaleCompare("equalize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002266 {
cristy6fccee12011-10-20 18:43:18 +00002267 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002268 (void) EqualizeImage(*image,exception);
2269 break;
2270 }
anthonydcf510d2011-10-30 13:51:40 +00002271 if (LocaleCompare("evaluate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002272 {
2273 double
2274 constant;
2275
2276 MagickEvaluateOperator
2277 op;
2278
cristy6fccee12011-10-20 18:43:18 +00002279 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002280 op=(MagickEvaluateOperator) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00002281 MagickEvaluateOptions,MagickFalse,args[0]);
cristy9b34e302011-11-05 02:15:45 +00002282 constant=StringToDoubleInterval(argv[2],(double) QuantumRange+1.0);
anthony805a2d42011-09-25 08:25:12 +00002283 (void) EvaluateImage(*image,op,constant,exception);
2284 break;
2285 }
anthonydcf510d2011-10-30 13:51:40 +00002286 if (LocaleCompare("extent",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002287 {
cristy6fccee12011-10-20 18:43:18 +00002288 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002289 flags=ParseGravityGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00002290 if (geometry.width == 0)
2291 geometry.width=(*image)->columns;
2292 if (geometry.height == 0)
2293 geometry.height=(*image)->rows;
2294 new_image=ExtentImage(*image,&geometry,exception);
2295 break;
2296 }
2297 break;
2298 }
2299 case 'f':
2300 {
anthonydcf510d2011-10-30 13:51:40 +00002301 if (LocaleCompare("features",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002302 {
anthonyafbaed72011-10-26 12:05:04 +00002303 /* FUTURE: Assign Artifact to all images -- per image setting */
anthony6dc09cd2011-10-12 08:56:49 +00002304 (void) SetImageArtifact(*image,"identify:features",
anthonydcf510d2011-10-30 13:51:40 +00002305 IfSetOption ? args[0] : (const char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002306 break;
2307 }
anthonydcf510d2011-10-30 13:51:40 +00002308 if (LocaleCompare("flip",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002309 {
cristy947cb4c2011-10-20 18:41:46 +00002310 /*
2311 Flip image scanlines.
2312 */
cristy6fccee12011-10-20 18:43:18 +00002313 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002314 new_image=FlipImage(*image,exception);
2315 break;
2316 }
anthonydcf510d2011-10-30 13:51:40 +00002317 if (LocaleCompare("flop",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002318 {
cristy947cb4c2011-10-20 18:41:46 +00002319 /*
2320 Flop image scanlines.
2321 */
cristy6fccee12011-10-20 18:43:18 +00002322 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002323 new_image=FlopImage(*image,exception);
2324 break;
2325 }
anthonydcf510d2011-10-30 13:51:40 +00002326 if (LocaleCompare("floodfill",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002327 {
2328 PixelInfo
2329 target;
2330
cristy947cb4c2011-10-20 18:41:46 +00002331 /*
2332 Floodfill image.
2333 */
cristy6fccee12011-10-20 18:43:18 +00002334 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002335 (void) ParsePageGeometry(*image,args[0],&geometry,exception);
cristy269c9412011-10-13 23:41:15 +00002336 (void) QueryColorCompliance(argv[2],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00002337 exception);
anthony805a2d42011-09-25 08:25:12 +00002338 (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
2339 geometry.y,*argv[0] == '-' ? MagickFalse : MagickTrue,exception);
2340 break;
2341 }
cristy947cb4c2011-10-20 18:41:46 +00002342 /* FUTURE: should be from ImageOption "format"
anthonydcf510d2011-10-30 13:51:40 +00002343 if (LocaleCompare("format",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002344 {
anthonydcf510d2011-10-30 13:51:40 +00002345 format=args[0];
cristy947cb4c2011-10-20 18:41:46 +00002346 break;
2347 }
2348 */
anthonydcf510d2011-10-30 13:51:40 +00002349 if (LocaleCompare("frame",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002350 {
2351 FrameInfo
2352 frame_info;
2353
cristy947cb4c2011-10-20 18:41:46 +00002354 /*
2355 Surround image with an ornamental border.
2356 */
cristy6fccee12011-10-20 18:43:18 +00002357 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002358 flags=ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00002359 frame_info.width=geometry.width;
2360 frame_info.height=geometry.height;
2361 if ((flags & HeightValue) == 0)
2362 frame_info.height=geometry.width;
2363 frame_info.outer_bevel=geometry.x;
2364 frame_info.inner_bevel=geometry.y;
2365 frame_info.x=(ssize_t) frame_info.width;
2366 frame_info.y=(ssize_t) frame_info.height;
2367 frame_info.width=(*image)->columns+2*frame_info.width;
2368 frame_info.height=(*image)->rows+2*frame_info.height;
anthony5f867ae2011-10-09 10:28:34 +00002369 new_image=FrameImage(*image,&frame_info,COMPOSE,exception);
anthony805a2d42011-09-25 08:25:12 +00002370 break;
2371 }
anthonydcf510d2011-10-30 13:51:40 +00002372 if (LocaleCompare("function",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002373 {
2374 char
2375 *arguments,
2376 token[MaxTextExtent];
2377
2378 const char
2379 *p;
2380
2381 double
2382 *parameters;
2383
2384 MagickFunction
2385 function;
2386
2387 register ssize_t
2388 x;
2389
2390 size_t
2391 number_parameters;
2392
cristy947cb4c2011-10-20 18:41:46 +00002393 /*
2394 Function Modify Image Values
2395 */
cristy6fccee12011-10-20 18:43:18 +00002396 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002397 function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
anthonydcf510d2011-10-30 13:51:40 +00002398 MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002399 arguments=InterpretImageProperties(image_info,*image,argv[2],
2400 exception);
2401 if (arguments == (char *) NULL)
2402 break;
2403 p=(char *) arguments;
2404 for (x=0; *p != '\0'; x++)
2405 {
2406 GetMagickToken(p,&p,token);
2407 if (*token == ',')
2408 GetMagickToken(p,&p,token);
2409 }
2410 number_parameters=(size_t) x;
2411 parameters=(double *) AcquireQuantumMemory(number_parameters,
2412 sizeof(*parameters));
2413 if (parameters == (double *) NULL)
2414 ThrowWandFatalException(ResourceLimitFatalError,
2415 "MemoryAllocationFailed",(*image)->filename);
2416 (void) ResetMagickMemory(parameters,0,number_parameters*
2417 sizeof(*parameters));
2418 p=(char *) arguments;
2419 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
2420 {
2421 GetMagickToken(p,&p,token);
2422 if (*token == ',')
2423 GetMagickToken(p,&p,token);
cristydbdd0e32011-11-04 23:29:40 +00002424 parameters[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002425 }
2426 arguments=DestroyString(arguments);
2427 (void) FunctionImage(*image,function,number_parameters,parameters,
2428 exception);
2429 parameters=(double *) RelinquishMagickMemory(parameters);
2430 break;
2431 }
2432 break;
2433 }
2434 case 'g':
2435 {
anthonydcf510d2011-10-30 13:51:40 +00002436 if (LocaleCompare("gamma",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002437 {
cristy6fccee12011-10-20 18:43:18 +00002438 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002439 if (*argv[0] == '+')
cristydbdd0e32011-11-04 23:29:40 +00002440 (*image)->gamma=StringToDouble(args[0],(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002441 else
cristydbdd0e32011-11-04 23:29:40 +00002442 (void) GammaImage(*image,StringToDouble(args[0],
anthony805a2d42011-09-25 08:25:12 +00002443 (char **) NULL),exception);
2444 break;
2445 }
anthonydcf510d2011-10-30 13:51:40 +00002446 if ((LocaleCompare("gaussian-blur",option) == 0) ||
2447 (LocaleCompare("gaussian",option) == 0))
anthony805a2d42011-09-25 08:25:12 +00002448 {
cristy6fccee12011-10-20 18:43:18 +00002449 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002450 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002451 if ((flags & SigmaValue) == 0)
2452 geometry_info.sigma=1.0;
2453 if ((flags & XiValue) == 0)
2454 geometry_info.xi=0.0;
2455 new_image=GaussianBlurImage(*image,geometry_info.rho,
2456 geometry_info.sigma,geometry_info.xi,exception);
2457 break;
2458 }
anthonydcf510d2011-10-30 13:51:40 +00002459 if (LocaleCompare("geometry",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002460 {
2461 /*
anthony6613bf32011-10-15 07:24:44 +00002462 Record Image offset for composition,
2463 Resize last image. -- FUTURE depreciate this aspect
anthony805a2d42011-09-25 08:25:12 +00002464 */
cristy6fccee12011-10-20 18:43:18 +00002465 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002466 if (*argv[0] == '+')
2467 {
2468 if ((*image)->geometry != (char *) NULL)
2469 (*image)->geometry=DestroyString((*image)->geometry);
2470 break;
2471 }
anthonydcf510d2011-10-30 13:51:40 +00002472 flags=ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00002473 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
anthonydcf510d2011-10-30 13:51:40 +00002474 (void) CloneString(&(*image)->geometry,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002475 else
2476 new_image=ResizeImage(*image,geometry.width,geometry.height,
2477 (*image)->filter,(*image)->blur,exception);
2478 break;
2479 }
anthony805a2d42011-09-25 08:25:12 +00002480 break;
2481 }
2482 case 'h':
2483 {
anthonydcf510d2011-10-30 13:51:40 +00002484 if (LocaleCompare("highlight-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002485 {
anthonydcf510d2011-10-30 13:51:40 +00002486 (void) SetImageArtifact(*image,option,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002487 break;
2488 }
2489 break;
2490 }
2491 case 'i':
2492 {
anthonydcf510d2011-10-30 13:51:40 +00002493 if (LocaleCompare("identify",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002494 {
2495 char
2496 *text;
2497
cristy6fccee12011-10-20 18:43:18 +00002498 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002499 if (format == (char *) NULL)
2500 {
2501 (void) IdentifyImage(*image,stdout,image_info->verbose,
2502 exception);
2503 break;
2504 }
2505 text=InterpretImageProperties(image_info,*image,format,
2506 exception);
2507 if (text == (char *) NULL)
2508 break;
2509 (void) fputs(text,stdout);
2510 (void) fputc('\n',stdout);
2511 text=DestroyString(text);
2512 break;
2513 }
anthonydcf510d2011-10-30 13:51:40 +00002514 if (LocaleCompare("implode",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002515 {
cristy947cb4c2011-10-20 18:41:46 +00002516 /*
2517 Implode image.
2518 */
cristy6fccee12011-10-20 18:43:18 +00002519 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002520 (void) ParseGeometry(args[0],&geometry_info);
anthonya89dd172011-10-04 13:29:35 +00002521 new_image=ImplodeImage(*image,geometry_info.rho,
2522 interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00002523 break;
2524 }
anthonydcf510d2011-10-30 13:51:40 +00002525 if (LocaleCompare("interline-spacing",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002526 {
2527 if (*argv[0] == '+')
2528 (void) ParseGeometry("0",&geometry_info);
2529 else
anthonydcf510d2011-10-30 13:51:40 +00002530 (void) ParseGeometry(args[0],&geometry_info);
cristy947cb4c2011-10-20 18:41:46 +00002531 draw_info->interline_spacing=geometry_info.rho;
2532 break;
2533 }
anthonydcf510d2011-10-30 13:51:40 +00002534 if (LocaleCompare("interpolate",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002535 {
2536 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00002537 MagickInterpolateOptions,MagickFalse,args[0]);
cristy947cb4c2011-10-20 18:41:46 +00002538 break;
2539 }
anthonydcf510d2011-10-30 13:51:40 +00002540 if (LocaleCompare("interword-spacing",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002541 {
2542 if (*argv[0] == '+')
2543 (void) ParseGeometry("0",&geometry_info);
2544 else
anthonydcf510d2011-10-30 13:51:40 +00002545 (void) ParseGeometry(args[0],&geometry_info);
cristy947cb4c2011-10-20 18:41:46 +00002546 draw_info->interword_spacing=geometry_info.rho;
2547 break;
2548 }
2549 break;
2550 }
2551 case 'k':
2552 {
anthonydcf510d2011-10-30 13:51:40 +00002553 if (LocaleCompare("kerning",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002554 {
2555 if (*argv[0] == '+')
2556 (void) ParseGeometry("0",&geometry_info);
2557 else
anthonydcf510d2011-10-30 13:51:40 +00002558 (void) ParseGeometry(args[0],&geometry_info);
cristy947cb4c2011-10-20 18:41:46 +00002559 draw_info->kerning=geometry_info.rho;
2560 break;
2561 }
anthony805a2d42011-09-25 08:25:12 +00002562 break;
2563 }
2564 case 'l':
2565 {
anthonydcf510d2011-10-30 13:51:40 +00002566 if (LocaleCompare("lat",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002567 {
2568 /*
2569 Local adaptive threshold image.
2570 */
cristy6fccee12011-10-20 18:43:18 +00002571 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002572 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002573 if ((flags & PercentValue) != 0)
2574 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2575 new_image=AdaptiveThresholdImage(*image,(size_t)
2576 geometry_info.rho,(size_t) geometry_info.sigma,(double)
2577 geometry_info.xi,exception);
2578 break;
2579 }
anthonydcf510d2011-10-30 13:51:40 +00002580 if (LocaleCompare("level",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002581 {
2582 MagickRealType
2583 black_point,
2584 gamma,
2585 white_point;
2586
2587 MagickStatusType
2588 flags;
2589
cristy947cb4c2011-10-20 18:41:46 +00002590 /*
2591 Parse levels.
2592 */
cristy6fccee12011-10-20 18:43:18 +00002593 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002594 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002595 black_point=geometry_info.rho;
2596 white_point=(MagickRealType) QuantumRange;
2597 if ((flags & SigmaValue) != 0)
2598 white_point=geometry_info.sigma;
2599 gamma=1.0;
2600 if ((flags & XiValue) != 0)
2601 gamma=geometry_info.xi;
2602 if ((flags & PercentValue) != 0)
2603 {
2604 black_point*=(MagickRealType) (QuantumRange/100.0);
2605 white_point*=(MagickRealType) (QuantumRange/100.0);
2606 }
2607 if ((flags & SigmaValue) == 0)
2608 white_point=(MagickRealType) QuantumRange-black_point;
2609 if ((*argv[0] == '+') || ((flags & AspectValue) != 0))
2610 (void) LevelizeImage(*image,black_point,white_point,gamma,
2611 exception);
2612 else
2613 (void) LevelImage(*image,black_point,white_point,gamma,
2614 exception);
anthony805a2d42011-09-25 08:25:12 +00002615 break;
2616 }
anthonydcf510d2011-10-30 13:51:40 +00002617 if (LocaleCompare("level-colors",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002618 {
2619 char
2620 token[MaxTextExtent];
2621
2622 const char
2623 *p;
2624
2625 PixelInfo
2626 black_point,
2627 white_point;
2628
anthonydcf510d2011-10-30 13:51:40 +00002629 p=(const char *) args[0];
anthony805a2d42011-09-25 08:25:12 +00002630 GetMagickToken(p,&p,token); /* get black point color */
2631 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002632 (void) QueryColorCompliance(token,AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002633 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002634 else
cristy269c9412011-10-13 23:41:15 +00002635 (void) QueryColorCompliance("#000000",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002636 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002637 if (isalpha((int) token[0]) || (token[0] == '#'))
2638 GetMagickToken(p,&p,token);
2639 if (*token == '\0')
2640 white_point=black_point; /* set everything to that color */
2641 else
2642 {
2643 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2644 GetMagickToken(p,&p,token); /* Get white point color. */
2645 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002646 (void) QueryColorCompliance(token,AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002647 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002648 else
cristy269c9412011-10-13 23:41:15 +00002649 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002650 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002651 }
2652 (void) LevelImageColors(*image,&black_point,&white_point,
2653 *argv[0] == '+' ? MagickTrue : MagickFalse,exception);
2654 break;
2655 }
anthonydcf510d2011-10-30 13:51:40 +00002656 if (LocaleCompare("linear-stretch",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002657 {
2658 double
2659 black_point,
2660 white_point;
2661
2662 MagickStatusType
2663 flags;
2664
cristy6fccee12011-10-20 18:43:18 +00002665 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002666 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002667 black_point=geometry_info.rho;
2668 white_point=(MagickRealType) (*image)->columns*(*image)->rows;
2669 if ((flags & SigmaValue) != 0)
2670 white_point=geometry_info.sigma;
2671 if ((flags & PercentValue) != 0)
2672 {
2673 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2674 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2675 }
2676 if ((flags & SigmaValue) == 0)
2677 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2678 black_point;
2679 (void) LinearStretchImage(*image,black_point,white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002680 break;
2681 }
anthonydcf510d2011-10-30 13:51:40 +00002682 if (LocaleCompare("linewidth",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002683 {
cristydbdd0e32011-11-04 23:29:40 +00002684 draw_info->stroke_width=StringToDouble(args[0],
cristy947cb4c2011-10-20 18:41:46 +00002685 (char **) NULL);
2686 break;
2687 }
anthonydcf510d2011-10-30 13:51:40 +00002688 if (LocaleCompare("liquid-rescale",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002689 {
2690 /*
2691 Liquid rescale image.
2692 */
cristy6fccee12011-10-20 18:43:18 +00002693 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002694 flags=ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00002695 if ((flags & XValue) == 0)
2696 geometry.x=1;
2697 if ((flags & YValue) == 0)
2698 geometry.y=0;
2699 new_image=LiquidRescaleImage(*image,geometry.width,
2700 geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
2701 break;
2702 }
anthonydcf510d2011-10-30 13:51:40 +00002703 if (LocaleCompare("lowlight-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002704 {
anthonydcf510d2011-10-30 13:51:40 +00002705 (void) SetImageArtifact(*image,option,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002706 break;
2707 }
2708 break;
2709 }
2710 case 'm':
2711 {
anthonydcf510d2011-10-30 13:51:40 +00002712 if (LocaleCompare("map",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002713 {
2714 Image
2715 *remap_image;
2716
cristy947cb4c2011-10-20 18:41:46 +00002717 /*
2718 Transform image colors to match this set of colors.
2719 */
cristy6fccee12011-10-20 18:43:18 +00002720 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002721 if (*argv[0] == '+')
2722 break;
anthonydcf510d2011-10-30 13:51:40 +00002723 remap_image=GetImageCache(image_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00002724 if (remap_image == (Image *) NULL)
2725 break;
2726 (void) RemapImage(quantize_info,*image,remap_image,exception);
2727 remap_image=DestroyImage(remap_image);
2728 break;
2729 }
anthonydcf510d2011-10-30 13:51:40 +00002730 if (LocaleCompare("mask",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002731 {
2732 Image
2733 *mask;
2734
cristy6fccee12011-10-20 18:43:18 +00002735 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002736 if (*argv[0] == '+')
2737 {
cristy947cb4c2011-10-20 18:41:46 +00002738 /*
2739 Remove a mask.
2740 */
anthony805a2d42011-09-25 08:25:12 +00002741 (void) SetImageMask(*image,(Image *) NULL,exception);
2742 break;
2743 }
cristy947cb4c2011-10-20 18:41:46 +00002744 /*
2745 Set the image mask.
2746 */
anthonydcf510d2011-10-30 13:51:40 +00002747 mask=GetImageCache(image_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00002748 if (mask == (Image *) NULL)
2749 break;
2750 (void) SetImageMask(*image,mask,exception);
2751 mask=DestroyImage(mask);
2752 break;
2753 }
anthonydcf510d2011-10-30 13:51:40 +00002754 if (LocaleCompare("matte",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002755 {
cristy947cb4c2011-10-20 18:41:46 +00002756 (void) SetImageAlphaChannel(*image,(*argv[0] == '-') ?
2757 SetAlphaChannel : DeactivateAlphaChannel,exception);
anthony805a2d42011-09-25 08:25:12 +00002758 break;
2759 }
anthonydcf510d2011-10-30 13:51:40 +00002760 if (LocaleCompare("median",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002761 {
cristy947cb4c2011-10-20 18:41:46 +00002762 /*
2763 Median filter image.
2764 */
cristy6fccee12011-10-20 18:43:18 +00002765 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002766 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002767 if ((flags & SigmaValue) == 0)
2768 geometry_info.sigma=geometry_info.rho;
2769 new_image=StatisticImage(*image,MedianStatistic,(size_t)
2770 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2771 break;
2772 }
anthonydcf510d2011-10-30 13:51:40 +00002773 if (LocaleCompare("mode",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002774 {
2775 /*
cristy947cb4c2011-10-20 18:41:46 +00002776 Mode image.
anthony805a2d42011-09-25 08:25:12 +00002777 */
cristy6fccee12011-10-20 18:43:18 +00002778 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002779 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002780 if ((flags & SigmaValue) == 0)
2781 geometry_info.sigma=geometry_info.rho;
2782 new_image=StatisticImage(*image,ModeStatistic,(size_t)
2783 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2784 break;
2785 }
anthonydcf510d2011-10-30 13:51:40 +00002786 if (LocaleCompare("modulate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002787 {
cristy6fccee12011-10-20 18:43:18 +00002788 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002789 (void) ModulateImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00002790 break;
2791 }
anthonydcf510d2011-10-30 13:51:40 +00002792 if (LocaleCompare("monitor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002793 {
anthonyafbaed72011-10-26 12:05:04 +00002794 /* FUTURE: Why is this a per-image setting? */
anthony805a2d42011-09-25 08:25:12 +00002795 if (*argv[0] == '+')
2796 {
2797 (void) SetImageProgressMonitor(*image,
2798 (MagickProgressMonitor) NULL,(void *) NULL);
2799 break;
2800 }
2801 (void) SetImageProgressMonitor(*image,MonitorProgress,
2802 (void *) NULL);
2803 break;
2804 }
anthonydcf510d2011-10-30 13:51:40 +00002805 if (LocaleCompare("monochrome",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002806 {
cristy6fccee12011-10-20 18:43:18 +00002807 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002808 (void) SetImageType(*image,BilevelType,exception);
2809 break;
2810 }
anthonydcf510d2011-10-30 13:51:40 +00002811 if (LocaleCompare("morphology",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002812 {
2813 char
2814 token[MaxTextExtent];
2815
2816 const char
2817 *p;
2818
2819 KernelInfo
2820 *kernel;
2821
2822 MorphologyMethod
2823 method;
2824
2825 ssize_t
2826 iterations;
2827
cristy6fccee12011-10-20 18:43:18 +00002828 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002829 p=args[0];
anthony805a2d42011-09-25 08:25:12 +00002830 GetMagickToken(p,&p,token);
2831 method=(MorphologyMethod) ParseCommandOption(
2832 MagickMorphologyOptions,MagickFalse,token);
2833 iterations=1L;
2834 GetMagickToken(p,&p,token);
2835 if ((*p == ':') || (*p == ','))
2836 GetMagickToken(p,&p,token);
2837 if ((*p != '\0'))
2838 iterations=(ssize_t) StringToLong(p);
2839 kernel=AcquireKernelInfo(argv[2]);
2840 if (kernel == (KernelInfo *) NULL)
2841 {
2842 (void) ThrowMagickException(exception,GetMagickModule(),
2843 OptionError,"UnabletoParseKernel","morphology");
2844 status=MagickFalse;
2845 break;
2846 }
2847 new_image=MorphologyImage(*image,method,iterations,kernel,
2848 exception);
2849 kernel=DestroyKernelInfo(kernel);
2850 break;
2851 }
anthonydcf510d2011-10-30 13:51:40 +00002852 if (LocaleCompare("motion-blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002853 {
cristy947cb4c2011-10-20 18:41:46 +00002854 /*
2855 Motion blur image.
2856 */
cristy6fccee12011-10-20 18:43:18 +00002857 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002858 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002859 if ((flags & SigmaValue) == 0)
2860 geometry_info.sigma=1.0;
2861 new_image=MotionBlurImage(*image,geometry_info.rho,
2862 geometry_info.sigma,geometry_info.xi,geometry_info.psi,
2863 exception);
2864 break;
2865 }
2866 break;
2867 }
2868 case 'n':
2869 {
anthonydcf510d2011-10-30 13:51:40 +00002870 if (LocaleCompare("negate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002871 {
cristy6fccee12011-10-20 18:43:18 +00002872 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002873 (void) NegateImage(*image,*argv[0] == '+' ? MagickTrue :
2874 MagickFalse,exception);
2875 break;
2876 }
anthonydcf510d2011-10-30 13:51:40 +00002877 if (LocaleCompare("noise",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002878 {
cristy6fccee12011-10-20 18:43:18 +00002879 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002880 if (*argv[0] == '-')
2881 {
anthonydcf510d2011-10-30 13:51:40 +00002882 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002883 if ((flags & SigmaValue) == 0)
2884 geometry_info.sigma=geometry_info.rho;
2885 new_image=StatisticImage(*image,NonpeakStatistic,(size_t)
2886 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2887 }
2888 else
2889 {
2890 NoiseType
2891 noise;
2892
2893 noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
anthonydcf510d2011-10-30 13:51:40 +00002894 MagickFalse,args[0]);
anthony5f867ae2011-10-09 10:28:34 +00002895 new_image=AddNoiseImage(*image,noise,exception);
anthony805a2d42011-09-25 08:25:12 +00002896 }
2897 break;
2898 }
anthonydcf510d2011-10-30 13:51:40 +00002899 if (LocaleCompare("normalize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002900 {
cristy6fccee12011-10-20 18:43:18 +00002901 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002902 (void) NormalizeImage(*image,exception);
2903 break;
2904 }
2905 break;
2906 }
2907 case 'o':
2908 {
anthonydcf510d2011-10-30 13:51:40 +00002909 if (LocaleCompare("opaque",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002910 {
2911 PixelInfo
2912 target;
2913
cristy6fccee12011-10-20 18:43:18 +00002914 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002915 (void) QueryColorCompliance(args[0],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00002916 exception);
anthony805a2d42011-09-25 08:25:12 +00002917 (void) OpaquePaintImage(*image,&target,&fill,*argv[0] == '-' ?
2918 MagickFalse : MagickTrue,exception);
2919 break;
2920 }
anthonydcf510d2011-10-30 13:51:40 +00002921 if (LocaleCompare("ordered-dither",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002922 {
cristy6fccee12011-10-20 18:43:18 +00002923 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002924 (void) OrderedPosterizeImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00002925 break;
2926 }
2927 break;
2928 }
2929 case 'p':
2930 {
anthonydcf510d2011-10-30 13:51:40 +00002931 if (LocaleCompare("paint",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002932 {
cristy6fccee12011-10-20 18:43:18 +00002933 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002934 (void) ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002935 new_image=OilPaintImage(*image,geometry_info.rho,
2936 geometry_info.sigma,exception);
2937 break;
2938 }
anthonydcf510d2011-10-30 13:51:40 +00002939 if (LocaleCompare("polaroid",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002940 {
cristye9e3d382011-12-14 01:50:13 +00002941 const char
2942 *caption;
2943
anthony805a2d42011-09-25 08:25:12 +00002944 double
2945 angle;
2946
2947 RandomInfo
2948 *random_info;
2949
cristy947cb4c2011-10-20 18:41:46 +00002950 /*
2951 Simulate a Polaroid picture.
2952 */
cristy6fccee12011-10-20 18:43:18 +00002953 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002954 random_info=AcquireRandomInfo();
2955 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2956 random_info=DestroyRandomInfo(random_info);
2957 if (*argv[0] == '-')
2958 {
2959 SetGeometryInfo(&geometry_info);
anthonydcf510d2011-10-30 13:51:40 +00002960 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002961 angle=geometry_info.rho;
2962 }
cristye9e3d382011-12-14 01:50:13 +00002963 caption=GetImageProperty(*image,"caption",exception);
2964 new_image=PolaroidImage(*image,draw_info,caption,angle,
anthony805a2d42011-09-25 08:25:12 +00002965 interpolate_method,exception);
2966 break;
2967 }
anthonydcf510d2011-10-30 13:51:40 +00002968 if (LocaleCompare("posterize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002969 {
cristy947cb4c2011-10-20 18:41:46 +00002970 /*
2971 Posterize image.
2972 */
cristy6fccee12011-10-20 18:43:18 +00002973 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002974 (void) PosterizeImage(*image,StringToUnsignedLong(args[0]),
anthony805a2d42011-09-25 08:25:12 +00002975 quantize_info->dither,exception);
2976 break;
2977 }
anthonydcf510d2011-10-30 13:51:40 +00002978 if (LocaleCompare("preview",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002979 {
2980 PreviewType
cristy947cb4c2011-10-20 18:41:46 +00002981 preview_type;
anthony170fce92011-10-20 11:50:23 +00002982
cristy947cb4c2011-10-20 18:41:46 +00002983 /*
2984 Preview image.
2985 */
cristy6fccee12011-10-20 18:43:18 +00002986 (void) SyncImageSettings(image_info,*image,exception);
cristy947cb4c2011-10-20 18:41:46 +00002987 if (*argv[0] == '+')
2988 preview_type=UndefinedPreview;
2989 else
anthony805a2d42011-09-25 08:25:12 +00002990 preview_type=(PreviewType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00002991 MagickPreviewOptions,MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002992 new_image=PreviewImage(*image,preview_type,exception);
2993 break;
2994 }
anthonydcf510d2011-10-30 13:51:40 +00002995 if (LocaleCompare("profile",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002996 {
2997 const char
2998 *name;
2999
3000 const StringInfo
3001 *profile;
3002
3003 Image
3004 *profile_image;
3005
3006 ImageInfo
3007 *profile_info;
3008
cristy6fccee12011-10-20 18:43:18 +00003009 (void) SyncImageSettings(image_info,*image,exception);
cristy947cb4c2011-10-20 18:41:46 +00003010 if (*argv[0] == '+')
anthony805a2d42011-09-25 08:25:12 +00003011 {
cristy947cb4c2011-10-20 18:41:46 +00003012 /*
3013 Remove a profile from the image.
3014 */
anthonydcf510d2011-10-30 13:51:40 +00003015 (void) ProfileImage(*image,args[0],(const unsigned char *)
cristy092d71c2011-10-14 18:01:29 +00003016 NULL,0,exception);
anthony805a2d42011-09-25 08:25:12 +00003017 break;
3018 }
cristy947cb4c2011-10-20 18:41:46 +00003019 /*
3020 Associate a profile with the image.
3021 */
anthony805a2d42011-09-25 08:25:12 +00003022 profile_info=CloneImageInfo(image_info);
3023 profile=GetImageProfile(*image,"iptc");
3024 if (profile != (StringInfo *) NULL)
3025 profile_info->profile=(void *) CloneStringInfo(profile);
anthonydcf510d2011-10-30 13:51:40 +00003026 profile_image=GetImageCache(profile_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003027 profile_info=DestroyImageInfo(profile_info);
3028 if (profile_image == (Image *) NULL)
3029 {
3030 StringInfo
3031 *profile;
3032
3033 profile_info=CloneImageInfo(image_info);
anthonydcf510d2011-10-30 13:51:40 +00003034 (void) CopyMagickString(profile_info->filename,args[0],
anthony805a2d42011-09-25 08:25:12 +00003035 MaxTextExtent);
3036 profile=FileToStringInfo(profile_info->filename,~0UL,exception);
3037 if (profile != (StringInfo *) NULL)
3038 {
3039 (void) ProfileImage(*image,profile_info->magick,
3040 GetStringInfoDatum(profile),(size_t)
cristy092d71c2011-10-14 18:01:29 +00003041 GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003042 profile=DestroyStringInfo(profile);
3043 }
3044 profile_info=DestroyImageInfo(profile_info);
3045 break;
3046 }
3047 ResetImageProfileIterator(profile_image);
3048 name=GetNextImageProfile(profile_image);
3049 while (name != (const char *) NULL)
3050 {
3051 profile=GetImageProfile(profile_image,name);
3052 if (profile != (StringInfo *) NULL)
3053 (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
cristy092d71c2011-10-14 18:01:29 +00003054 (size_t) GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003055 name=GetNextImageProfile(profile_image);
3056 }
3057 profile_image=DestroyImage(profile_image);
3058 break;
3059 }
3060 break;
3061 }
cristy947cb4c2011-10-20 18:41:46 +00003062 case 'q':
3063 {
anthonydcf510d2011-10-30 13:51:40 +00003064 if (LocaleCompare("quantize",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00003065 {
3066 if (*argv[0] == '+')
3067 {
3068 quantize_info->colorspace=UndefinedColorspace;
3069 break;
3070 }
3071 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00003072 MagickColorspaceOptions,MagickFalse,args[0]);
cristy947cb4c2011-10-20 18:41:46 +00003073 break;
3074 }
3075 break;
3076 }
anthony805a2d42011-09-25 08:25:12 +00003077 case 'r':
3078 {
anthonydcf510d2011-10-30 13:51:40 +00003079 if (LocaleCompare("radial-blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003080 {
cristy6fccee12011-10-20 18:43:18 +00003081 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003082 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003083 new_image=RadialBlurImage(*image,geometry_info.rho,
3084 geometry_info.sigma,exception);
3085 break;
3086 }
anthonydcf510d2011-10-30 13:51:40 +00003087 if (LocaleCompare("raise",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003088 {
anthonydcf510d2011-10-30 13:51:40 +00003089 flags=ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003090 if ((flags & SigmaValue) == 0)
3091 geometry.height=geometry.width;
3092 (void) RaiseImage(*image,&geometry,*argv[0] == '-' ? MagickTrue :
3093 MagickFalse,exception);
3094 break;
3095 }
anthonydcf510d2011-10-30 13:51:40 +00003096 if (LocaleCompare("random-threshold",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003097 {
cristy6fccee12011-10-20 18:43:18 +00003098 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003099 (void) RandomThresholdImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003100 break;
3101 }
anthonydcf510d2011-10-30 13:51:40 +00003102 if (LocaleCompare("recolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003103 {
3104 KernelInfo
3105 *kernel;
3106
cristy6fccee12011-10-20 18:43:18 +00003107 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003108 kernel=AcquireKernelInfo(args[0]);
anthony805a2d42011-09-25 08:25:12 +00003109 if (kernel == (KernelInfo *) NULL)
3110 break;
3111 new_image=ColorMatrixImage(*image,kernel,exception);
3112 kernel=DestroyKernelInfo(kernel);
3113 break;
3114 }
anthonydcf510d2011-10-30 13:51:40 +00003115 if (LocaleCompare("remap",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003116 {
3117 Image
3118 *remap_image;
3119
cristy6fccee12011-10-20 18:43:18 +00003120 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003121 if (*argv[0] == '+')
3122 break;
anthonydcf510d2011-10-30 13:51:40 +00003123 remap_image=GetImageCache(image_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003124 if (remap_image == (Image *) NULL)
3125 break;
3126 (void) RemapImage(quantize_info,*image,remap_image,exception);
3127 remap_image=DestroyImage(remap_image);
3128 break;
3129 }
anthonydcf510d2011-10-30 13:51:40 +00003130 if (LocaleCompare("repage",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003131 {
3132 if (*argv[0] == '+')
3133 {
3134 (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
3135 break;
3136 }
anthonydcf510d2011-10-30 13:51:40 +00003137 (void) ResetImagePage(*image,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003138 break;
3139 }
anthonydcf510d2011-10-30 13:51:40 +00003140 if (LocaleCompare("resample",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003141 {
anthonyafbaed72011-10-26 12:05:04 +00003142 /* FUTURE: remove blur - no longer used */
cristy6fccee12011-10-20 18:43:18 +00003143 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003144 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003145 if ((flags & SigmaValue) == 0)
3146 geometry_info.sigma=geometry_info.rho;
3147 new_image=ResampleImage(*image,geometry_info.rho,
3148 geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
3149 break;
3150 }
anthonydcf510d2011-10-30 13:51:40 +00003151 if (LocaleCompare("resize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003152 {
anthonyafbaed72011-10-26 12:05:04 +00003153 /* FUTURE: remove blur argument - no longer used */
cristy6fccee12011-10-20 18:43:18 +00003154 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003155 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003156 new_image=ResizeImage(*image,geometry.width,geometry.height,
3157 (*image)->filter,(*image)->blur,exception);
3158 break;
3159 }
anthonydcf510d2011-10-30 13:51:40 +00003160 if (LocaleCompare("roll",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003161 {
cristy6fccee12011-10-20 18:43:18 +00003162 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003163 (void) ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003164 new_image=RollImage(*image,geometry.x,geometry.y,exception);
3165 break;
3166 }
anthonydcf510d2011-10-30 13:51:40 +00003167 if (LocaleCompare("rotate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003168 {
anthonyafbaed72011-10-26 12:05:04 +00003169 /* special case rotation flags */
cristy6fccee12011-10-20 18:43:18 +00003170 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003171 if (strchr(args[0],'>') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00003172 if ((*image)->columns <= (*image)->rows)
3173 break;
anthonydcf510d2011-10-30 13:51:40 +00003174 if (strchr(args[0],'<') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00003175 if ((*image)->columns >= (*image)->rows)
3176 break;
anthonyafbaed72011-10-26 12:05:04 +00003177
anthonydcf510d2011-10-30 13:51:40 +00003178 (void) ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003179 new_image=RotateImage(*image,geometry_info.rho,exception);
3180 break;
3181 }
3182 break;
3183 }
3184 case 's':
3185 {
anthonydcf510d2011-10-30 13:51:40 +00003186 if (LocaleCompare("sample",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003187 {
cristy6fccee12011-10-20 18:43:18 +00003188 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003189 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003190 new_image=SampleImage(*image,geometry.width,geometry.height,
3191 exception);
3192 break;
3193 }
anthonydcf510d2011-10-30 13:51:40 +00003194 if (LocaleCompare("scale",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003195 {
cristy6fccee12011-10-20 18:43:18 +00003196 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003197 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003198 new_image=ScaleImage(*image,geometry.width,geometry.height,
3199 exception);
3200 break;
3201 }
anthonydcf510d2011-10-30 13:51:40 +00003202 if (LocaleCompare("selective-blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003203 {
cristy6fccee12011-10-20 18:43:18 +00003204 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003205 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003206 if ((flags & PercentValue) != 0)
3207 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3208 new_image=SelectiveBlurImage(*image,geometry_info.rho,
3209 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3210 break;
3211 }
anthonydcf510d2011-10-30 13:51:40 +00003212 if (LocaleCompare("separate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003213 {
3214 /*
3215 Break channels into separate images.
3216 WARNING: This can generate multiple images!
3217 */
cristy6fccee12011-10-20 18:43:18 +00003218 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003219 new_image=SeparateImages(*image,exception);
3220 break;
3221 }
anthonydcf510d2011-10-30 13:51:40 +00003222 if (LocaleCompare("sepia-tone",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003223 {
3224 double
3225 threshold;
3226
cristy6fccee12011-10-20 18:43:18 +00003227 (void) SyncImageSettings(image_info,*image,exception);
cristy9b34e302011-11-05 02:15:45 +00003228 threshold=StringToDoubleInterval(args[0],(double) QuantumRange+1.0);
anthony805a2d42011-09-25 08:25:12 +00003229 new_image=SepiaToneImage(*image,threshold,exception);
3230 break;
3231 }
anthonydcf510d2011-10-30 13:51:40 +00003232 if (LocaleCompare("segment",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003233 {
cristy6fccee12011-10-20 18:43:18 +00003234 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003235 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003236 if ((flags & SigmaValue) == 0)
3237 geometry_info.sigma=1.0;
3238 (void) SegmentImage(*image,(*image)->colorspace,
3239 image_info->verbose,geometry_info.rho,geometry_info.sigma,
3240 exception);
3241 break;
3242 }
anthonydcf510d2011-10-30 13:51:40 +00003243 if (LocaleCompare("set",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003244 {
3245 char
3246 *value;
3247
anthony805a2d42011-09-25 08:25:12 +00003248 if (*argv[0] == '+')
3249 {
anthonydcf510d2011-10-30 13:51:40 +00003250 if (LocaleNCompare(args[0],"registry:",9) == 0)
3251 (void) DeleteImageRegistry(args[0]+9);
anthony805a2d42011-09-25 08:25:12 +00003252 else
anthonydcf510d2011-10-30 13:51:40 +00003253 if (LocaleNCompare(args[0],"argv[0]:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003254 {
anthonydcf510d2011-10-30 13:51:40 +00003255 (void) DeleteImageOption(image_info,args[0]+7);
3256 (void) DeleteImageArtifact(*image,args[0]+7);
anthony805a2d42011-09-25 08:25:12 +00003257 }
3258 else
anthonydcf510d2011-10-30 13:51:40 +00003259 (void) DeleteImageProperty(*image,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003260 break;
3261 }
3262 value=InterpretImageProperties(image_info,*image,argv[2],
3263 exception);
3264 if (value == (char *) NULL)
3265 break;
anthonydcf510d2011-10-30 13:51:40 +00003266 if (LocaleNCompare(args[0],"registry:",9) == 0)
3267 (void) SetImageRegistry(StringRegistryType,args[0]+9,value,
anthony805a2d42011-09-25 08:25:12 +00003268 exception);
3269 else
anthonydcf510d2011-10-30 13:51:40 +00003270 if (LocaleNCompare(args[0],"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003271 {
anthonydcf510d2011-10-30 13:51:40 +00003272 (void) SetImageOption(image_info,args[0]+7,value);
3273 (void) SetImageArtifact(*image,args[0]+7,value);
anthony805a2d42011-09-25 08:25:12 +00003274 }
3275 else
anthonydcf510d2011-10-30 13:51:40 +00003276 (void) SetImageProperty(*image,args[0],value,exception);
anthony805a2d42011-09-25 08:25:12 +00003277 value=DestroyString(value);
3278 break;
3279 }
anthonydcf510d2011-10-30 13:51:40 +00003280 if (LocaleCompare("shade",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003281 {
cristy6fccee12011-10-20 18:43:18 +00003282 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003283 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003284 if ((flags & SigmaValue) == 0)
3285 geometry_info.sigma=1.0;
3286 new_image=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue :
3287 MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
3288 break;
3289 }
anthonydcf510d2011-10-30 13:51:40 +00003290 if (LocaleCompare("shadow",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003291 {
cristy6fccee12011-10-20 18:43:18 +00003292 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003293 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003294 if ((flags & SigmaValue) == 0)
3295 geometry_info.sigma=1.0;
3296 if ((flags & XiValue) == 0)
3297 geometry_info.xi=4.0;
3298 if ((flags & PsiValue) == 0)
3299 geometry_info.psi=4.0;
3300 new_image=ShadowImage(*image,geometry_info.rho,
cristyeb6e6582011-12-09 09:14:23 +00003301 geometry_info.sigma,(*image)->bias,(ssize_t)
3302 ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5),
3303 exception);
anthony805a2d42011-09-25 08:25:12 +00003304 break;
3305 }
anthonydcf510d2011-10-30 13:51:40 +00003306 if (LocaleCompare("sharpen",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003307 {
cristy6fccee12011-10-20 18:43:18 +00003308 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003309 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003310 if ((flags & SigmaValue) == 0)
3311 geometry_info.sigma=1.0;
3312 if ((flags & XiValue) == 0)
3313 geometry_info.xi=0.0;
3314 new_image=SharpenImage(*image,geometry_info.rho,
3315 geometry_info.sigma,geometry_info.xi,exception);
3316 break;
3317 }
anthonydcf510d2011-10-30 13:51:40 +00003318 if (LocaleCompare("shave",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003319 {
cristy6fccee12011-10-20 18:43:18 +00003320 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003321 flags=ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003322 new_image=ShaveImage(*image,&geometry,exception);
3323 break;
3324 }
anthonydcf510d2011-10-30 13:51:40 +00003325 if (LocaleCompare("shear",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003326 {
cristy6fccee12011-10-20 18:43:18 +00003327 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003328 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003329 if ((flags & SigmaValue) == 0)
3330 geometry_info.sigma=geometry_info.rho;
3331 new_image=ShearImage(*image,geometry_info.rho,
3332 geometry_info.sigma,exception);
3333 break;
3334 }
anthonydcf510d2011-10-30 13:51:40 +00003335 if (LocaleCompare("sigmoidal-contrast",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003336 {
cristy6fccee12011-10-20 18:43:18 +00003337 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003338 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003339 if ((flags & SigmaValue) == 0)
3340 geometry_info.sigma=(double) QuantumRange/2.0;
3341 if ((flags & PercentValue) != 0)
3342 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3343 100.0;
3344 (void) SigmoidalContrastImage(*image,(*argv[0] == '-') ?
3345 MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
3346 exception);
3347 break;
3348 }
anthonydcf510d2011-10-30 13:51:40 +00003349 if (LocaleCompare("sketch",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003350 {
cristy6fccee12011-10-20 18:43:18 +00003351 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003352 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003353 if ((flags & SigmaValue) == 0)
3354 geometry_info.sigma=1.0;
3355 new_image=SketchImage(*image,geometry_info.rho,
3356 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3357 break;
3358 }
anthonydcf510d2011-10-30 13:51:40 +00003359 if (LocaleCompare("solarize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003360 {
3361 double
3362 threshold;
3363
cristy6fccee12011-10-20 18:43:18 +00003364 (void) SyncImageSettings(image_info,*image,exception);
cristy9b34e302011-11-05 02:15:45 +00003365 threshold=StringToDoubleInterval(args[0],(double) QuantumRange+1.0);
anthony805a2d42011-09-25 08:25:12 +00003366 (void) SolarizeImage(*image,threshold,exception);
3367 break;
3368 }
anthonydcf510d2011-10-30 13:51:40 +00003369 if (LocaleCompare("sparse-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003370 {
3371 SparseColorMethod
3372 method;
3373
3374 char
3375 *arguments;
3376
cristy6fccee12011-10-20 18:43:18 +00003377 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003378 method=(SparseColorMethod) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00003379 MagickSparseColorOptions,MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003380 arguments=InterpretImageProperties(image_info,*image,argv[2],
3381 exception);
3382 if (arguments == (char *) NULL)
3383 break;
3384 new_image=SparseColorOption(*image,method,arguments,
3385 argv[0][0] == '+' ? MagickTrue : MagickFalse,exception);
3386 arguments=DestroyString(arguments);
3387 break;
3388 }
anthonydcf510d2011-10-30 13:51:40 +00003389 if (LocaleCompare("splice",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003390 {
cristy6fccee12011-10-20 18:43:18 +00003391 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003392 (void) ParseGravityGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003393 new_image=SpliceImage(*image,&geometry,exception);
3394 break;
3395 }
anthonydcf510d2011-10-30 13:51:40 +00003396 if (LocaleCompare("spread",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003397 {
cristy6fccee12011-10-20 18:43:18 +00003398 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003399 (void) ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003400 new_image=SpreadImage(*image,geometry_info.rho,
3401 interpolate_method,exception);
3402 break;
3403 }
anthonydcf510d2011-10-30 13:51:40 +00003404 if (LocaleCompare("statistic",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003405 {
3406 StatisticType
3407 type;
3408
cristy6fccee12011-10-20 18:43:18 +00003409 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003410 type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
anthonydcf510d2011-10-30 13:51:40 +00003411 MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003412 (void) ParseGeometry(argv[2],&geometry_info);
3413 new_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
3414 (size_t) geometry_info.sigma,exception);
3415 break;
3416 }
anthonydcf510d2011-10-30 13:51:40 +00003417 if (LocaleCompare("strip",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003418 {
cristy6fccee12011-10-20 18:43:18 +00003419 (void) SyncImageSettings(image_info,*image,exception);
anthony6613bf32011-10-15 07:24:44 +00003420 (void) StripImage(*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003421 break;
3422 }
anthonydcf510d2011-10-30 13:51:40 +00003423 if (LocaleCompare("swirl",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003424 {
cristy6fccee12011-10-20 18:43:18 +00003425 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003426 (void) ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003427 new_image=SwirlImage(*image,geometry_info.rho,
3428 interpolate_method,exception);
3429 break;
3430 }
3431 break;
3432 }
3433 case 't':
3434 {
anthonydcf510d2011-10-30 13:51:40 +00003435 if (LocaleCompare("threshold",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003436 {
3437 double
3438 threshold;
3439
cristy6fccee12011-10-20 18:43:18 +00003440 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003441 if (*argv[0] == '+')
3442 threshold=(double) QuantumRange/2;
3443 else
cristy9b34e302011-11-05 02:15:45 +00003444 threshold=StringToDoubleInterval(args[0],(double) QuantumRange+1.0);
anthony6613bf32011-10-15 07:24:44 +00003445 (void) BilevelImage(*image,threshold,exception);
anthony805a2d42011-09-25 08:25:12 +00003446 break;
3447 }
anthonydcf510d2011-10-30 13:51:40 +00003448 if (LocaleCompare("thumbnail",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003449 {
3450 /*
3451 Thumbnail image.
3452 */
cristy6fccee12011-10-20 18:43:18 +00003453 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003454 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003455 new_image=ThumbnailImage(*image,geometry.width,geometry.height,
3456 exception);
3457 break;
3458 }
anthonydcf510d2011-10-30 13:51:40 +00003459 if (LocaleCompare("tint",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003460 {
cristy6fccee12011-10-20 18:43:18 +00003461 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003462 new_image=TintImage(*image,args[0],&fill,exception);
anthony805a2d42011-09-25 08:25:12 +00003463 break;
3464 }
anthonydcf510d2011-10-30 13:51:40 +00003465 if (LocaleCompare("transform",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003466 {
cristy6fccee12011-10-20 18:43:18 +00003467 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003468 new_image=AffineTransformImage(*image,&draw_info->affine,
3469 exception);
3470 break;
3471 }
anthonydcf510d2011-10-30 13:51:40 +00003472 if (LocaleCompare("transparent",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003473 {
3474 PixelInfo
3475 target;
3476
cristy6fccee12011-10-20 18:43:18 +00003477 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003478 (void) QueryColorCompliance(args[0],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00003479 exception);
anthony805a2d42011-09-25 08:25:12 +00003480 (void) TransparentPaintImage(*image,&target,(Quantum)
3481 TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue,
cristy82d7af52011-10-16 16:26:41 +00003482 exception);
anthony805a2d42011-09-25 08:25:12 +00003483 break;
3484 }
anthonydcf510d2011-10-30 13:51:40 +00003485 if (LocaleCompare("transpose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003486 {
cristy6fccee12011-10-20 18:43:18 +00003487 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003488 new_image=TransposeImage(*image,exception);
3489 break;
3490 }
anthonydcf510d2011-10-30 13:51:40 +00003491 if (LocaleCompare("transverse",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003492 {
cristy6fccee12011-10-20 18:43:18 +00003493 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003494 new_image=TransverseImage(*image,exception);
3495 break;
3496 }
anthonydcf510d2011-10-30 13:51:40 +00003497 if (LocaleCompare("treedepth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003498 {
anthonydcf510d2011-10-30 13:51:40 +00003499 quantize_info->tree_depth=StringToUnsignedLong(args[0]);
anthony805a2d42011-09-25 08:25:12 +00003500 break;
3501 }
anthonydcf510d2011-10-30 13:51:40 +00003502 if (LocaleCompare("trim",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003503 {
cristy6fccee12011-10-20 18:43:18 +00003504 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003505 new_image=TrimImage(*image,exception);
3506 break;
3507 }
anthonydcf510d2011-10-30 13:51:40 +00003508 if (LocaleCompare("type",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003509 {
anthonyab3a50c2011-10-27 11:48:57 +00003510 /* Note that "type" setting should have already been defined */
cristy6fccee12011-10-20 18:43:18 +00003511 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003512 (void) SetImageType(*image,type,exception);
3513 break;
3514 }
3515 break;
3516 }
3517 case 'u':
3518 {
anthonydcf510d2011-10-30 13:51:40 +00003519 if (LocaleCompare("unique",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003520 {
3521 if (*argv[0] == '+')
3522 {
3523 (void) DeleteImageArtifact(*image,"identify:unique-colors");
3524 break;
3525 }
3526 (void) SetImageArtifact(*image,"identify:unique-colors","true");
3527 (void) SetImageArtifact(*image,"verbose","true");
3528 break;
3529 }
anthonydcf510d2011-10-30 13:51:40 +00003530 if (LocaleCompare("unique-colors",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003531 {
cristy6fccee12011-10-20 18:43:18 +00003532 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003533 new_image=UniqueImageColors(*image,exception);
3534 break;
3535 }
anthonydcf510d2011-10-30 13:51:40 +00003536 if (LocaleCompare("unsharp",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003537 {
cristy6fccee12011-10-20 18:43:18 +00003538 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003539 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003540 if ((flags & SigmaValue) == 0)
3541 geometry_info.sigma=1.0;
3542 if ((flags & XiValue) == 0)
3543 geometry_info.xi=1.0;
3544 if ((flags & PsiValue) == 0)
3545 geometry_info.psi=0.05;
3546 new_image=UnsharpMaskImage(*image,geometry_info.rho,
3547 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3548 break;
3549 }
3550 break;
3551 }
3552 case 'v':
3553 {
anthonydcf510d2011-10-30 13:51:40 +00003554 if (LocaleCompare("verbose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003555 {
anthonydcf510d2011-10-30 13:51:40 +00003556 (void) SetImageArtifact(*image,option,
anthonyab3a50c2011-10-27 11:48:57 +00003557 *argv[0] == '+' ? "false" : "true");
anthony805a2d42011-09-25 08:25:12 +00003558 break;
3559 }
anthonydcf510d2011-10-30 13:51:40 +00003560 if (LocaleCompare("vignette",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003561 {
3562 /*
3563 Vignette image.
3564 */
cristy6fccee12011-10-20 18:43:18 +00003565 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003566 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003567 if ((flags & SigmaValue) == 0)
3568 geometry_info.sigma=1.0;
3569 if ((flags & XiValue) == 0)
3570 geometry_info.xi=0.1*(*image)->columns;
3571 if ((flags & PsiValue) == 0)
3572 geometry_info.psi=0.1*(*image)->rows;
3573 new_image=VignetteImage(*image,geometry_info.rho,
cristyeb6e6582011-12-09 09:14:23 +00003574 geometry_info.sigma,(*image)->bias,(ssize_t)
3575 ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5),
3576 exception);
anthony805a2d42011-09-25 08:25:12 +00003577 break;
3578 }
anthonydcf510d2011-10-30 13:51:40 +00003579 if (LocaleCompare("virtual-pixel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003580 {
anthonyab3a50c2011-10-27 11:48:57 +00003581 /* setting already defined in image_info structure */
3582 SetImageVirtualPixelMethod(*image, image_info->virtual_pixel_method);
anthony805a2d42011-09-25 08:25:12 +00003583 break;
3584 }
3585 break;
3586 }
3587 case 'w':
3588 {
anthonydcf510d2011-10-30 13:51:40 +00003589 if (LocaleCompare("wave",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003590 {
cristy6fccee12011-10-20 18:43:18 +00003591 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003592 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003593 if ((flags & SigmaValue) == 0)
3594 geometry_info.sigma=1.0;
3595 new_image=WaveImage(*image,geometry_info.rho,
anthonya89dd172011-10-04 13:29:35 +00003596 geometry_info.sigma,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003597 break;
3598 }
anthonydcf510d2011-10-30 13:51:40 +00003599 if (LocaleCompare("white-threshold",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003600 {
cristy6fccee12011-10-20 18:43:18 +00003601 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003602 (void) WhiteThresholdImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003603 break;
3604 }
3605 break;
3606 }
3607 default:
3608 break;
3609 }
3610 /*
3611 Replace current image with any image that was generated
3612 */
3613 if (new_image != (Image *) NULL)
3614 ReplaceImageInListReturnLast(image,new_image);
3615
3616 /*
3617 Free resources.
3618 */
3619 quantize_info=DestroyQuantizeInfo(quantize_info);
3620 draw_info=DestroyDrawInfo(draw_info);
cristy82d7af52011-10-16 16:26:41 +00003621 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthonya89dd172011-10-04 13:29:35 +00003622 return(status == 0 ? MagickFalse : MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003623}
3624
3625/*
3626%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3627% %
3628% %
3629% %
3630+ S e q u e n c e O p e r a t i o n I m a g e s %
3631% %
3632% %
3633% %
3634%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3635%
3636% SequenceOperationImages() applies a single operation that apply to the
3637% entire image list (e.g. -append, -layers, -coalesce, etc.).
3638%
3639% The format of the MogrifyImage method is:
3640%
3641% MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3642% const int argc, const char **argv,Image **images,
3643% ExceptionInfo *exception)
3644%
3645% A description of each parameter follows:
3646%
3647% o image_info: the image info..
3648%
3649% o argc: Specifies a pointer to an integer describing the number of
3650% elements in the argument vector.
3651%
3652% o argv: Specifies a pointer to a text array containing the command line
3653% arguments.
3654%
3655% o images: pointer to pointer of the first image in image list.
3656%
3657% o exception: return any errors or warnings in this structure.
3658%
3659*/
3660WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3661 const int argc,const char **argv,Image **images,ExceptionInfo *exception)
3662{
3663
3664 MagickStatusType
3665 status;
3666
3667 QuantizeInfo
3668 *quantize_info;
3669
3670 assert(image_info != (ImageInfo *) NULL);
3671 assert(image_info->signature == MagickSignature);
3672 assert(images != (Image **) NULL);
3673 assert((*images)->previous == (Image *) NULL);
3674 assert((*images)->signature == MagickSignature);
3675 if ((*images)->debug != MagickFalse)
3676 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3677 (*images)->filename);
anthonya89dd172011-10-04 13:29:35 +00003678 if ((argc <= 0) || (*argv == (char *) NULL))
3679 return(MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003680 status=MagickTrue;
3681
3682 switch (*(argv[0]+1))
3683 {
3684 case 'a':
3685 {
3686 if (LocaleCompare("affinity",argv[0]+1) == 0)
3687 {
cristy6fccee12011-10-20 18:43:18 +00003688 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003689 if (*argv[0] == '+')
3690 {
3691 (void) RemapImages(quantize_info,*images,(Image *) NULL,
3692 exception);
3693 break;
3694 }
3695 break;
3696 }
3697 if (LocaleCompare("append",argv[0]+1) == 0)
3698 {
3699 Image
3700 *append_image;
3701
cristy6fccee12011-10-20 18:43:18 +00003702 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003703 append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue :
3704 MagickFalse,exception);
3705 if (append_image == (Image *) NULL)
3706 {
3707 status=MagickFalse;
3708 break;
3709 }
3710 *images=DestroyImageList(*images);
3711 *images=append_image;
3712 break;
3713 }
3714 if (LocaleCompare("average",argv[0]+1) == 0)
3715 {
3716 Image
3717 *average_image;
3718
3719 /*
3720 Average an image sequence (deprecated).
3721 */
cristy6fccee12011-10-20 18:43:18 +00003722 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003723 average_image=EvaluateImages(*images,MeanEvaluateOperator,
3724 exception);
3725 if (average_image == (Image *) NULL)
3726 {
3727 status=MagickFalse;
3728 break;
3729 }
3730 *images=DestroyImageList(*images);
3731 *images=average_image;
3732 break;
3733 }
3734 break;
3735 }
3736 case 'c':
3737 {
3738 if (LocaleCompare("channel",argv[0]+1) == 0)
3739 {
3740 ChannelType
3741 channel;
3742
3743 if (*argv[0] == '+')
3744 {
3745 channel=DefaultChannels;
3746 break;
3747 }
3748 channel=(ChannelType) ParseChannelOption(argv[1]);
3749 SetPixelChannelMap(*images,channel);
3750 break;
3751 }
3752 if (LocaleCompare("clut",argv[0]+1) == 0)
3753 {
3754 Image
3755 *clut_image,
3756 *image;
3757
cristy6fccee12011-10-20 18:43:18 +00003758 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003759 image=RemoveFirstImageFromList(images);
3760 clut_image=RemoveFirstImageFromList(images);
3761 if (clut_image == (Image *) NULL)
3762 {
3763 status=MagickFalse;
3764 break;
3765 }
anthonya89dd172011-10-04 13:29:35 +00003766 (void) ClutImage(image,clut_image,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003767 clut_image=DestroyImage(clut_image);
3768 *images=DestroyImageList(*images);
3769 *images=image;
3770 break;
3771 }
3772 if (LocaleCompare("coalesce",argv[0]+1) == 0)
3773 {
3774 Image
3775 *coalesce_image;
3776
cristy6fccee12011-10-20 18:43:18 +00003777 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003778 coalesce_image=CoalesceImages(*images,exception);
3779 if (coalesce_image == (Image *) NULL)
3780 {
3781 status=MagickFalse;
3782 break;
3783 }
3784 *images=DestroyImageList(*images);
3785 *images=coalesce_image;
3786 break;
3787 }
3788 if (LocaleCompare("combine",argv[0]+1) == 0)
3789 {
3790 Image
3791 *combine_image;
3792
cristy6fccee12011-10-20 18:43:18 +00003793 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003794 combine_image=CombineImages(*images,exception);
3795 if (combine_image == (Image *) NULL)
3796 {
3797 status=MagickFalse;
3798 break;
3799 }
3800 *images=DestroyImageList(*images);
3801 *images=combine_image;
3802 break;
3803 }
3804 if (LocaleCompare("composite",argv[0]+1) == 0)
3805 {
3806 Image
3807 *mask_image,
3808 *composite_image,
3809 *image;
3810
3811 RectangleInfo
3812 geometry;
3813
anthony5f867ae2011-10-09 10:28:34 +00003814 ComposeOperator
3815 compose;
3816
3817 const char*
3818 value;
3819
3820 value=GetImageOption(image_info,"compose");
3821 if (value != (const char *) NULL)
3822 compose=(CompositeOperator) ParseCommandOption(
3823 MagickComposeOptions,MagickFalse,value);
3824 else
3825 compose=OverCompositeOp; /* use Over not image->compose */
3826
3827 const char*
3828 value=GetImageOption(image_info,"compose");
3829
3830 if (value != (const char *) NULL)
3831 compose=(CompositeOperator) ParseCommandOption(
3832 MagickComposeOptions,MagickFalse,value);
3833 else
3834 compose=OverCompositeOp; /* use Over not image->compose */
3835
3836
cristy6fccee12011-10-20 18:43:18 +00003837 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003838 image=RemoveFirstImageFromList(images);
3839 composite_image=RemoveFirstImageFromList(images);
3840 if (composite_image == (Image *) NULL)
3841 {
3842 status=MagickFalse;
3843 break;
3844 }
3845 (void) TransformImage(&composite_image,(char *) NULL,
anthony6613bf32011-10-15 07:24:44 +00003846 composite_image->geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003847 SetGeometry(composite_image,&geometry);
3848 (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
3849 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
3850 &geometry);
3851 mask_image=RemoveFirstImageFromList(images);
3852 if (mask_image != (Image *) NULL)
3853 {
anthony5f867ae2011-10-09 10:28:34 +00003854 if ((compose == DisplaceCompositeOp) ||
3855 (compose == DistortCompositeOp))
anthony805a2d42011-09-25 08:25:12 +00003856 {
3857 /*
3858 Merge Y displacement into X displacement image.
3859 */
3860 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
anthony6613bf32011-10-15 07:24:44 +00003861 mask_image,0,0,exception);
anthony805a2d42011-09-25 08:25:12 +00003862 mask_image=DestroyImage(mask_image);
3863 }
3864 else
3865 {
3866 /*
3867 Set a blending mask for the composition.
anthony80c37752012-01-16 01:03:11 +00003868 Possible problem, what if image->mask already set.
anthony805a2d42011-09-25 08:25:12 +00003869 */
3870 image->mask=mask_image;
3871 (void) NegateImage(image->mask,MagickFalse,exception);
3872 }
3873 }
anthony5f867ae2011-10-09 10:28:34 +00003874 (void) CompositeImage(image,compose,composite_image,
anthony6613bf32011-10-15 07:24:44 +00003875 geometry.x,geometry.y,exception);
anthony805a2d42011-09-25 08:25:12 +00003876 if (mask_image != (Image *) NULL)
anthony80c37752012-01-16 01:03:11 +00003877 {
3878 image->mask=DestroyImage(image->mask);
3879 mask_image=(Image *) NULL;
3880 }
anthony805a2d42011-09-25 08:25:12 +00003881 composite_image=DestroyImage(composite_image);
anthony805a2d42011-09-25 08:25:12 +00003882 *images=DestroyImageList(*images);
3883 *images=image;
3884 break;
3885 }
3886 break;
3887 }
3888 case 'd':
3889 {
3890 if (LocaleCompare("deconstruct",argv[0]+1) == 0)
3891 {
3892 Image
3893 *deconstruct_image;
3894
cristy6fccee12011-10-20 18:43:18 +00003895 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003896 deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
3897 exception);
3898 if (deconstruct_image == (Image *) NULL)
3899 {
3900 status=MagickFalse;
3901 break;
3902 }
3903 *images=DestroyImageList(*images);
3904 *images=deconstruct_image;
3905 break;
3906 }
3907 if (LocaleCompare("delete",argv[0]+1) == 0)
3908 {
3909 if (*argv[0] == '+')
3910 DeleteImages(images,"-1",exception);
3911 else
3912 DeleteImages(images,argv[1],exception);
3913 break;
3914 }
3915 if (LocaleCompare("dither",argv[0]+1) == 0)
3916 {
3917 if (*argv[0] == '+')
3918 {
3919 quantize_info->dither=MagickFalse;
3920 break;
3921 }
3922 quantize_info->dither=MagickTrue;
3923 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
3924 MagickDitherOptions,MagickFalse,argv[1]);
3925 break;
3926 }
3927 if (LocaleCompare("duplicate",argv[0]+1) == 0)
3928 {
3929 Image
3930 *duplicate_images;
3931
3932 if (*argv[0] == '+')
3933 duplicate_images=DuplicateImages(*images,1,"-1",exception);
3934 else
3935 {
3936 const char
3937 *p;
3938
3939 size_t
3940 number_duplicates;
3941
3942 number_duplicates=(size_t) StringToLong(argv[1]);
3943 p=strchr(argv[1],',');
3944 if (p == (const char *) NULL)
3945 duplicate_images=DuplicateImages(*images,number_duplicates,
3946 "-1",exception);
3947 else
3948 duplicate_images=DuplicateImages(*images,number_duplicates,p,
3949 exception);
3950 }
3951 AppendImageToList(images, duplicate_images);
cristy6fccee12011-10-20 18:43:18 +00003952 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003953 break;
3954 }
3955 break;
3956 }
3957 case 'e':
3958 {
3959 if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0)
3960 {
3961 Image
3962 *evaluate_image;
3963
3964 MagickEvaluateOperator
3965 op;
3966
3967 (void) SyncImageSettings(image_info,*images);
3968 op=(MagickEvaluateOperator) ParseCommandOption(
3969 MagickEvaluateOptions,MagickFalse,argv[1]);
3970 evaluate_image=EvaluateImages(*images,op,exception);
3971 if (evaluate_image == (Image *) NULL)
3972 {
3973 status=MagickFalse;
3974 break;
3975 }
3976 *images=DestroyImageList(*images);
3977 *images=evaluate_image;
3978 break;
3979 }
3980 break;
3981 }
3982 case 'f':
3983 {
3984 if (LocaleCompare("fft",argv[0]+1) == 0)
3985 {
3986 Image
3987 *fourier_image;
3988
3989 /*
3990 Implements the discrete Fourier transform (DFT).
3991 */
3992 (void) SyncImageSettings(image_info,*images);
3993 fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ?
3994 MagickTrue : MagickFalse,exception);
3995 if (fourier_image == (Image *) NULL)
3996 break;
3997 *images=DestroyImage(*images);
3998 *images=fourier_image;
3999 break;
4000 }
4001 if (LocaleCompare("flatten",argv[0]+1) == 0)
4002 {
4003 Image
4004 *flatten_image;
4005
cristy6fccee12011-10-20 18:43:18 +00004006 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004007 flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
4008 if (flatten_image == (Image *) NULL)
4009 break;
4010 *images=DestroyImageList(*images);
4011 *images=flatten_image;
4012 break;
4013 }
4014 if (LocaleCompare("fx",argv[0]+1) == 0)
4015 {
4016 Image
4017 *fx_image;
4018
cristy6fccee12011-10-20 18:43:18 +00004019 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004020 fx_image=FxImage(*images,argv[1],exception);
4021 if (fx_image == (Image *) NULL)
4022 {
4023 status=MagickFalse;
4024 break;
4025 }
4026 *images=DestroyImageList(*images);
4027 *images=fx_image;
4028 break;
4029 }
4030 break;
4031 }
4032 case 'h':
4033 {
4034 if (LocaleCompare("hald-clut",argv[0]+1) == 0)
4035 {
4036 Image
4037 *hald_image,
4038 *image;
4039
cristy6fccee12011-10-20 18:43:18 +00004040 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004041 image=RemoveFirstImageFromList(images);
4042 hald_image=RemoveFirstImageFromList(images);
4043 if (hald_image == (Image *) NULL)
4044 {
4045 status=MagickFalse;
4046 break;
4047 }
4048 (void) HaldClutImage(image,hald_image,exception);
4049 hald_image=DestroyImage(hald_image);
4050 if (*images != (Image *) NULL)
4051 *images=DestroyImageList(*images);
4052 *images=image;
4053 break;
4054 }
4055 break;
4056 }
4057 case 'i':
4058 {
4059 if (LocaleCompare("ift",argv[0]+1) == 0)
4060 {
4061 Image
4062 *fourier_image,
4063 *magnitude_image,
4064 *phase_image;
4065
4066 /*
4067 Implements the inverse fourier discrete Fourier transform (DFT).
4068 */
cristy6fccee12011-10-20 18:43:18 +00004069 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004070 magnitude_image=RemoveFirstImageFromList(images);
4071 phase_image=RemoveFirstImageFromList(images);
4072 if (phase_image == (Image *) NULL)
4073 {
4074 status=MagickFalse;
4075 break;
4076 }
4077 fourier_image=InverseFourierTransformImage(magnitude_image,
4078 phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception);
4079 if (fourier_image == (Image *) NULL)
4080 break;
4081 if (*images != (Image *) NULL)
4082 *images=DestroyImage(*images);
4083 *images=fourier_image;
4084 break;
4085 }
4086 if (LocaleCompare("insert",argv[0]+1) == 0)
4087 {
4088 Image
4089 *p,
4090 *q;
4091
4092 index=0;
4093 if (*argv[0] != '+')
4094 index=(ssize_t) StringToLong(argv[1]);
4095 p=RemoveLastImageFromList(images);
4096 if (p == (Image *) NULL)
4097 {
4098 (void) ThrowMagickException(exception,GetMagickModule(),
4099 OptionError,"NoSuchImage","`%s'",argv[1]);
4100 status=MagickFalse;
4101 break;
4102 }
4103 q=p;
4104 if (index == 0)
4105 PrependImageToList(images,q);
4106 else
4107 if (index == (ssize_t) GetImageListLength(*images))
4108 AppendImageToList(images,q);
4109 else
4110 {
4111 q=GetImageFromList(*images,index-1);
4112 if (q == (Image *) NULL)
4113 {
4114 (void) ThrowMagickException(exception,GetMagickModule(),
4115 OptionError,"NoSuchImage","`%s'",argv[1]);
4116 status=MagickFalse;
4117 break;
4118 }
4119 InsertImageInList(&q,p);
4120 }
4121 *images=GetFirstImageInList(q);
4122 break;
4123 }
4124 if (LocaleCompare("interpolate",argv[0]+1) == 0)
4125 {
4126 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
4127 MagickInterpolateOptions,MagickFalse,argv[1]);
4128 break;
4129 }
4130 break;
4131 }
4132 case 'l':
4133 {
4134 if (LocaleCompare("layers",argv[0]+1) == 0)
4135 {
4136 Image
4137 *layers;
4138
4139 ImageLayerMethod
4140 method;
4141
cristy6fccee12011-10-20 18:43:18 +00004142 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004143 layers=(Image *) NULL;
4144 method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
4145 MagickFalse,argv[1]);
4146 switch (method)
4147 {
4148 case CoalesceLayer:
4149 {
4150 layers=CoalesceImages(*images,exception);
4151 break;
4152 }
4153 case CompareAnyLayer:
4154 case CompareClearLayer:
4155 case CompareOverlayLayer:
4156 default:
4157 {
4158 layers=CompareImagesLayers(*images,method,exception);
4159 break;
4160 }
4161 case MergeLayer:
4162 case FlattenLayer:
4163 case MosaicLayer:
4164 case TrimBoundsLayer:
4165 {
4166 layers=MergeImageLayers(*images,method,exception);
4167 break;
4168 }
4169 case DisposeLayer:
4170 {
4171 layers=DisposeImages(*images,exception);
4172 break;
4173 }
4174 case OptimizeImageLayer:
4175 {
4176 layers=OptimizeImageLayers(*images,exception);
4177 break;
4178 }
4179 case OptimizePlusLayer:
4180 {
4181 layers=OptimizePlusImageLayers(*images,exception);
4182 break;
4183 }
4184 case OptimizeTransLayer:
4185 {
4186 OptimizeImageTransparency(*images,exception);
4187 break;
4188 }
4189 case RemoveDupsLayer:
4190 {
4191 RemoveDuplicateLayers(images,exception);
4192 break;
4193 }
4194 case RemoveZeroLayer:
4195 {
4196 RemoveZeroDelayLayers(images,exception);
4197 break;
4198 }
4199 case OptimizeLayer:
4200 {
4201 /*
4202 General Purpose, GIF Animation Optimizer.
4203 */
4204 layers=CoalesceImages(*images,exception);
4205 if (layers == (Image *) NULL)
4206 {
4207 status=MagickFalse;
4208 break;
4209 }
4210 *images=DestroyImageList(*images);
4211 *images=layers;
4212 layers=OptimizeImageLayers(*images,exception);
4213 if (layers == (Image *) NULL)
4214 {
4215 status=MagickFalse;
4216 break;
4217 }
4218 *images=DestroyImageList(*images);
4219 *images=layers;
4220 layers=(Image *) NULL;
4221 OptimizeImageTransparency(*images,exception);
4222 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4223 exception);
4224 break;
4225 }
4226 case CompositeLayer:
4227 {
anthony805a2d42011-09-25 08:25:12 +00004228 Image
4229 *source;
4230
4231 RectangleInfo
4232 geometry;
4233
anthony5f867ae2011-10-09 10:28:34 +00004234 ComposeOperator
4235 compose;
4236
4237 const char*
4238 value;
4239
4240 value=GetImageOption(image_info,"compose");
4241 if (value != (const char *) NULL)
4242 compose=(CompositeOperator) ParseCommandOption(
4243 MagickComposeOptions,MagickFalse,value);
4244 else
4245 compose=OverCompositeOp; /* use Over not image->compose */
4246
anthony805a2d42011-09-25 08:25:12 +00004247 /*
4248 Split image sequence at the first 'NULL:' image.
4249 */
4250 source=(*images);
4251 while (source != (Image *) NULL)
4252 {
4253 source=GetNextImageInList(source);
4254 if ((source != (Image *) NULL) &&
4255 (LocaleCompare(source->magick,"NULL") == 0))
4256 break;
4257 }
4258 if (source != (Image *) NULL)
4259 {
4260 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4261 (GetNextImageInList(source) == (Image *) NULL))
4262 source=(Image *) NULL;
4263 else
4264 {
4265 /*
4266 Separate the two lists, junk the null: image.
4267 */
4268 source=SplitImageList(source->previous);
4269 DeleteImageFromList(&source);
4270 }
4271 }
4272 if (source == (Image *) NULL)
4273 {
4274 (void) ThrowMagickException(exception,GetMagickModule(),
4275 OptionError,"MissingNullSeparator","layers Composite");
4276 status=MagickFalse;
4277 break;
4278 }
4279 /*
4280 Adjust offset with gravity and virtual canvas.
4281 */
4282 SetGeometry(*images,&geometry);
4283 (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
4284 geometry.width=source->page.width != 0 ?
4285 source->page.width : source->columns;
4286 geometry.height=source->page.height != 0 ?
4287 source->page.height : source->rows;
4288 GravityAdjustGeometry((*images)->page.width != 0 ?
4289 (*images)->page.width : (*images)->columns,
4290 (*images)->page.height != 0 ? (*images)->page.height :
4291 (*images)->rows,(*images)->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004292
4293 /*
4294 Compose the two image sequences together
4295 */
anthony805a2d42011-09-25 08:25:12 +00004296 CompositeLayers(*images,compose,source,geometry.x,geometry.y,
4297 exception);
4298 source=DestroyImageList(source);
4299 break;
4300 }
4301 }
4302 if (layers == (Image *) NULL)
4303 break;
anthony805a2d42011-09-25 08:25:12 +00004304 *images=DestroyImageList(*images);
4305 *images=layers;
4306 break;
4307 }
4308 break;
4309 }
4310 case 'm':
4311 {
4312 if (LocaleCompare("map",argv[0]+1) == 0)
4313 {
cristy6fccee12011-10-20 18:43:18 +00004314 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004315 if (*argv[0] == '+')
4316 {
4317 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4318 exception);
4319 break;
4320 }
4321 break;
4322 }
4323 if (LocaleCompare("maximum",argv[0]+1) == 0)
4324 {
4325 Image
4326 *maximum_image;
4327
4328 /*
4329 Maximum image sequence (deprecated).
4330 */
cristy6fccee12011-10-20 18:43:18 +00004331 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004332 maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
4333 if (maximum_image == (Image *) NULL)
4334 {
4335 status=MagickFalse;
4336 break;
4337 }
4338 *images=DestroyImageList(*images);
4339 *images=maximum_image;
4340 break;
4341 }
4342 if (LocaleCompare("minimum",argv[0]+1) == 0)
4343 {
4344 Image
4345 *minimum_image;
4346
4347 /*
4348 Minimum image sequence (deprecated).
4349 */
cristy6fccee12011-10-20 18:43:18 +00004350 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004351 minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
4352 if (minimum_image == (Image *) NULL)
4353 {
4354 status=MagickFalse;
4355 break;
4356 }
4357 *images=DestroyImageList(*images);
4358 *images=minimum_image;
4359 break;
4360 }
4361 if (LocaleCompare("morph",argv[0]+1) == 0)
4362 {
4363 Image
4364 *morph_image;
4365
cristy6fccee12011-10-20 18:43:18 +00004366 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004367 morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]),
4368 exception);
4369 if (morph_image == (Image *) NULL)
4370 {
4371 status=MagickFalse;
4372 break;
4373 }
4374 *images=DestroyImageList(*images);
4375 *images=morph_image;
4376 break;
4377 }
4378 if (LocaleCompare("mosaic",argv[0]+1) == 0)
4379 {
4380 Image
4381 *mosaic_image;
4382
cristy6fccee12011-10-20 18:43:18 +00004383 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004384 mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
4385 if (mosaic_image == (Image *) NULL)
4386 {
4387 status=MagickFalse;
4388 break;
4389 }
4390 *images=DestroyImageList(*images);
4391 *images=mosaic_image;
4392 break;
4393 }
4394 break;
4395 }
4396 case 'p':
4397 {
4398 if (LocaleCompare("print",argv[0]+1) == 0)
4399 {
4400 char
4401 *string;
4402
cristy6fccee12011-10-20 18:43:18 +00004403 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004404 string=InterpretImageProperties(image_info,*images,argv[1],
4405 exception);
4406 if (string == (char *) NULL)
4407 break;
4408 (void) FormatLocaleFile(stdout,"%s",string);
4409 string=DestroyString(string);
4410 }
4411 if (LocaleCompare("process",argv[0]+1) == 0)
4412 {
4413 char
4414 **arguments;
4415
4416 int
4417 j,
4418 number_arguments;
4419
cristy6fccee12011-10-20 18:43:18 +00004420 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004421 arguments=StringToArgv(argv[1],&number_arguments);
4422 if (arguments == (char **) NULL)
4423 break;
4424 if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
4425 {
4426 char
4427 breaker,
4428 quote,
4429 *token;
4430
4431 const char
4432 *arguments;
4433
4434 int
4435 next,
4436 status;
4437
4438 size_t
4439 length;
4440
4441 TokenInfo
4442 *token_info;
4443
4444 /*
4445 Support old style syntax, filter="-option arg".
4446 */
4447 length=strlen(argv[1]);
4448 token=(char *) NULL;
4449 if (~length >= (MaxTextExtent-1))
4450 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4451 sizeof(*token));
4452 if (token == (char *) NULL)
4453 break;
4454 next=0;
4455 arguments=argv[1];
4456 token_info=AcquireTokenInfo();
4457 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4458 "\"",'\0',&breaker,&next,&quote);
4459 token_info=DestroyTokenInfo(token_info);
4460 if (status == 0)
4461 {
4462 const char
4463 *argv;
4464
4465 argv=(&(arguments[next]));
4466 (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
4467 exception);
4468 }
4469 token=DestroyString(token);
4470 break;
4471 }
4472 (void) SubstituteString(&arguments[1],"-","");
4473 (void) InvokeDynamicImageFilter(arguments[1],&(*images),
4474 number_arguments-2,(const char **) arguments+2,exception);
4475 for (j=0; j < number_arguments; j++)
4476 arguments[j]=DestroyString(arguments[j]);
4477 arguments=(char **) RelinquishMagickMemory(arguments);
4478 break;
4479 }
4480 break;
4481 }
4482 case 'r':
4483 {
4484 if (LocaleCompare("reverse",argv[0]+1) == 0)
4485 {
4486 ReverseImageList(images);
anthony805a2d42011-09-25 08:25:12 +00004487 break;
4488 }
4489 break;
4490 }
4491 case 's':
4492 {
4493 if (LocaleCompare("smush",argv[0]+1) == 0)
4494 {
4495 Image
4496 *smush_image;
4497
4498 ssize_t
4499 offset;
4500
cristy6fccee12011-10-20 18:43:18 +00004501 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004502 offset=(ssize_t) StringToLong(argv[1]);
4503 smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue :
4504 MagickFalse,offset,exception);
4505 if (smush_image == (Image *) NULL)
4506 {
4507 status=MagickFalse;
4508 break;
4509 }
4510 *images=DestroyImageList(*images);
4511 *images=smush_image;
4512 break;
4513 }
4514 if (LocaleCompare("swap",argv[0]+1) == 0)
4515 {
4516 Image
4517 *p,
4518 *q,
4519 *swap;
4520
4521 ssize_t
4522 swap_index;
4523
4524 index=(-1);
4525 swap_index=(-2);
4526 if (*argv[0] != '+')
4527 {
4528 GeometryInfo
4529 geometry_info;
4530
4531 MagickStatusType
4532 flags;
4533
4534 swap_index=(-1);
4535 flags=ParseGeometry(argv[1],&geometry_info);
4536 index=(ssize_t) geometry_info.rho;
4537 if ((flags & SigmaValue) != 0)
4538 swap_index=(ssize_t) geometry_info.sigma;
4539 }
4540 p=GetImageFromList(*images,index);
4541 q=GetImageFromList(*images,swap_index);
4542 if ((p == (Image *) NULL) || (q == (Image *) NULL))
4543 {
4544 (void) ThrowMagickException(exception,GetMagickModule(),
4545 OptionError,"NoSuchImage","`%s'",(*images)->filename);
4546 status=MagickFalse;
4547 break;
4548 }
4549 if (p == q)
4550 break;
4551 swap=CloneImage(p,0,0,MagickTrue,exception);
4552 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
4553 ReplaceImageInList(&q,swap);
4554 *images=GetFirstImageInList(q);
4555 break;
4556 }
4557 break;
4558 }
4559 case 'w':
4560 {
4561 if (LocaleCompare("write",argv[0]+1) == 0)
4562 {
4563 char
4564 key[MaxTextExtent];
4565
4566 Image
4567 *write_images;
4568
4569 ImageInfo
4570 *write_info;
4571
cristy6fccee12011-10-20 18:43:18 +00004572 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004573 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]);
4574 (void) DeleteImageRegistry(key);
4575 write_images=(*images);
4576 if (*argv[0] == '+')
4577 write_images=CloneImageList(*images,exception);
4578 write_info=CloneImageInfo(image_info);
4579 status&=WriteImages(write_info,write_images,argv[1],exception);
4580 write_info=DestroyImageInfo(write_info);
4581 if (*argv[0] == '+')
4582 write_images=DestroyImageList(write_images);
4583 break;
4584 }
4585 break;
4586 }
4587 default:
4588 break;
4589 }
4590 quantize_info=DestroyQuantizeInfo(quantize_info);
4591
cristy82d7af52011-10-16 16:26:41 +00004592 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthony805a2d42011-09-25 08:25:12 +00004593 return(status != 0 ? MagickTrue : MagickFalse);
4594}
cristy0a0ca4f2011-09-28 01:15:28 +00004595#endif