blob: b2ad69355fb25b237d6100acc029ca6bafbfe2d2 [file] [log] [blame]
anthony805a2d42011-09-25 08:25:12 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% OOO PPPP EEEE RRRR AA TTTTTT III OOO N N %
7% O O P P E R R A A TT I O O NN N %
8% O O PPPP EEE RRRR AAAA TT I O O N N N %
9% O O P E R R A A TT I O O N NN %
10% OOO P EEEE R RR A A TT III OOO N N %
11% %
12% %
13% MagickWand Module Methods %
14% %
15% Software Design %
16% John Cristy %
cristy0a0ca4f2011-09-28 01:15:28 +000017% September 2011 %
anthony805a2d42011-09-25 08:25:12 +000018% %
19% %
20% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% Apply the given options (settings, and simple, or sequence operations) to
37% the given image(s) according to the current "image_info" and "draw_info"
38% settings.
39%
40% The final goal is to allow the execution in a strict one option at a time
41% manner that is needed for 'pipelining and file scripting' of options in
42% IMv7.
43%
44% Anthony Thyssen, Sept 2011
45*/
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 }
268 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
269 /* Y coordinate */
270 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
271 if ( token[0] == '\0' ) break;
272 if ( isalpha((int) token[0]) || token[0] == '#' ) {
273 (void) ThrowMagickException(exception,GetMagickModule(),
274 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
275 "Color found, instead of Y-coord");
276 error = MagickTrue;
277 break;
278 }
279 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
280 /* color values for this control point */
281#if 0
282 if ( (color_from_image ) {
283 /* get color from image */
284 /* HOW??? */
285 }
286 else
287#endif
288 {
289 /* color name or function given in string argument */
290 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
291 if ( token[0] == '\0' ) break;
292 if ( isalpha((int) token[0]) || token[0] == '#' ) {
293 /* Color string given */
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;
317 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
318 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;
325 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
326 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;
333 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
334 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;
342 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
343 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;
351 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
352 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%
anthonydcf510d2011-10-30 13:51:40 +0000388% These options require no images to be present in the wand for them to be
389% able to be set. That is they may be used before the first image is read.
anthony805a2d42011-09-25 08:25:12 +0000390%
anthony1afdc7a2011-10-05 11:54:28 +0000391% The format of the ApplySettingOption method is:
392%
393% MagickBooleanType ApplySettingOption(MagickWand *wand,
anthonydcf510d2011-10-30 13:51:40 +0000394% const char *option, const MagickBooleanType set_option, const char
395% **args, ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000396%
397% A description of each parameter follows:
398%
anthony1afdc7a2011-10-05 11:54:28 +0000399% o wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +0000400%
anthonydcf510d2011-10-30 13:51:40 +0000401% o option: The option string to be set
anthony805a2d42011-09-25 08:25:12 +0000402%
anthonydcf510d2011-10-30 13:51:40 +0000403% o set_option: is the option being set, or reset to some default
404%
405% o arg: the single argument (if needed) to set this option.
anthony805a2d42011-09-25 08:25:12 +0000406%
407% o exception: return any errors or warnings in this structure.
408%
anthonydcf510d2011-10-30 13:51:40 +0000409%
410% Example usage (FUTURE)
411%
412% argc,argv
413% i=index in argv
414%
415% count=ParseCommandOption(MagickCommandOptions,MagickFalse,argv[i]);
416% flags=GetCommandOptionFlags(MagickCommandOptions,MagickFalse,argv[i]);
417% if ( flags == MagickCommandOptions )
418% ApplySettingsOption(wand, argv[i]+1,
419% (*argv[i])=='-' ? MagickTrue : MagickFalse,
420% (count>0)? argv[i+1]:(char *)NULL,
421% exception);
422% i += count+1;
423%
anthony805a2d42011-09-25 08:25:12 +0000424*/
anthonydcf510d2011-10-30 13:51:40 +0000425WandExport MagickBooleanType ApplySettingsOption(MagickWand *wand,
426 const char *option, const MagickBooleanType set_option, const char *arg,
427 ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000428{
anthony1afdc7a2011-10-05 11:54:28 +0000429 assert(wand != (MagickWand *) NULL);
430 assert(wand->signature == WandSignature);
431 assert(wand->draw_info != (DrawInfo *) NULL); /* ensure it is a CLI wand */
anthony1afdc7a2011-10-05 11:54:28 +0000432 if (wand->debug != MagickFalse)
433 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
anthony1afdc7a2011-10-05 11:54:28 +0000434
anthonydcf510d2011-10-30 13:51:40 +0000435#define image_info (wand->image_info)
436#define draw_info (wand->draw_info)
437#define quantize_info (wand->quantize_info)
438#define IfSetOption (set_option != MagickFalse)
439#define IfArgOption (IfSetOption?arg:(char *)NULL)
anthony74b1cfc2011-10-06 12:44:16 +0000440
441 switch (*option)
anthony805a2d42011-09-25 08:25:12 +0000442 {
443 case 'a':
444 {
anthony74b1cfc2011-10-06 12:44:16 +0000445 if (LocaleCompare("adjoin",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000446 {
anthonydcf510d2011-10-30 13:51:40 +0000447 image_info->adjoin = set_option;
anthony805a2d42011-09-25 08:25:12 +0000448 break;
449 }
anthony74b1cfc2011-10-06 12:44:16 +0000450 if (LocaleCompare("affine",option) == 0)
anthony1afdc7a2011-10-05 11:54:28 +0000451 {
anthonyafbaed72011-10-26 12:05:04 +0000452 /* draw_info setting only */
anthony74b1cfc2011-10-06 12:44:16 +0000453 if (IfSetOption)
anthonydcf510d2011-10-30 13:51:40 +0000454 (void) ParseAffineGeometry(arg,draw_info->affine,exception);
anthony74b1cfc2011-10-06 12:44:16 +0000455 else
456 GetAffineMatrix(draw_info->affine);
anthony1afdc7a2011-10-05 11:54:28 +0000457 break;
458 }
anthony74b1cfc2011-10-06 12:44:16 +0000459 if (LocaleCompare("antialias",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000460 {
anthony1afdc7a2011-10-05 11:54:28 +0000461 image_info->antialias =
462 draw_info->stroke_antialias =
anthonydcf510d2011-10-30 13:51:40 +0000463 draw_info->text_antialias = set_option;
anthony805a2d42011-09-25 08:25:12 +0000464 break;
465 }
anthony74b1cfc2011-10-06 12:44:16 +0000466 if (LocaleCompare("authenticate",option) == 0)
anthonydcf510d2011-10-30 13:51:40 +0000467 {
468 (void) SetImageOption(image_info,option,IfArgOption);
anthony805a2d42011-09-25 08:25:12 +0000469 break;
470 }
471 break;
472 }
473 case 'b':
474 {
anthony74b1cfc2011-10-06 12:44:16 +0000475 if (LocaleCompare("background",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000476 {
anthony74b1cfc2011-10-06 12:44:16 +0000477 /* FUTURE: both image_info attribute & ImageOption in use!
anthonyafbaed72011-10-26 12:05:04 +0000478 image_info only used for generating new images.
479 Note that +background, means fall-back to image
480 attribute so ImageOption is deleted, not set to a default.
anthony74b1cfc2011-10-06 12:44:16 +0000481 */
482 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000483 {
anthonydcf510d2011-10-30 13:51:40 +0000484 (void) SetImageOption(image_info,option,arg);
485 (void) QueryColorCompliance(arg,AllCompliance,
anthonyafbaed72011-10-26 12:05:04 +0000486 image_info->background_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000487 break;
488 }
anthonyafbaed72011-10-26 12:05:04 +0000489 (void) DeleteImageOption(image_info,option);
490 (void) QueryColorCompliance("none",AllCompliance,
491 image_info->background_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000492 break;
493 }
anthony74b1cfc2011-10-06 12:44:16 +0000494 if (LocaleCompare("bias",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000495 {
anthony74b1cfc2011-10-06 12:44:16 +0000496 /* FUTURE: bias OBSOLETED, replaced by "convolve:bias"
497 as it is actually rarely used except in direct convolve
498 Usage outside direct convolve is actally non-sensible!
499 */
500 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000501 IfSetOption ? arg : "0");
anthony805a2d42011-09-25 08:25:12 +0000502 break;
503 }
anthony74b1cfc2011-10-06 12:44:16 +0000504 if (LocaleCompare("black-point-compensation",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000505 {
anthonyafbaed72011-10-26 12:05:04 +0000506 /* Used as a image chromaticity setting */
anthony74b1cfc2011-10-06 12:44:16 +0000507 (void) SetImageOption(image_info,option,
508 IfSetOption ? "true" : "false" );
anthony805a2d42011-09-25 08:25:12 +0000509 break;
510 }
anthony74b1cfc2011-10-06 12:44:16 +0000511 if (LocaleCompare("blue-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000512 {
anthonyafbaed72011-10-26 12:05:04 +0000513 /* Image chromaticity X,Y NB: Y=X if Y not defined
514 Used by many coders including PNG
515 */
anthony74b1cfc2011-10-06 12:44:16 +0000516 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000517 IfSetOption ? arg : "0" );
anthony805a2d42011-09-25 08:25:12 +0000518 break;
519 }
anthony74b1cfc2011-10-06 12:44:16 +0000520 if (LocaleCompare("bordercolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000521 {
anthony74b1cfc2011-10-06 12:44:16 +0000522 /* FUTURE: both image_info attribute & ImageOption in use! */
523 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000524 {
anthonydcf510d2011-10-30 13:51:40 +0000525 (void) SetImageOption(image_info,option,arg);
526 (void) QueryColorCompliance(arg,AllCompliece,
anthony74b1cfc2011-10-06 12:44:16 +0000527 &image_info->border_color,exception);
anthonydcf510d2011-10-30 13:51:40 +0000528 (void) QueryColorCompliance(arg,AllCompliance,
anthony74b1cfc2011-10-06 12:44:16 +0000529 &draw_info->border_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000530 break;
531 }
anthony74b1cfc2011-10-06 12:44:16 +0000532 (void) DeleteImageOption(image_info,option);
533 (void) QueryColorCompliance(BorderColor,AllCompliance,
534 &image_info->border_color,exception);
535 (void) QueryColorCompliance(BorderColor,AllCompliance,
536 &draw_info->border_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000537 break;
538 }
anthony74b1cfc2011-10-06 12:44:16 +0000539 if (LocaleCompare("box",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000540 {
anthonyafbaed72011-10-26 12:05:04 +0000541 /* Only used to set draw_info for text drawing */
anthony74b1cfc2011-10-06 12:44:16 +0000542 const char
anthonydcf510d2011-10-30 13:51:40 +0000543 *value = IfSetOption ? arg : "none";
anthony74b1cfc2011-10-06 12:44:16 +0000544 (void) SetImageOption(image_info,option,value);
545 (void) QueryColorCompliance(value,AllCompliance,
546 &draw_info->undercolor,exception);
anthony805a2d42011-09-25 08:25:12 +0000547 break;
548 }
549 break;
550 }
551 case 'c':
552 {
anthony74b1cfc2011-10-06 12:44:16 +0000553 if (LocaleCompare("cache",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000554 {
555 MagickSizeType
556 limit;
557
558 limit=MagickResourceInfinity;
anthonydcf510d2011-10-30 13:51:40 +0000559 if (LocaleCompare("unlimited",arg) != 0)
560 limit=(MagickSizeType) SiPrefixToDouble(arg,100.0);
anthony805a2d42011-09-25 08:25:12 +0000561 (void) SetMagickResourceLimit(MemoryResource,limit);
562 (void) SetMagickResourceLimit(MapResource,2*limit);
563 break;
564 }
anthony74b1cfc2011-10-06 12:44:16 +0000565 if (LocaleCompare("caption",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000566 {
anthony74b1cfc2011-10-06 12:44:16 +0000567 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000568 IfSetOption ? arg : (const char*)NULL);
anthony805a2d42011-09-25 08:25:12 +0000569 break;
570 }
anthony74b1cfc2011-10-06 12:44:16 +0000571 if (LocaleCompare("channel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000572 {
anthonyafbaed72011-10-26 12:05:04 +0000573 /* FUTURE: This is also a SimpleImageOperator!!! */
anthony74b1cfc2011-10-06 12:44:16 +0000574 image_info->channel=(ChannelType) (
anthonydcf510d2011-10-30 13:51:40 +0000575 IfSetOption ? ParseChannelOption(arg) : DefaultChannels );
cristy947cb4c2011-10-20 18:41:46 +0000576 /* This is also a SimpleImageOperator */
anthony805a2d42011-09-25 08:25:12 +0000577 break;
578 }
anthony74b1cfc2011-10-06 12:44:16 +0000579 if (LocaleCompare("colorspace",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000580 {
anthonyafbaed72011-10-26 12:05:04 +0000581 /* Setting used for new images via AquireImage()
582 But also used as a SimpleImageOperator
583 Undefined colorspace means don't modify images on
584 read or as a operation */
anthony965524b2011-10-07 12:34:14 +0000585 image_info->colorspace=UndefinedColorspace;
anthonyd2cdc862011-10-07 14:07:17 +0000586 if (IfSetOption)
587 image_info->colorspace=(ColorspaceType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +0000588 MagickColorspaceOptions,MagickFalse,arg)
anthony805a2d42011-09-25 08:25:12 +0000589 break;
590 }
anthony74b1cfc2011-10-06 12:44:16 +0000591 if (LocaleCompare("comment",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000592 {
anthony965524b2011-10-07 12:34:14 +0000593 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000594 IfSetOption ? arg : (const char*)NULL);
anthony805a2d42011-09-25 08:25:12 +0000595 break;
596 }
anthony74b1cfc2011-10-06 12:44:16 +0000597 if (LocaleCompare("compose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000598 {
anthonyafbaed72011-10-26 12:05:04 +0000599 /* FUTURE: image_info should be used, but Option kept escapes
600 This setting should NOT be used to set image 'compose'
601 which is used by "-layer" operators is image_info is undefined
anthony965524b2011-10-07 12:34:14 +0000602 */
anthony5f867ae2011-10-09 10:28:34 +0000603 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000604 IfSetOption ? arg : (const char*)NULL);
anthony965524b2011-10-07 12:34:14 +0000605 image_info->compose=(CompositeOperator) ParseCommandOption(
anthony5f867ae2011-10-09 10:28:34 +0000606 MagickComposeOptions,MagickFalse,
anthonydcf510d2011-10-30 13:51:40 +0000607 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000608 break;
609 }
anthony74b1cfc2011-10-06 12:44:16 +0000610 if (LocaleCompare("compress",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000611 {
anthony5f867ae2011-10-09 10:28:34 +0000612 /* FUTURE: What should be used? image_info or ImageOption ???
613 The former is more efficent, but Crisy prefers the latter!
614
615 The coders appears to use image_info, not Image_Option
616 however the image attribute (for save) is set from the
617 ImageOption!
618 */
619 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000620 {
anthony5f867ae2011-10-09 10:28:34 +0000621 image_info->compression=(CompressionType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +0000622 MagickCompressOptions,MagickFalse,arg);
623 (void) SetImageOption(image_info,option,arg);
anthony805a2d42011-09-25 08:25:12 +0000624 break;
625 }
anthony5f867ae2011-10-09 10:28:34 +0000626 image_info->compression=UndefinedCompression;
627 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000628 break;
629 }
630 break;
631 }
632 case 'd':
633 {
anthony74b1cfc2011-10-06 12:44:16 +0000634 if (LocaleCompare("debug",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000635 {
anthony5f867ae2011-10-09 10:28:34 +0000636 if (IfSetOption)
anthonydcf510d2011-10-30 13:51:40 +0000637 (void) SetLogEventMask(IfSetOption?arg:"none");
anthony5f867ae2011-10-09 10:28:34 +0000638 image_info->debug=IsEventLogging(); /* extract logging*/
639 wand->debug=IsEventLogging();
anthony805a2d42011-09-25 08:25:12 +0000640 break;
641 }
anthony74b1cfc2011-10-06 12:44:16 +0000642 if (LocaleCompare("define",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000643 {
anthony5f867ae2011-10-09 10:28:34 +0000644 /* FUTURE both -set and -define sets ImageOption
anthonyafbaed72011-10-26 12:05:04 +0000645 But differs in that -set tries to set image properity (attributes)
anthony5f867ae2011-10-09 10:28:34 +0000646 */
anthonydcf510d2011-10-30 13:51:40 +0000647 if (LocaleNCompare(arg,"registry:",9) == 0)
anthony805a2d42011-09-25 08:25:12 +0000648 {
anthony5f867ae2011-10-09 10:28:34 +0000649 if (IfSetOption)
anthonydcf510d2011-10-30 13:51:40 +0000650 (void) DefineImageRegistry(StringRegistryType,arg+9,
anthony5f867ae2011-10-09 10:28:34 +0000651 exception);
652 else
anthonydcf510d2011-10-30 13:51:40 +0000653 (void) DefineImageOption(image_info,arg,exception);
anthony805a2d42011-09-25 08:25:12 +0000654 break;
655 }
anthony5f867ae2011-10-09 10:28:34 +0000656 if (IfSetOption)
anthonydcf510d2011-10-30 13:51:40 +0000657 (void) DefineImageOption(image_info,arg,exception);
anthony5f867ae2011-10-09 10:28:34 +0000658 else
anthonydcf510d2011-10-30 13:51:40 +0000659 (void) DeleteImageOption(image_info,arg,exception);
anthony805a2d42011-09-25 08:25:12 +0000660 break;
661 }
anthony74b1cfc2011-10-06 12:44:16 +0000662 if (LocaleCompare("delay",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000663 {
anthonyafbaed72011-10-26 12:05:04 +0000664 /* Only used for new images via AcquireImage()
665 FUTURE: Option should also be used for "-morph" (color morphing)
anthony5f867ae2011-10-09 10:28:34 +0000666 */
667 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000668 IfSetOption ? arg : "0");
anthony805a2d42011-09-25 08:25:12 +0000669 break;
670 }
anthony74b1cfc2011-10-06 12:44:16 +0000671 if (LocaleCompare("density",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000672 {
anthonyafbaed72011-10-26 12:05:04 +0000673 /* FUTURE: string in image_info - moved into Option ??? */
674 /* Used by both draw_info and in images via SyncImageSettings() */
675 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000676 {
anthonydcf510d2011-10-30 13:51:40 +0000677 (void) CloneString(&image_info->density,arg);
678 (void) CloneString(&draw_info->density,arg);
679 (void) SetImageOption(image_info,option,arg);
anthony805a2d42011-09-25 08:25:12 +0000680 break;
681 }
anthony5f867ae2011-10-09 10:28:34 +0000682 if (image_info->density != (char *) NULL)
683 image_info->density=DestroyString(image_info->density);
684 if (draw_info->density != (char *) NULL)
685 draw_info->density=DestroyString(draw_info->density);
686 (void) SetImageOption(image_info,option,"72");
anthony805a2d42011-09-25 08:25:12 +0000687 break;
688 }
anthony74b1cfc2011-10-06 12:44:16 +0000689 if (LocaleCompare("depth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000690 {
anthonydcf510d2011-10-30 13:51:40 +0000691 /* This is also a SimpleImageOperator! to set depth across images */
692 image_info->depth=IfSetOption?StringToUnsignedLong(arg)
anthony5f867ae2011-10-09 10:28:34 +0000693 :MAGICKCORE_QUANTUM_DEPTH;
anthony805a2d42011-09-25 08:25:12 +0000694 break;
695 }
anthony74b1cfc2011-10-06 12:44:16 +0000696 if (LocaleCompare("direction",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000697 {
anthony6dc09cd2011-10-12 08:56:49 +0000698 /* Image Option is only used to set draw_info */
anthony5f867ae2011-10-09 10:28:34 +0000699 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000700 IfSetOption ? arg : "undefined");
anthony5f867ae2011-10-09 10:28:34 +0000701 draw_info->direction=(DirectionType) ParseCommandOption(
702 MagickDirectionOptions,MagickFalse,
anthonydcf510d2011-10-30 13:51:40 +0000703 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000704 break;
705 }
anthony74b1cfc2011-10-06 12:44:16 +0000706 if (LocaleCompare("display",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000707 {
anthonyafbaed72011-10-26 12:05:04 +0000708 /* FUTURE: string in image_info - moved into Option ??? */
709 (void) CloneString(&image_info->server_name,
anthonydcf510d2011-10-30 13:51:40 +0000710 IfSetOption ? arg :(char *) NULL);
anthony805a2d42011-09-25 08:25:12 +0000711 break;
712 }
anthony74b1cfc2011-10-06 12:44:16 +0000713 if (LocaleCompare("dispose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000714 {
anthony5f867ae2011-10-09 10:28:34 +0000715 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000716 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000717 break;
718 }
anthony74b1cfc2011-10-06 12:44:16 +0000719 if (LocaleCompare("dither",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000720 {
anthonyafbaed72011-10-26 12:05:04 +0000721 /* FUTURE: merge all options to just Option and quantize_info! */
anthony5f867ae2011-10-09 10:28:34 +0000722 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000723 IfSetOption ? arg : "none");
anthony5f867ae2011-10-09 10:28:34 +0000724 image_info->dither = quantize_info->dither =
anthony6dc09cd2011-10-12 08:56:49 +0000725 IfSetOption ? MagickTrue : MagickFalse;
anthony5f867ae2011-10-09 10:28:34 +0000726 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
anthony6dc09cd2011-10-12 08:56:49 +0000727 MagickDitherOptions,MagickFalse,
anthonydcf510d2011-10-30 13:51:40 +0000728 IfSetOption ? arg : "none");
anthony5f867ae2011-10-09 10:28:34 +0000729 if (quantize_info->dither_method == NoDitherMethod)
anthony6dc09cd2011-10-12 08:56:49 +0000730 image_info->dither = quantize_info->dither = MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000731 break;
732 }
733 break;
734 }
735 case 'e':
736 {
anthony74b1cfc2011-10-06 12:44:16 +0000737 if (LocaleCompare("encoding",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000738 {
anthony6dc09cd2011-10-12 08:56:49 +0000739 (void) CloneString(&draw_info->encoding,
anthonydcf510d2011-10-30 13:51:40 +0000740 IfSetOption ? arg : "undefined");
anthony6dc09cd2011-10-12 08:56:49 +0000741 (void) SetImageOption(image_info,option,&draw_info->encoding);
anthony805a2d42011-09-25 08:25:12 +0000742 break;
743 }
anthony74b1cfc2011-10-06 12:44:16 +0000744 if (LocaleCompare("endian",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000745 {
anthony6dc09cd2011-10-12 08:56:49 +0000746 const char
747 value;
748
anthonydcf510d2011-10-30 13:51:40 +0000749 value=IfSetOption?arg:"undefined";
anthony6dc09cd2011-10-12 08:56:49 +0000750 (void) SetImageOption(image_info,option,value);
anthony805a2d42011-09-25 08:25:12 +0000751 image_info->endian=(EndianType) ParseCommandOption(
anthony6dc09cd2011-10-12 08:56:49 +0000752 MagickEndianOptions,MagickFalse,value);
anthony805a2d42011-09-25 08:25:12 +0000753 break;
754 }
anthony74b1cfc2011-10-06 12:44:16 +0000755 if (LocaleCompare("extract",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000756 {
anthony6dc09cd2011-10-12 08:56:49 +0000757 (void) CloneString(&image_info->extract,
anthonydcf510d2011-10-30 13:51:40 +0000758 IfSetOption?arg:(const char *) NULL);
anthony805a2d42011-09-25 08:25:12 +0000759 break;
760 }
761 break;
762 }
763 case 'f':
764 {
anthony6dc09cd2011-10-12 08:56:49 +0000765 if (LocaleCompare("family",argv[0]+1) == 0)
766 {
767 (void) CloneString(&draw_info->family,
anthonydcf510d2011-10-30 13:51:40 +0000768 IfSetOption ? arg : (const char *) NULL);
anthony6dc09cd2011-10-12 08:56:49 +0000769 break;
770 }
anthony74b1cfc2011-10-06 12:44:16 +0000771 if (LocaleCompare("fill",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000772 {
anthonyafbaed72011-10-26 12:05:04 +0000773 /* set fill OR a fill-pattern
774 color is only used by draw_info
775 but draw_info is only initialsed using the color not the pattern
776 */
anthony6dc09cd2011-10-12 08:56:49 +0000777 const char
778 value;
779
780 ExceptionInfo
781 *sans;
782
anthonydcf510d2011-10-30 13:51:40 +0000783 value = IfSetOption ? arg : "none";
anthony6dc09cd2011-10-12 08:56:49 +0000784 (void) SetImageOption(image_info,option,value);
785
786 sans=AcquireExceptionInfo();
anthony6dc09cd2011-10-12 08:56:49 +0000787 status=QueryColorCompliance(value,AllCompliance,&draw_info->fill,sans);
788 sans=DestroyExceptionInfo(sans);
789
790 if (draw_info->fill_pattern != (Image *) NULL)
791 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
792 if (status == MagickFalse)
793 draw_info->fill_pattern=GetImageCache(image_info,value,
794 exception);
anthony805a2d42011-09-25 08:25:12 +0000795 break;
796 }
anthony74b1cfc2011-10-06 12:44:16 +0000797 if (LocaleCompare("filter",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000798 {
anthony6dc09cd2011-10-12 08:56:49 +0000799 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +0000800 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000801 break;
802 }
anthonydcf510d2011-10-30 13:51:40 +0000803 if (LocaleCompare("font",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000804 {
anthony6dc09cd2011-10-12 08:56:49 +0000805 (void) CloneString(&draw_info->font,
anthonydcf510d2011-10-30 13:51:40 +0000806 IfSetOption ? arg : (const char *) NULL);
anthony6dc09cd2011-10-12 08:56:49 +0000807 (void) CloneString(&image_info->font,draw_info->font);
anthony805a2d42011-09-25 08:25:12 +0000808 break;
809 }
anthony74b1cfc2011-10-06 12:44:16 +0000810 if (LocaleCompare("format",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000811 {
anthonydcf510d2011-10-30 13:51:40 +0000812 /* FUTURE: why the ping test, you could set ping after this! */
813 /*
anthony805a2d42011-09-25 08:25:12 +0000814 register const char
815 *q;
816
anthonydcf510d2011-10-30 13:51:40 +0000817 for (q=strchr(arg,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
anthony805a2d42011-09-25 08:25:12 +0000818 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
819 image_info->ping=MagickFalse;
anthonydcf510d2011-10-30 13:51:40 +0000820 */
821 (void) SetImageOption(image_info,option,
822 IfSetOption ? arg : (const char *) NULL);
anthony805a2d42011-09-25 08:25:12 +0000823 break;
824 }
anthony74b1cfc2011-10-06 12:44:16 +0000825 if (LocaleCompare("fuzz",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000826 {
anthony6613bf32011-10-15 07:24:44 +0000827 /* FUTURE: image_info and ImageOption!
828 Option used to set image fuzz! unless blank canvas (from color)
anthonydcf510d2011-10-30 13:51:40 +0000829 Image attribute used for color compare operations
830 image->fuzz is being set by SyncImageSettings()
cristy947cb4c2011-10-20 18:41:46 +0000831 Can't find anything using image_info->fuzz (except cloning)!
anthony6613bf32011-10-15 07:24:44 +0000832 */
833 if (IfSetOption)
cristy947cb4c2011-10-20 18:41:46 +0000834 {
anthonydcf510d2011-10-30 13:51:40 +0000835 image_info->fuzz=SiPrefixToDouble(arg,(double) QuantumRange+1.0);
836 (void) SetImageOption(image_info,option,arg);
cristy947cb4c2011-10-20 18:41:46 +0000837 break;
838 }
839 image_info->fuzz=0.0;
840 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +0000841 break;
842 }
843 break;
844 }
845 case 'g':
846 {
anthony74b1cfc2011-10-06 12:44:16 +0000847 if (LocaleCompare("gravity",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000848 {
anthonydcf510d2011-10-30 13:51:40 +0000849 /* FUTURE gravity also set in image via SyncImageSettings() */
850 const char
851 value;
852
853 value = IfSetOption ? arg : "none";
854 (void) SetImageOption(image_info,option,value);
anthony6dc09cd2011-10-12 08:56:49 +0000855 draw_info->gravity=(GravityType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +0000856 MagickGravityOptions,MagickFalse,value);
anthony805a2d42011-09-25 08:25:12 +0000857 break;
858 }
anthony74b1cfc2011-10-06 12:44:16 +0000859 if (LocaleCompare("green-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000860 {
anthonydcf510d2011-10-30 13:51:40 +0000861 /* Image chromaticity X,Y NB: Y=X if Y not defined
862 Used by many coders
863 */
864 (void) SetImageOption(image_info,option,
865 IfSetOption ? arg : "0.0");
anthony805a2d42011-09-25 08:25:12 +0000866 break;
867 }
868 break;
869 }
870 case 'i':
871 {
anthony74b1cfc2011-10-06 12:44:16 +0000872 if (LocaleCompare("intent",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000873 {
anthonydcf510d2011-10-30 13:51:40 +0000874 /* FUTURE: sets image->rendering_intent in SyncImagesSettings
875 Which is only used by coders: MIFF, MPC, BMP, PNG
876 and for image profile call to AcquireTransformThreadSet()
877 */
878 (void) SetImageOption(image_info,option,
879 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000880 break;
881 }
anthony74b1cfc2011-10-06 12:44:16 +0000882 if (LocaleCompare("interlace",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000883 {
anthonydcf510d2011-10-30 13:51:40 +0000884 /* sets image attibute interlace via SyncImageSettings()
885 Also image_info is directly used by coders
886 */
887 const char
888 value;
889
890 value = IfSetOption ? arg : "undefined";
891 (void) SetImageOption(image_info,option, value);
anthony805a2d42011-09-25 08:25:12 +0000892 image_info->interlace=(InterlaceType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +0000893 MagickInterlaceOptions,MagickFalse,arg);
894 (void) SetImageOption(image_info,option,arg);
anthony805a2d42011-09-25 08:25:12 +0000895 break;
896 }
anthony74b1cfc2011-10-06 12:44:16 +0000897 if (LocaleCompare("interline-spacing",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000898 {
anthonydcf510d2011-10-30 13:51:40 +0000899 const char
900 value;
901
902 value = IfSetOption ? arg : "0"; /* undefined? */
903 (void) SetImageOption(image_info,option, value);
904 draw_info->interline_spacing=InterpretLocaleValue(value,
905 (char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000906 break;
907 }
anthony74b1cfc2011-10-06 12:44:16 +0000908 if (LocaleCompare("interpolate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000909 {
anthonydcf510d2011-10-30 13:51:40 +0000910 /* FUTURE: sets image interpolate value via SyncImageSettings()
911 It is NOT used by coders, only in image processing,
912 so shoud really be a image_info attribute.
913 */
914 (void) SetImageOption(image_info,option,
915 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000916 break;
917 }
cristy947cb4c2011-10-20 18:41:46 +0000918 if (LocaleCompare("interword-spacing",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000919 {
anthonydcf510d2011-10-30 13:51:40 +0000920 const char
921 value;
922
923 value = IfSetOption ? arg : "0"; /* undefined? */
924 (void) SetImageOption(image_info,option, value);
925 draw_info->interword_spacing=InterpretLocaleValue(value,
926 (char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000927 break;
928 }
929 break;
930 }
931 case 'k':
932 {
anthony74b1cfc2011-10-06 12:44:16 +0000933 if (LocaleCompare("kerning",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000934 {
anthonydcf510d2011-10-30 13:51:40 +0000935 const char
936 value;
937
938 value = IfSetOption ? arg : "0"; /* undefined? */
939 (void) SetImageOption(image_info,option, value);
940 draw_info->kerning=InterpretLocaleValue(value,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000941 break;
942 }
943 break;
944 }
945 case 'l':
946 {
anthony74b1cfc2011-10-06 12:44:16 +0000947 if (LocaleCompare("label",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000948 {
anthonydcf510d2011-10-30 13:51:40 +0000949 /* only used for new images */
950 (void) SetImageOption(image_info,option,
951 IfSetOption ? arg : (char *)NULL);
anthony805a2d42011-09-25 08:25:12 +0000952 break;
953 }
anthony74b1cfc2011-10-06 12:44:16 +0000954 if (LocaleCompare("limit",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000955 {
956 MagickSizeType
957 limit;
958
959 ResourceType
960 type;
961
anthonydcf510d2011-10-30 13:51:40 +0000962 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000963 break;
964 type=(ResourceType) ParseCommandOption(MagickResourceOptions,
anthonydcf510d2011-10-30 13:51:40 +0000965 MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +0000966 limit=MagickResourceInfinity;
967 if (LocaleCompare("unlimited",argv[2]) != 0)
968 limit=(MagickSizeType) SiPrefixToDouble(argv[2],100.0);
969 (void) SetMagickResourceLimit(type,limit);
970 break;
971 }
anthony74b1cfc2011-10-06 12:44:16 +0000972 if (LocaleCompare("list",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000973 {
974 ssize_t
975 list;
976
anthonydcf510d2011-10-30 13:51:40 +0000977 list=ParseCommandOption(MagickListOptions,MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +0000978 switch (list)
979 {
980 case MagickCoderOptions:
981 {
982 (void) ListCoderInfo((FILE *) NULL,exception);
983 break;
984 }
985 case MagickColorOptions:
986 {
987 (void) ListColorInfo((FILE *) NULL,exception);
988 break;
989 }
990 case MagickConfigureOptions:
991 {
992 (void) ListConfigureInfo((FILE *) NULL,exception);
993 break;
994 }
995 case MagickDelegateOptions:
996 {
997 (void) ListDelegateInfo((FILE *) NULL,exception);
998 break;
999 }
1000 case MagickFontOptions:
1001 {
1002 (void) ListTypeInfo((FILE *) NULL,exception);
1003 break;
1004 }
1005 case MagickFormatOptions:
1006 {
1007 (void) ListMagickInfo((FILE *) NULL,exception);
1008 break;
1009 }
1010 case MagickLocaleOptions:
1011 {
1012 (void) ListLocaleInfo((FILE *) NULL,exception);
1013 break;
1014 }
1015 case MagickLogOptions:
1016 {
1017 (void) ListLogInfo((FILE *) NULL,exception);
1018 break;
1019 }
1020 case MagickMagicOptions:
1021 {
1022 (void) ListMagicInfo((FILE *) NULL,exception);
1023 break;
1024 }
1025 case MagickMimeOptions:
1026 {
1027 (void) ListMimeInfo((FILE *) NULL,exception);
1028 break;
1029 }
1030 case MagickModuleOptions:
1031 {
1032 (void) ListModuleInfo((FILE *) NULL,exception);
1033 break;
1034 }
1035 case MagickPolicyOptions:
1036 {
1037 (void) ListPolicyInfo((FILE *) NULL,exception);
1038 break;
1039 }
1040 case MagickResourceOptions:
1041 {
1042 (void) ListMagickResourceInfo((FILE *) NULL,exception);
1043 break;
1044 }
1045 case MagickThresholdOptions:
1046 {
1047 (void) ListThresholdMaps((FILE *) NULL,exception);
1048 break;
1049 }
1050 default:
1051 {
1052 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
1053 exception);
1054 break;
1055 }
1056 }
1057 break;
1058 }
anthony74b1cfc2011-10-06 12:44:16 +00001059 if (LocaleCompare("log",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001060 {
anthonydcf510d2011-10-30 13:51:40 +00001061 if (IfSetOption)
1062 (void) SetLogFormat(arg);
anthony805a2d42011-09-25 08:25:12 +00001063 break;
1064 }
anthony74b1cfc2011-10-06 12:44:16 +00001065 if (LocaleCompare("loop",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001066 {
anthonydcf510d2011-10-30 13:51:40 +00001067 /* Sets image attibutes iterations via SyncImageSettings() */
1068 (void) SetImageOption(image_info,option,
1069 IfSetOption ? arg : "0");
anthony805a2d42011-09-25 08:25:12 +00001070 break;
1071 }
1072 break;
1073 }
1074 case 'm':
1075 {
cristy947cb4c2011-10-20 18:41:46 +00001076 if (LocaleCompare("matte",option) == 0)
1077 {
1078 if (*argv[0] == '+')
1079 {
1080 (void) SetImageOption(image_info,option,"false");
1081 break;
1082 }
1083 (void) SetImageOption(image_info,option,"true");
1084 break;
1085 }
anthony74b1cfc2011-10-06 12:44:16 +00001086 if (LocaleCompare("mattecolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001087 {
cristy947cb4c2011-10-20 18:41:46 +00001088 if (*argv[0] == '+')
1089 {
anthonydcf510d2011-10-30 13:51:40 +00001090 (void) SetImageOption(image_info,option,arg);
cristy947cb4c2011-10-20 18:41:46 +00001091 (void) QueryColorCompliance(MatteColor,AllCompliance,
1092 &image_info->matte_color,exception);
1093 break;
1094 }
anthonydcf510d2011-10-30 13:51:40 +00001095 (void) SetImageOption(image_info,option,arg);
1096 (void) QueryColorCompliance(arg,AllCompliance,&image_info->matte_color,
cristy947cb4c2011-10-20 18:41:46 +00001097 exception);
anthony805a2d42011-09-25 08:25:12 +00001098 break;
1099 }
anthony74b1cfc2011-10-06 12:44:16 +00001100 if (LocaleCompare("monitor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001101 {
1102 (void) SetImageInfoProgressMonitor(image_info,MonitorProgress,
1103 (void *) NULL);
1104 break;
1105 }
anthony74b1cfc2011-10-06 12:44:16 +00001106 if (LocaleCompare("monochrome",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001107 {
anthonydcf510d2011-10-30 13:51:40 +00001108 /* Setting (for input coders) and a 'type' operation */
1109 image_info->monochrome=IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +00001110 break;
1111 }
1112 break;
1113 }
1114 case 'o':
1115 {
anthony74b1cfc2011-10-06 12:44:16 +00001116 if (LocaleCompare("orient",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001117 {
anthonydcf510d2011-10-30 13:51:40 +00001118 /* Sets image attribute orientation via SyncImageSettings()
1119 Is not used when defining for new images.
1120 This makes it more of a 'operation' than a setting
1121 */
1122 const char
1123 value;
1124
1125 value = IfSetOption ? arg : "undefined";
1126 (void) SetImageOption(image_info,option, value);
1127 image_info->orientation=(InterlaceType) ParseCommandOption(
1128 MagickOrientationOptions,MagickFalse,value);
anthony805a2d42011-09-25 08:25:12 +00001129 break;
1130 }
1131 }
1132 case 'p':
1133 {
anthony74b1cfc2011-10-06 12:44:16 +00001134 if (LocaleCompare("page",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001135 {
anthonydcf510d2011-10-30 13:51:40 +00001136 /* Only used for new images and image generators */
anthony805a2d42011-09-25 08:25:12 +00001137 char
1138 *canonical_page,
1139 page[MaxTextExtent];
1140
1141 const char
1142 *image_option;
1143
1144 MagickStatusType
1145 flags;
1146
1147 RectangleInfo
1148 geometry;
1149
anthonydcf510d2011-10-30 13:51:40 +00001150 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001151 {
anthony74b1cfc2011-10-06 12:44:16 +00001152 (void) DeleteImageOption(image_info,option);
anthony805a2d42011-09-25 08:25:12 +00001153 (void) CloneString(&image_info->page,(char *) NULL);
1154 break;
1155 }
1156 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
1157 image_option=GetImageOption(image_info,"page");
1158 if (image_option != (const char *) NULL)
1159 flags=ParseAbsoluteGeometry(image_option,&geometry);
anthonydcf510d2011-10-30 13:51:40 +00001160 canonical_page=GetPageGeometry(arg);
anthony805a2d42011-09-25 08:25:12 +00001161 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1162 canonical_page=DestroyString(canonical_page);
1163 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1164 (unsigned long) geometry.width,(unsigned long) geometry.height);
1165 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1166 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1167 (unsigned long) geometry.width,(unsigned long) geometry.height,
1168 (long) geometry.x,(long) geometry.y);
anthony74b1cfc2011-10-06 12:44:16 +00001169 (void) SetImageOption(image_info,option,page);
anthony805a2d42011-09-25 08:25:12 +00001170 (void) CloneString(&image_info->page,page);
1171 break;
1172 }
anthony74b1cfc2011-10-06 12:44:16 +00001173 if (LocaleCompare("ping",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001174 {
anthonydcf510d2011-10-30 13:51:40 +00001175 image_info->ping= IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +00001176 break;
1177 }
anthony74b1cfc2011-10-06 12:44:16 +00001178 if (LocaleCompare("pointsize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001179 {
anthonydcf510d2011-10-30 13:51:40 +00001180 double
1181 value=12.0;
1182
1183 if (IfSetOption)
1184 InterpretLocaleValue(arg,(char **) NULL);
1185 image_info->pointsize=draw_info->pointsize=value;
anthony805a2d42011-09-25 08:25:12 +00001186 break;
1187 }
anthony74b1cfc2011-10-06 12:44:16 +00001188 if (LocaleCompare("precision",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001189 {
anthonydcf510d2011-10-30 13:51:40 +00001190 (void) SetMagickPrecision(StringToInteger(arg));
anthony805a2d42011-09-25 08:25:12 +00001191 break;
1192 }
anthonydcf510d2011-10-30 13:51:40 +00001193 /* FUTURE: Only the 'preview' coder appears to use this
1194 * Depreciate the coder? Leaving only the 'preview' operator.
anthony74b1cfc2011-10-06 12:44:16 +00001195 if (LocaleCompare("preview",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001196 {
anthonydcf510d2011-10-30 13:51:40 +00001197 image_info->preview_type=UndefinedPreview;
1198 if (IfSetOption)
1199 image_info->preview_type=(PreviewType) ParseCommandOption(
1200 MagickPreviewOptions,MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +00001201 break;
1202 }
anthonydcf510d2011-10-30 13:51:40 +00001203 */
anthony805a2d42011-09-25 08:25:12 +00001204 break;
1205 }
1206 case 'q':
1207 {
anthony74b1cfc2011-10-06 12:44:16 +00001208 if (LocaleCompare("quality",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001209 {
anthonydcf510d2011-10-30 13:51:40 +00001210 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001211 {
anthonydcf510d2011-10-30 13:51:40 +00001212 image_info->quality=StringToUnsignedLong(arg);
1213 (void) SetImageOption(image_info,option,arg);
anthony805a2d42011-09-25 08:25:12 +00001214 break;
1215 }
anthonydcf510d2011-10-30 13:51:40 +00001216 image_info->quality=UndefinedCompressionQuality;
1217 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001218 break;
1219 }
anthonyafbaed72011-10-26 12:05:04 +00001220 if (LocaleCompare("quantize",option) == 0)
1221 {
1222 /* no image_info setting! Only set direct in quantize_info */
1223 quantize_info->colorspace=UndefinedColorspace;
1224 if (IfSetOption)
1225 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00001226 MagickColorspaceOptions,MagickFalse,arg);
anthonyafbaed72011-10-26 12:05:04 +00001227 break;
1228 }
anthony74b1cfc2011-10-06 12:44:16 +00001229 if (LocaleCompare("quiet",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001230 {
anthonydcf510d2011-10-30 13:51:40 +00001231 /* FUTURE: if two -quiet is performed you can not do +quiet! */
anthony805a2d42011-09-25 08:25:12 +00001232 static WarningHandler
1233 warning_handler = (WarningHandler) NULL;
anthonyafbaed72011-10-26 12:05:04 +00001234 WarningHandler
1235 tmp = SetWarningHandler((WarningHandler) NULL);
anthony805a2d42011-09-25 08:25:12 +00001236
anthonyafbaed72011-10-26 12:05:04 +00001237 if ( tmp != (WarningHandler) NULL)
1238 warning_handler = tmp; /* remember the old handler */
1239 if (!IfSetOption) /* set the old handler */
1240 warning_handler=SetWarningHandler(warning_handler);
anthony805a2d42011-09-25 08:25:12 +00001241 break;
1242 }
1243 break;
1244 }
1245 case 'r':
1246 {
anthony74b1cfc2011-10-06 12:44:16 +00001247 if (LocaleCompare("red-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001248 {
anthonydcf510d2011-10-30 13:51:40 +00001249 /* Image chromaticity X,Y NB: Y=X if Y not defined
1250 Used by many coders
1251 */
1252 (void) SetImageOption(image_info,option,
1253 IfSetOption ? arg : "0" );
anthony805a2d42011-09-25 08:25:12 +00001254 break;
1255 }
anthonyafbaed72011-10-26 12:05:04 +00001256 if (LocaleCompare("render",option) == 0)
1257 {
1258 /* draw_info only setting */
1259 draw_info->render= IfSetOption ? MagickFalse : MagickTrue;
1260 break;
1261 }
anthony805a2d42011-09-25 08:25:12 +00001262 break;
1263 }
1264 case 's':
1265 {
anthony74b1cfc2011-10-06 12:44:16 +00001266 if (LocaleCompare("sampling-factor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001267 {
anthonyafbaed72011-10-26 12:05:04 +00001268 /* FUTURE: should be converted to jpeg:sampling_factor */
1269 (void) CloneString(&image_info->sampling_factor,
anthonydcf510d2011-10-30 13:51:40 +00001270 IfSetOption ? arg : (char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001271 break;
1272 }
anthony74b1cfc2011-10-06 12:44:16 +00001273 if (LocaleCompare("scene",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001274 {
anthonyafbaed72011-10-26 12:05:04 +00001275 char
anthonydcf510d2011-10-30 13:51:40 +00001276 *value = IfSetOption ? arg : "0";
anthonyafbaed72011-10-26 12:05:04 +00001277
1278 (void) SetImageOption(image_info,option,value);
1279 image_info->scene=StringToUnsignedLong(value);
anthony805a2d42011-09-25 08:25:12 +00001280 break;
1281 }
anthony74b1cfc2011-10-06 12:44:16 +00001282 if (LocaleCompare("seed",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001283 {
anthonyafbaed72011-10-26 12:05:04 +00001284 SeedPseudoRandomGenerator(
anthonydcf510d2011-10-30 13:51:40 +00001285 IfSetOption ? (size_t) StringToUnsignedLong(arg)
anthonyafbaed72011-10-26 12:05:04 +00001286 : (size_t) time((time_t *) NULL) );
anthony805a2d42011-09-25 08:25:12 +00001287 break;
1288 }
anthony74b1cfc2011-10-06 12:44:16 +00001289 if (LocaleCompare("size",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001290 {
anthonyafbaed72011-10-26 12:05:04 +00001291 /* FUTURE: string in image_info -- convert to Option ???
1292 Look at the special handling for "size" in SetImageOption()
anthony74b1cfc2011-10-06 12:44:16 +00001293 */
anthonyafbaed72011-10-26 12:05:04 +00001294 (void) CloneString(&image_info->size,
anthonydcf510d2011-10-30 13:51:40 +00001295 IfSetOption ? arg : (char *) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001296 break;
1297 }
1298 if (LocaleCompare("stretch",option) == 0)
1299 {
1300 draw_info->stretch=UndefinedStretch;
1301 if (IfSetOption)
1302 draw_info->stretch=(StretchType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00001303 MagickStretchOptions,MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +00001304 break;
1305 }
anthony74b1cfc2011-10-06 12:44:16 +00001306 if (LocaleCompare("stroke",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001307 {
anthonyafbaed72011-10-26 12:05:04 +00001308 /* set stroke color OR stroke-pattern
1309 color is only used by draw_info
1310 but draw_info is only initialsed using the color not the pattern
1311 */
1312 const char
anthonydcf510d2011-10-30 13:51:40 +00001313 *value = IfSetOption ? arg : "none";
anthonyafbaed72011-10-26 12:05:04 +00001314
1315 ExceptionInfo
1316 *sans;
1317
1318 (void) SetImageOption(image_info,option,value);
1319
1320 sans=AcquireExceptionInfo();
1321 status=QueryColorCompliance(value,AllCompliance,&draw_info->stroke,
1322 sans);
1323 sans=DestroyExceptionInfo(sans);
1324
1325 if (draw_info->stroke_pattern != (Image *) NULL)
1326 draw_info->stroke_pattern=DestroyImage(draw_info->stroke_pattern);
1327 if (status == MagickFalse)
1328 draw_info->stroke_pattern=GetImageCache(image_info,value,
1329 exception);
anthony805a2d42011-09-25 08:25:12 +00001330 break;
1331 }
anthony74b1cfc2011-10-06 12:44:16 +00001332 if (LocaleCompare("strokewidth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001333 {
anthonyafbaed72011-10-26 12:05:04 +00001334 const char
anthonydcf510d2011-10-30 13:51:40 +00001335 *value = IfSetOption ? arg : "1.0";
anthonyafbaed72011-10-26 12:05:04 +00001336 (void) SetImageOption(image_info,option,value);
1337 draw_info->stroke_width=InterpretLocaleValue(value,(char **) NULL);
1338 break;
1339 }
1340 if (LocaleCompare("style",option) == 0)
1341 {
1342 draw_info->style=UndefinedStyle;
1343 if (IfSetOption)
1344 draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
anthonydcf510d2011-10-30 13:51:40 +00001345 MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +00001346 break;
1347 }
anthony74b1cfc2011-10-06 12:44:16 +00001348 if (LocaleCompare("synchronize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001349 {
anthonyafbaed72011-10-26 12:05:04 +00001350 image_info->synchronize=IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +00001351 break;
1352 }
1353 break;
1354 }
1355 case 't':
1356 {
anthony74b1cfc2011-10-06 12:44:16 +00001357 if (LocaleCompare("taint",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001358 {
anthonyafbaed72011-10-26 12:05:04 +00001359 (void) SetImageOption(image_info,option,
1360 IfSetOption ? "true" : "false");
anthony805a2d42011-09-25 08:25:12 +00001361 break;
1362 }
anthony74b1cfc2011-10-06 12:44:16 +00001363 if (LocaleCompare("texture",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001364 {
anthonyafbaed72011-10-26 12:05:04 +00001365 /* FUTURE: move image_info string to option splay-tree */
1366 (void) CloneString(&image_info->texture,
anthonydcf510d2011-10-30 13:51:40 +00001367 IfSetOption ? arg : (char *) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001368 break;
1369 }
1370 if (LocaleCompare("tile",option) == 0)
1371 {
1372 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
1373 if (IfSetOption)
anthonydcf510d2011-10-30 13:51:40 +00001374 draw_info->fill_pattern=GetImageCache(image_info,arg,exception);
anthony805a2d42011-09-25 08:25:12 +00001375 break;
1376 }
anthony74b1cfc2011-10-06 12:44:16 +00001377 if (LocaleCompare("tile-offset",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001378 {
anthonyafbaed72011-10-26 12:05:04 +00001379 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +00001380 IfSetOption ? arg : "0");
anthony805a2d42011-09-25 08:25:12 +00001381 break;
1382 }
anthony74b1cfc2011-10-06 12:44:16 +00001383 if (LocaleCompare("transparent-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001384 {
anthonyafbaed72011-10-26 12:05:04 +00001385 /* FUTURE: both image_info attribute & ImageOption in use!
1386 image_info only used for generating new images.
1387 Note that +transparent-color, means fall-back to image
1388 attribute so ImageOption is deleted, not set to a default.
1389 */
1390 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001391 {
anthonydcf510d2011-10-30 13:51:40 +00001392 (void) SetImageOption(image_info,option,arg);
1393 (void) QueryColorCompliance(arg,AllCompliance,
anthonyafbaed72011-10-26 12:05:04 +00001394 image_info->transparent_color,exception);
anthony805a2d42011-09-25 08:25:12 +00001395 break;
1396 }
anthonyafbaed72011-10-26 12:05:04 +00001397 (void) DeleteImageOption(image_info,option);
1398 (void) QueryColorCompliance("none",AllCompliance,
1399 image_info->transparent_color,exception);
anthony805a2d42011-09-25 08:25:12 +00001400 break;
1401 }
anthony74b1cfc2011-10-06 12:44:16 +00001402 if (LocaleCompare("type",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001403 {
anthonyab3a50c2011-10-27 11:48:57 +00001404 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +00001405 IfSetOption ? arg : (char) NULL);
anthonyab3a50c2011-10-27 11:48:57 +00001406 image_info->type=UndefinedType;
1407 if (IfSetOption)
1408 image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
anthonydcf510d2011-10-30 13:51:40 +00001409 MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +00001410 break;
1411 }
1412 break;
1413 }
1414 case 'u':
1415 {
anthony74b1cfc2011-10-06 12:44:16 +00001416 if (LocaleCompare("undercolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001417 {
anthonyab3a50c2011-10-27 11:48:57 +00001418 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +00001419 IfSetOption ? arg : (char) NULL);
1420 (void) QueryColorCompliance(arg,AllCompliance,
anthonyab3a50c2011-10-27 11:48:57 +00001421 draw_info->undercolor,exception);
anthony805a2d42011-09-25 08:25:12 +00001422 break;
1423 }
anthony74b1cfc2011-10-06 12:44:16 +00001424 if (LocaleCompare("units",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001425 {
anthonyab3a50c2011-10-27 11:48:57 +00001426 /* Set in images via SyncImageSettings() */
1427 /* Should this effect draw_info X and Y resolution? */
1428 /* FUTURE: this probably should be part of the density setting */
1429 (void) SetImageOption(image_info,option,
anthonydcf510d2011-10-30 13:51:40 +00001430 IfSetOption ? arg : (char) NULL);
anthonyab3a50c2011-10-27 11:48:57 +00001431 image_info->units=UndefinedResolution;
1432 if (IfSetOption)
1433 image_info->units=(ResolutionType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00001434 MagickResolutionOptions,MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +00001435 break;
1436 }
1437 break;
1438 }
1439 case 'v':
1440 {
anthony74b1cfc2011-10-06 12:44:16 +00001441 if (LocaleCompare("verbose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001442 {
anthonyab3a50c2011-10-27 11:48:57 +00001443 /* FUTURE: Also an image artifact, set in Simple Operators.
1444 But artifact is only used in verbose output.
1445 */
1446 image_info->verbose= IfSetOption ? MagickTrue : MagickFalse;
1447 image_info->ping=MagickFalse; /* verbose can't be a ping */
anthony805a2d42011-09-25 08:25:12 +00001448 break;
1449 }
anthony74b1cfc2011-10-06 12:44:16 +00001450 if (LocaleCompare("view",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001451 {
anthonyab3a50c2011-10-27 11:48:57 +00001452 /* FUTURE: Convert from image_info to Option
1453 Only used by coder FPX
1454 */
1455 (void) CloneString(&image_info->view,
anthonydcf510d2011-10-30 13:51:40 +00001456 IfSetOption ? arg : (char) NULL);
anthony805a2d42011-09-25 08:25:12 +00001457 break;
1458 }
anthony74b1cfc2011-10-06 12:44:16 +00001459 if (LocaleCompare("virtual-pixel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001460 {
anthonyab3a50c2011-10-27 11:48:57 +00001461 /* Also used as a 'image' option deep in image structure */
1462 const char
anthonydcf510d2011-10-30 13:51:40 +00001463 *value = IfSetOption ? arg : "undefined";
anthonyab3a50c2011-10-27 11:48:57 +00001464
1465 (void) SetImageOption(image_info,option,value);
anthony805a2d42011-09-25 08:25:12 +00001466 image_info->virtual_pixel_method=(VirtualPixelMethod)
anthonyab3a50c2011-10-27 11:48:57 +00001467 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,value);
anthony805a2d42011-09-25 08:25:12 +00001468 break;
1469 }
1470 break;
1471 }
1472 case 'w':
1473 {
anthonydcf510d2011-10-30 13:51:40 +00001474 if (LocaleCompare("weight",option) == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001475 {
1476 /* FUTURE: relative weights not sensical due to first assignment!
1477 Also just what is actually using font 'weight' ???
anthonydcf510d2011-10-30 13:51:40 +00001478 There is no "-list weight" output (reference manual says there is)
anthonyab3a50c2011-10-27 11:48:57 +00001479 */
anthonydcf510d2011-10-30 13:51:40 +00001480 draw_info->weight=StringToUnsignedLong(arg);
1481 if (LocaleCompare(arg,"all") == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001482 draw_info->weight=0;
anthonydcf510d2011-10-30 13:51:40 +00001483 if (LocaleCompare(arg,"bold") == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001484 draw_info->weight=700;
anthonydcf510d2011-10-30 13:51:40 +00001485 if (LocaleCompare(arg,"bolder") == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001486 if (draw_info->weight <= 800)
1487 draw_info->weight+=100;
anthonydcf510d2011-10-30 13:51:40 +00001488 if (LocaleCompare(arg,"lighter") == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001489 if (draw_info->weight >= 100)
1490 draw_info->weight-=100;
anthonydcf510d2011-10-30 13:51:40 +00001491 if (LocaleCompare(arg,"normal") == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001492 draw_info->weight=400;
1493 break;
1494 }
anthony74b1cfc2011-10-06 12:44:16 +00001495 if (LocaleCompare("white-point",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001496 {
anthonydcf510d2011-10-30 13:51:40 +00001497 /* Used as a image chromaticity setting */
1498 (void) SetImageOption(image_info,option,
1499 IfSetOption ? arg : "0.0" );
anthony805a2d42011-09-25 08:25:12 +00001500 break;
1501 }
1502 break;
1503 }
1504 default:
1505 break;
1506 }
1507 return(MagickTrue);
1508}
1509
1510/*
1511%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1512% %
1513% %
1514% %
anthony74b1cfc2011-10-06 12:44:16 +00001515+ A p p l y I m a g e O p e r a t o r %
anthony805a2d42011-09-25 08:25:12 +00001516% %
1517% %
1518% %
1519%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1520%
anthonydcf510d2011-10-30 13:51:40 +00001521% ApplyImageOperator() apply one simple image operation to the current
1522% image pointed to by the CLI wand, with the settings that are saved in the
1523% CLI wand.
anthony805a2d42011-09-25 08:25:12 +00001524%
1525% The image in the list may be modified in three different ways...
1526%
1527% * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1528% * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1529% * replace by a list of images (-separate and -crop only!)
1530%
anthonydcf510d2011-10-30 13:51:40 +00001531% In each case the result replaces the original image in the list, as well as
1532% the pointer to the modified image (last image added if replaced by a list
1533% of images) is returned. As the image pointed to may be replaced, the first
1534% image in the list may also change. GetFirstImageInList() should be used by
1535% caller if they wish return the Image pointer to the first image in list.
1536%
1537% It is assumed that any per-image settings are up-to-date with respect to
1538% extra settings that have been saved in the wand.
anthony805a2d42011-09-25 08:25:12 +00001539%
anthony74b1cfc2011-10-06 12:44:16 +00001540% The format of the ApplyImageOperator method is:
anthony805a2d42011-09-25 08:25:12 +00001541%
anthony74b1cfc2011-10-06 12:44:16 +00001542% MagickBooleanType ApplyImageOperator(MagickWand *wand,
anthonydcf510d2011-10-30 13:51:40 +00001543% const char *option, const MagickBooleanType set_option, const char
1544% **args, ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +00001545%
1546% A description of each parameter follows:
1547%
anthonydcf510d2011-10-30 13:51:40 +00001548% o wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +00001549%
anthonydcf510d2011-10-30 13:51:40 +00001550% o option: The option string to be set
anthony805a2d42011-09-25 08:25:12 +00001551%
anthonydcf510d2011-10-30 13:51:40 +00001552% o set_option: is the option being set, or reset to some default
1553%
1554% o arg: the single argument (if needed) to set this option.
anthony805a2d42011-09-25 08:25:12 +00001555%
anthony805a2d42011-09-25 08:25:12 +00001556% o exception: return any errors or warnings in this structure.
1557%
anthonydcf510d2011-10-30 13:51:40 +00001558%
1559% Example usage (FUTURE)
1560%
1561% argc,argv
1562% i=index in argv
1563%
1564% count=ParseCommandOption(MagickCommandOptions,MagickFalse,argv[i]);
1565% flags=GetCommandOptionFlags(MagickCommandOptions,MagickFalse,argv[i]);
1566% if ( flags == MagickCommandOptions )
1567% ApplySettingsOption(wand, argv[i]+1,
1568% (*argv[i])=='-' ? MagickTrue : MagickFalse,
1569% argv+i+1, exception);
1570% i += count+1;
1571%
anthony805a2d42011-09-25 08:25:12 +00001572*/
anthonydcf510d2011-10-30 13:51:40 +00001573WandExport MagickBooleanType ApplySettingsOption(MagickWand *wand,
1574 const char *option, const MagickBooleanType set_option, const char **args,
1575 ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +00001576{
1577 Image *
1578 new_image;
1579
anthony805a2d42011-09-25 08:25:12 +00001580 GeometryInfo
1581 geometry_info;
1582
1583 RectangleInfo
1584 geometry;
1585
1586 MagickStatusType
1587 status;
1588
anthony805a2d42011-09-25 08:25:12 +00001589 MagickStatusType
1590 flags;
1591
anthony805a2d42011-09-25 08:25:12 +00001592 assert(image_info != (const ImageInfo *) NULL);
1593 assert(image_info->signature == MagickSignature);
anthonydcf510d2011-10-30 13:51:40 +00001594 assert(wand->draw_info != (DrawInfo *) NULL); /* ensure it is a CLI wand */
1595 assert(image != (Image **) NULL); /* there is an image */
anthony805a2d42011-09-25 08:25:12 +00001596 assert((*image)->signature == MagickSignature);
anthonydcf510d2011-10-30 13:51:40 +00001597
1598 if (wand->debug != MagickFalse)
1599 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1600
anthony805a2d42011-09-25 08:25:12 +00001601 SetGeometryInfo(&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001602
anthonydcf510d2011-10-30 13:51:40 +00001603 new_image = (Image *)NULL; /* the replacement image, if not null at end */
anthony805a2d42011-09-25 08:25:12 +00001604
anthonydcf510d2011-10-30 13:51:40 +00001605 /* We need somthing more optimized than this! */
1606 (void) SyncImageSettings(image_info,*image,exception);
1607
1608 switch (*option)
anthony805a2d42011-09-25 08:25:12 +00001609 {
1610 case 'a':
1611 {
anthonydcf510d2011-10-30 13:51:40 +00001612 if (LocaleCompare("adaptive-blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001613 {
anthonydcf510d2011-10-30 13:51:40 +00001614 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001615 if ((flags & SigmaValue) == 0)
1616 geometry_info.sigma=1.0;
1617 if ((flags & XiValue) == 0)
1618 geometry_info.xi=0.0;
1619 new_image=AdaptiveBlurImage(*image,geometry_info.rho,
1620 geometry_info.sigma,geometry_info.xi,exception);
1621 break;
1622 }
anthonydcf510d2011-10-30 13:51:40 +00001623 if (LocaleCompare("adaptive-resize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001624 {
anthony1afdc7a2011-10-05 11:54:28 +00001625 /* FUTURE: this is really a "interpolate-resize" operator
1626 "adaptive-resize" uses a fixed "Mesh" interpolation
anthony805a2d42011-09-25 08:25:12 +00001627 */
anthonydcf510d2011-10-30 13:51:40 +00001628 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00001629 new_image=AdaptiveResizeImage(*image,geometry.width,
anthonya89dd172011-10-04 13:29:35 +00001630 geometry.height,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00001631 break;
1632 }
anthonydcf510d2011-10-30 13:51:40 +00001633 if (LocaleCompare("adaptive-sharpen",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001634 {
1635 /*
1636 Adaptive sharpen image.
1637 */
cristy6fccee12011-10-20 18:43:18 +00001638 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001639 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001640 if ((flags & SigmaValue) == 0)
1641 geometry_info.sigma=1.0;
1642 if ((flags & XiValue) == 0)
1643 geometry_info.xi=0.0;
1644 new_image=AdaptiveSharpenImage(*image,geometry_info.rho,
1645 geometry_info.sigma,geometry_info.xi,exception);
1646 break;
1647 }
anthonydcf510d2011-10-30 13:51:40 +00001648 if (LocaleCompare("alpha",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001649 {
1650 AlphaChannelType
1651 alpha_type;
1652
cristy6fccee12011-10-20 18:43:18 +00001653 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001654 alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
anthonydcf510d2011-10-30 13:51:40 +00001655 MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00001656 (void) SetImageAlphaChannel(*image,alpha_type,exception);
1657 break;
1658 }
anthonydcf510d2011-10-30 13:51:40 +00001659 if (LocaleCompare("annotate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001660 {
1661 char
1662 *text,
1663 geometry[MaxTextExtent];
1664
cristy6fccee12011-10-20 18:43:18 +00001665 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001666 SetGeometryInfo(&geometry_info);
anthonydcf510d2011-10-30 13:51:40 +00001667 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001668 if ((flags & SigmaValue) == 0)
1669 geometry_info.sigma=geometry_info.rho;
1670 text=InterpretImageProperties(image_info,*image,argv[2],
1671 exception);
1672 if (text == (char *) NULL)
1673 break;
1674 (void) CloneString(&draw_info->text,text);
1675 text=DestroyString(text);
1676 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1677 geometry_info.xi,geometry_info.psi);
1678 (void) CloneString(&draw_info->geometry,geometry);
1679 draw_info->affine.sx=cos(DegreesToRadians(
1680 fmod(geometry_info.rho,360.0)));
1681 draw_info->affine.rx=sin(DegreesToRadians(
1682 fmod(geometry_info.rho,360.0)));
1683 draw_info->affine.ry=(-sin(DegreesToRadians(
1684 fmod(geometry_info.sigma,360.0))));
1685 draw_info->affine.sy=cos(DegreesToRadians(
1686 fmod(geometry_info.sigma,360.0)));
1687 (void) AnnotateImage(*image,draw_info,exception);
1688 break;
1689 }
anthonydcf510d2011-10-30 13:51:40 +00001690 if (LocaleCompare("auto-gamma",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001691 {
1692 /*
1693 Auto Adjust Gamma of image based on its mean
1694 */
cristy6fccee12011-10-20 18:43:18 +00001695 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001696 (void) AutoGammaImage(*image,exception);
1697 break;
1698 }
anthonydcf510d2011-10-30 13:51:40 +00001699 if (LocaleCompare("auto-level",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001700 {
1701 /*
1702 Perfectly Normalize (max/min stretch) the image
1703 */
cristy6fccee12011-10-20 18:43:18 +00001704 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001705 (void) AutoLevelImage(*image,exception);
1706 break;
1707 }
anthonydcf510d2011-10-30 13:51:40 +00001708 if (LocaleCompare("auto-orient",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001709 {
cristy6fccee12011-10-20 18:43:18 +00001710 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001711 switch ((*image)->orientation)
1712 {
1713 case TopRightOrientation:
1714 {
1715 new_image=FlopImage(*image,exception);
1716 break;
1717 }
1718 case BottomRightOrientation:
1719 {
1720 new_image=RotateImage(*image,180.0,exception);
1721 break;
1722 }
1723 case BottomLeftOrientation:
1724 {
1725 new_image=FlipImage(*image,exception);
1726 break;
1727 }
1728 case LeftTopOrientation:
1729 {
1730 new_image=TransposeImage(*image,exception);
1731 break;
1732 }
1733 case RightTopOrientation:
1734 {
1735 new_image=RotateImage(*image,90.0,exception);
1736 break;
1737 }
1738 case RightBottomOrientation:
1739 {
1740 new_image=TransverseImage(*image,exception);
1741 break;
1742 }
1743 case LeftBottomOrientation:
1744 {
1745 new_image=RotateImage(*image,270.0,exception);
1746 break;
1747 }
1748 default:
1749 break;
1750 }
1751 if (new_image != (Image *) NULL)
1752 new_image->orientation=TopLeftOrientation;
1753 break;
1754 }
1755 break;
1756 }
1757 case 'b':
1758 {
anthonydcf510d2011-10-30 13:51:40 +00001759 if (LocaleCompare("black-threshold",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001760 {
cristy6fccee12011-10-20 18:43:18 +00001761 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001762 (void) BlackThresholdImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00001763 break;
1764 }
anthonydcf510d2011-10-30 13:51:40 +00001765 if (LocaleCompare("blue-shift",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001766 {
cristy6fccee12011-10-20 18:43:18 +00001767 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001768 geometry_info.rho=1.5;
1769 if (*argv[0] == '-')
anthonydcf510d2011-10-30 13:51:40 +00001770 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001771 new_image=BlueShiftImage(*image,geometry_info.rho,exception);
1772 break;
1773 }
anthonydcf510d2011-10-30 13:51:40 +00001774 if (LocaleCompare("blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001775 {
anthony74b1cfc2011-10-06 12:44:16 +00001776 /* FUTURE: use of "bias" in a blur is non-sensible */
cristy6fccee12011-10-20 18:43:18 +00001777 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001778 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001779 if ((flags & SigmaValue) == 0)
1780 geometry_info.sigma=1.0;
1781 if ((flags & XiValue) == 0)
1782 geometry_info.xi=0.0;
1783 new_image=BlurImage(*image,geometry_info.rho,
1784 geometry_info.sigma,geometry_info.xi,exception);
1785 break;
1786 }
anthonydcf510d2011-10-30 13:51:40 +00001787 if (LocaleCompare("border",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001788 {
anthony5f867ae2011-10-09 10:28:34 +00001789 ComposeOperator
1790 compose;
1791
1792 const char*
1793 const char*
1794 value;
1795
1796 value=GetImageOption(image_info,"compose");
1797 if (value != (const char *) NULL)
1798 compose=(CompositeOperator) ParseCommandOption(
1799 MagickComposeOptions,MagickFalse,value);
1800 else
1801 compose=OverCompositeOp; /* use Over not image->compose */
1802
cristy6fccee12011-10-20 18:43:18 +00001803 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001804 flags=ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00001805 if ((flags & SigmaValue) == 0)
1806 geometry.height=geometry.width;
anthonya89dd172011-10-04 13:29:35 +00001807 new_image=BorderImage(*image,&geometry,compose,exception);
anthony805a2d42011-09-25 08:25:12 +00001808 break;
1809 }
anthonydcf510d2011-10-30 13:51:40 +00001810 if (LocaleCompare("brightness-contrast",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001811 {
1812 double
1813 brightness,
1814 contrast;
1815
1816 GeometryInfo
1817 geometry_info;
1818
1819 MagickStatusType
1820 flags;
1821
cristy6fccee12011-10-20 18:43:18 +00001822 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001823 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001824 brightness=geometry_info.rho;
1825 contrast=0.0;
1826 if ((flags & SigmaValue) != 0)
1827 contrast=geometry_info.sigma;
1828 (void) BrightnessContrastImage(*image,brightness,contrast,
1829 exception);
anthony805a2d42011-09-25 08:25:12 +00001830 break;
1831 }
1832 break;
1833 }
1834 case 'c':
1835 {
anthonydcf510d2011-10-30 13:51:40 +00001836 if (LocaleCompare("cdl",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001837 {
1838 char
1839 *color_correction_collection;
1840
1841 /*
1842 Color correct with a color decision list.
1843 */
cristy6fccee12011-10-20 18:43:18 +00001844 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001845 color_correction_collection=FileToString(args[0],~0,exception);
anthony805a2d42011-09-25 08:25:12 +00001846 if (color_correction_collection == (char *) NULL)
1847 break;
1848 (void) ColorDecisionListImage(*image,color_correction_collection,
1849 exception);
anthony805a2d42011-09-25 08:25:12 +00001850 break;
1851 }
anthonydcf510d2011-10-30 13:51:40 +00001852 if (LocaleCompare("channel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001853 {
anthony74b1cfc2011-10-06 12:44:16 +00001854 /* The "channel" setting has already been set */
1855 SetPixelChannelMap(*image,image_info->channel);
anthony805a2d42011-09-25 08:25:12 +00001856 break;
1857 }
anthonydcf510d2011-10-30 13:51:40 +00001858 if (LocaleCompare("charcoal",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001859 {
cristy6fccee12011-10-20 18:43:18 +00001860 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001861 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001862 if ((flags & SigmaValue) == 0)
1863 geometry_info.sigma=1.0;
1864 if ((flags & XiValue) == 0)
1865 geometry_info.xi=1.0;
1866 new_image=CharcoalImage(*image,geometry_info.rho,
1867 geometry_info.sigma,geometry_info.xi,exception);
1868 break;
1869 }
anthonydcf510d2011-10-30 13:51:40 +00001870 if (LocaleCompare("chop",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001871 {
cristy6fccee12011-10-20 18:43:18 +00001872 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001873 (void) ParseGravityGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00001874 new_image=ChopImage(*image,&geometry,exception);
1875 break;
1876 }
anthonydcf510d2011-10-30 13:51:40 +00001877 if (LocaleCompare("clamp",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001878 {
cristy6fccee12011-10-20 18:43:18 +00001879 (void) SyncImageSettings(image_info,*image,exception);
cristy092d71c2011-10-14 18:01:29 +00001880 (void) ClampImage(*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001881 break;
1882 }
anthonydcf510d2011-10-30 13:51:40 +00001883 if (LocaleCompare("clip",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001884 {
cristy6fccee12011-10-20 18:43:18 +00001885 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001886 if (*argv[0] == '+')
1887 {
1888 (void) SetImageClipMask(*image,(Image *) NULL,exception);
1889 break;
1890 }
1891 (void) ClipImage(*image,exception);
1892 break;
1893 }
anthonydcf510d2011-10-30 13:51:40 +00001894 if (LocaleCompare("clip-mask",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001895 {
1896 CacheView
1897 *mask_view;
1898
1899 Image
1900 *mask_image;
1901
1902 register Quantum
1903 *restrict q;
1904
1905 register ssize_t
1906 x;
1907
1908 ssize_t
1909 y;
1910
cristy6fccee12011-10-20 18:43:18 +00001911 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001912 if (*argv[0] == '+')
1913 {
anthony74b1cfc2011-10-06 12:44:16 +00001914 /* Remove the write mask */
anthony805a2d42011-09-25 08:25:12 +00001915 (void) SetImageMask(*image,(Image *) NULL,exception);
1916 break;
1917 }
anthonydcf510d2011-10-30 13:51:40 +00001918 mask_image=GetImageCache(image_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00001919 if (mask_image == (Image *) NULL)
1920 break;
1921 if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
1922 return(MagickFalse);
anthony74b1cfc2011-10-06 12:44:16 +00001923 /* create a write mask from clip-mask image */
1924 /* FUTURE: use Alpha operations instead */
anthony805a2d42011-09-25 08:25:12 +00001925 mask_view=AcquireCacheView(mask_image);
1926 for (y=0; y < (ssize_t) mask_image->rows; y++)
1927 {
1928 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
1929 exception);
1930 if (q == (Quantum *) NULL)
1931 break;
1932 for (x=0; x < (ssize_t) mask_image->columns; x++)
1933 {
1934 if (mask_image->matte == MagickFalse)
1935 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1936 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1937 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1938 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1939 q+=GetPixelChannels(mask_image);
1940 }
1941 if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
1942 break;
1943 }
anthony74b1cfc2011-10-06 12:44:16 +00001944 /* set the write mask */
anthony805a2d42011-09-25 08:25:12 +00001945 mask_view=DestroyCacheView(mask_view);
1946 mask_image->matte=MagickTrue;
anthonya89dd172011-10-04 13:29:35 +00001947 (void) SetImageClipMask(*image,mask_image,exception);
anthony805a2d42011-09-25 08:25:12 +00001948 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00001949 break;
1950 }
anthonydcf510d2011-10-30 13:51:40 +00001951 if (LocaleCompare("clip-path",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001952 {
cristy6fccee12011-10-20 18:43:18 +00001953 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001954 (void) ClipImagePath(*image,args[0],*argv[0] == '-' ? MagickTrue :
anthony805a2d42011-09-25 08:25:12 +00001955 MagickFalse,exception);
1956 break;
1957 }
anthonydcf510d2011-10-30 13:51:40 +00001958 if (LocaleCompare("colorize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001959 {
cristy6fccee12011-10-20 18:43:18 +00001960 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001961 new_image=ColorizeImage(*image,args[0],draw_info->fill,
anthony805a2d42011-09-25 08:25:12 +00001962 exception);
1963 break;
1964 }
anthonydcf510d2011-10-30 13:51:40 +00001965 if (LocaleCompare("color-matrix",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001966 {
1967 KernelInfo
1968 *kernel;
1969
cristy6fccee12011-10-20 18:43:18 +00001970 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001971 kernel=AcquireKernelInfo(args[0]);
anthony805a2d42011-09-25 08:25:12 +00001972 if (kernel == (KernelInfo *) NULL)
1973 break;
1974 new_image=ColorMatrixImage(*image,kernel,exception);
1975 kernel=DestroyKernelInfo(kernel);
1976 break;
1977 }
anthonydcf510d2011-10-30 13:51:40 +00001978 if (LocaleCompare("colors",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001979 {
anthony74b1cfc2011-10-06 12:44:16 +00001980 /* Reduce the number of colors in the image. */
cristy6fccee12011-10-20 18:43:18 +00001981 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00001982 quantize_info->number_colors=StringToUnsignedLong(args[0]);
anthony805a2d42011-09-25 08:25:12 +00001983 if (quantize_info->number_colors == 0)
1984 break;
1985 if (((*image)->storage_class == DirectClass) ||
1986 (*image)->colors > quantize_info->number_colors)
1987 (void) QuantizeImage(quantize_info,*image,exception);
1988 else
1989 (void) CompressImageColormap(*image,exception);
1990 break;
1991 }
anthonydcf510d2011-10-30 13:51:40 +00001992 if (LocaleCompare("colorspace",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001993 {
anthonyd2cdc862011-10-07 14:07:17 +00001994 /* This is a Image Setting, which should already been set */
1995 /* FUTURE: default colorspace should be sRGB!
1996 Unless some type of 'linear colorspace' mode is set.
1997 Note that +colorspace sets "undefined" or no effect on
1998 new images, but forces images already in memory back to RGB!
1999 */
cristy6fccee12011-10-20 18:43:18 +00002000 (void) SyncImageSettings(image_info,*image,exception);
anthonyd2cdc862011-10-07 14:07:17 +00002001 (void) TransformImageColorspace(*image,
anthony6613bf32011-10-15 07:24:44 +00002002 IfSetOption ? image_info->colorspace : RGBColorspace,
2003 exception);
anthony805a2d42011-09-25 08:25:12 +00002004 break;
2005 }
anthonydcf510d2011-10-30 13:51:40 +00002006 if (LocaleCompare("contrast",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002007 {
cristy6fccee12011-10-20 18:43:18 +00002008 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002009 (void) ContrastImage(*image,(*argv[0] == '-') ? MagickTrue :
2010 MagickFalse,exception);
2011 break;
2012 }
anthonydcf510d2011-10-30 13:51:40 +00002013 if (LocaleCompare("contrast-stretch",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002014 {
2015 double
2016 black_point,
2017 white_point;
2018
2019 MagickStatusType
2020 flags;
2021
2022 /*
2023 Contrast stretch image.
2024 */
cristy6fccee12011-10-20 18:43:18 +00002025 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002026 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002027 black_point=geometry_info.rho;
2028 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2029 black_point;
2030 if ((flags & PercentValue) != 0)
2031 {
2032 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2033 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2034 }
2035 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2036 white_point;
2037 (void) ContrastStretchImage(*image,black_point,white_point,
2038 exception);
anthony805a2d42011-09-25 08:25:12 +00002039 break;
2040 }
anthonydcf510d2011-10-30 13:51:40 +00002041 if (LocaleCompare("convolve",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002042 {
2043 KernelInfo
2044 *kernel_info;
2045
cristy6fccee12011-10-20 18:43:18 +00002046 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002047 kernel_info=AcquireKernelInfo(args[0]);
anthony805a2d42011-09-25 08:25:12 +00002048 if (kernel_info == (KernelInfo *) NULL)
2049 break;
2050 kernel_info->bias=(*image)->bias;
2051 new_image=ConvolveImage(*image,kernel_info,exception);
2052 kernel_info=DestroyKernelInfo(kernel_info);
2053 break;
2054 }
anthonydcf510d2011-10-30 13:51:40 +00002055 if (LocaleCompare("crop",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002056 {
2057 /*
2058 Crop a image to a smaller size
2059 */
cristy6fccee12011-10-20 18:43:18 +00002060 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002061 new_image=CropImageToTiles(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00002062 break;
2063 }
anthonydcf510d2011-10-30 13:51:40 +00002064 if (LocaleCompare("cycle",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002065 {
2066 /*
2067 Cycle an image colormap.
2068 */
cristy6fccee12011-10-20 18:43:18 +00002069 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002070 (void) CycleColormapImage(*image,(ssize_t) StringToLong(args[0]),
anthony805a2d42011-09-25 08:25:12 +00002071 exception);
2072 break;
2073 }
2074 break;
2075 }
2076 case 'd':
2077 {
anthonydcf510d2011-10-30 13:51:40 +00002078 if (LocaleCompare("decipher",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002079 {
2080 StringInfo
2081 *passkey;
2082
2083 /*
2084 Decipher pixels.
2085 */
cristy6fccee12011-10-20 18:43:18 +00002086 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002087 passkey=FileToStringInfo(args[0],~0,exception);
anthony805a2d42011-09-25 08:25:12 +00002088 if (passkey != (StringInfo *) NULL)
2089 {
2090 (void) PasskeyDecipherImage(*image,passkey,exception);
2091 passkey=DestroyStringInfo(passkey);
2092 }
2093 break;
2094 }
anthonydcf510d2011-10-30 13:51:40 +00002095 if (LocaleCompare("depth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002096 {
anthonydcf510d2011-10-30 13:51:40 +00002097 /* The image_info->depth setting has already been set
2098 We just need to apply it to all images in current sequence
2099 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2100 That is it really is an operation, not a setting! Arrgghhh
2101 */
cristy6fccee12011-10-20 18:43:18 +00002102 (void) SyncImageSettings(image_info,*image,exception);
anthony5f867ae2011-10-09 10:28:34 +00002103 (void) SetImageDepth(*image,image_info->depth);
anthony805a2d42011-09-25 08:25:12 +00002104 break;
2105 }
anthonydcf510d2011-10-30 13:51:40 +00002106 if (LocaleCompare("deskew",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002107 {
2108 double
2109 threshold;
2110
2111 /*
2112 Straighten the image.
2113 */
cristy6fccee12011-10-20 18:43:18 +00002114 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002115 if (*argv[0] == '+')
2116 threshold=40.0*QuantumRange/100.0;
2117 else
anthonydcf510d2011-10-30 13:51:40 +00002118 threshold=SiPrefixToDouble(args[0],QuantumRange);
anthony805a2d42011-09-25 08:25:12 +00002119 new_image=DeskewImage(*image,threshold,exception);
2120 break;
2121 }
anthonydcf510d2011-10-30 13:51:40 +00002122 if (LocaleCompare("despeckle",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002123 {
2124 /*
2125 Reduce the speckles within an image.
2126 */
cristy6fccee12011-10-20 18:43:18 +00002127 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002128 new_image=DespeckleImage(*image,exception);
2129 break;
2130 }
anthonydcf510d2011-10-30 13:51:40 +00002131 if (LocaleCompare("display",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002132 {
anthonydcf510d2011-10-30 13:51:40 +00002133 (void) CloneString(&draw_info->server_name,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002134 break;
2135 }
anthonydcf510d2011-10-30 13:51:40 +00002136 if (LocaleCompare("distort",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002137 {
2138 char
2139 *args,
2140 token[MaxTextExtent];
2141
2142 const char
2143 *p;
2144
2145 DistortImageMethod
2146 method;
2147
2148 double
2149 *arguments;
2150
2151 register ssize_t
2152 x;
2153
2154 size_t
2155 number_arguments;
2156
2157 /*
2158 Distort image.
2159 */
cristy6fccee12011-10-20 18:43:18 +00002160 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002161 method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
anthonydcf510d2011-10-30 13:51:40 +00002162 MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002163 if ( method == ResizeDistortion )
2164 {
2165 /* Special Case - Argument is actually a resize geometry!
2166 ** Convert that to an appropriate distortion argument array.
2167 */
2168 double
2169 resize_args[2];
2170 (void) ParseRegionGeometry(*image,argv[2],&geometry,
2171 exception);
2172 resize_args[0]=(double)geometry.width;
2173 resize_args[1]=(double)geometry.height;
2174 new_image=DistortImage(*image,method,(size_t)2,
2175 resize_args,MagickTrue,exception);
2176 break;
2177 }
2178 args=InterpretImageProperties(image_info,*image,argv[2],
2179 exception);
2180 if (args == (char *) NULL)
2181 break;
2182 p=(char *) args;
2183 for (x=0; *p != '\0'; x++)
2184 {
2185 GetMagickToken(p,&p,token);
2186 if (*token == ',')
2187 GetMagickToken(p,&p,token);
2188 }
2189 number_arguments=(size_t) x;
2190 arguments=(double *) AcquireQuantumMemory(number_arguments,
2191 sizeof(*arguments));
2192 if (arguments == (double *) NULL)
2193 ThrowWandFatalException(ResourceLimitFatalError,
2194 "MemoryAllocationFailed",(*image)->filename);
2195 (void) ResetMagickMemory(arguments,0,number_arguments*
2196 sizeof(*arguments));
2197 p=(char *) args;
2198 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2199 {
2200 GetMagickToken(p,&p,token);
2201 if (*token == ',')
2202 GetMagickToken(p,&p,token);
2203 arguments[x]=InterpretLocaleValue(token,(char **) NULL);
2204 }
2205 args=DestroyString(args);
2206 new_image=DistortImage(*image,method,number_arguments,arguments,
2207 (*argv[0] == '+') ? MagickTrue : MagickFalse,exception);
2208 arguments=(double *) RelinquishMagickMemory(arguments);
2209 break;
2210 }
anthonydcf510d2011-10-30 13:51:40 +00002211 if (LocaleCompare("draw",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002212 {
cristy6fccee12011-10-20 18:43:18 +00002213 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002214 (void) CloneString(&draw_info->primitive,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002215 (void) DrawImage(*image,draw_info,exception);
2216 break;
2217 }
2218 break;
2219 }
2220 case 'e':
2221 {
anthonydcf510d2011-10-30 13:51:40 +00002222 if (LocaleCompare("edge",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002223 {
cristy6fccee12011-10-20 18:43:18 +00002224 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002225 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002226 if ((flags & SigmaValue) == 0)
2227 geometry_info.sigma=1.0;
2228 new_image=EdgeImage(*image,geometry_info.rho,
2229 geometry_info.sigma,exception);
2230 break;
2231 }
anthonydcf510d2011-10-30 13:51:40 +00002232 if (LocaleCompare("emboss",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002233 {
cristy6fccee12011-10-20 18:43:18 +00002234 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002235 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002236 if ((flags & SigmaValue) == 0)
2237 geometry_info.sigma=1.0;
2238 new_image=EmbossImage(*image,geometry_info.rho,
2239 geometry_info.sigma,exception);
2240 break;
2241 }
anthonydcf510d2011-10-30 13:51:40 +00002242 if (LocaleCompare("encipher",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002243 {
2244 StringInfo
2245 *passkey;
2246
cristy6fccee12011-10-20 18:43:18 +00002247 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002248 passkey=FileToStringInfo(args[0],~0,exception);
anthony805a2d42011-09-25 08:25:12 +00002249 if (passkey != (StringInfo *) NULL)
2250 {
2251 (void) PasskeyEncipherImage(*image,passkey,exception);
2252 passkey=DestroyStringInfo(passkey);
2253 }
2254 break;
2255 }
anthonydcf510d2011-10-30 13:51:40 +00002256 if (LocaleCompare("enhance",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002257 {
cristy6fccee12011-10-20 18:43:18 +00002258 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002259 new_image=EnhanceImage(*image,exception);
2260 break;
2261 }
anthonydcf510d2011-10-30 13:51:40 +00002262 if (LocaleCompare("equalize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002263 {
cristy6fccee12011-10-20 18:43:18 +00002264 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002265 (void) EqualizeImage(*image,exception);
2266 break;
2267 }
anthonydcf510d2011-10-30 13:51:40 +00002268 if (LocaleCompare("evaluate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002269 {
2270 double
2271 constant;
2272
2273 MagickEvaluateOperator
2274 op;
2275
cristy6fccee12011-10-20 18:43:18 +00002276 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002277 op=(MagickEvaluateOperator) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00002278 MagickEvaluateOptions,MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002279 constant=SiPrefixToDouble(argv[2],QuantumRange);
2280 (void) EvaluateImage(*image,op,constant,exception);
2281 break;
2282 }
anthonydcf510d2011-10-30 13:51:40 +00002283 if (LocaleCompare("extent",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002284 {
cristy6fccee12011-10-20 18:43:18 +00002285 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002286 flags=ParseGravityGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00002287 if (geometry.width == 0)
2288 geometry.width=(*image)->columns;
2289 if (geometry.height == 0)
2290 geometry.height=(*image)->rows;
2291 new_image=ExtentImage(*image,&geometry,exception);
2292 break;
2293 }
2294 break;
2295 }
2296 case 'f':
2297 {
anthonydcf510d2011-10-30 13:51:40 +00002298 if (LocaleCompare("features",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002299 {
anthonyafbaed72011-10-26 12:05:04 +00002300 /* FUTURE: Assign Artifact to all images -- per image setting */
anthony6dc09cd2011-10-12 08:56:49 +00002301 (void) SetImageArtifact(*image,"identify:features",
anthonydcf510d2011-10-30 13:51:40 +00002302 IfSetOption ? args[0] : (const char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002303 break;
2304 }
anthonydcf510d2011-10-30 13:51:40 +00002305 if (LocaleCompare("flip",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002306 {
cristy947cb4c2011-10-20 18:41:46 +00002307 /*
2308 Flip image scanlines.
2309 */
cristy6fccee12011-10-20 18:43:18 +00002310 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002311 new_image=FlipImage(*image,exception);
2312 break;
2313 }
anthonydcf510d2011-10-30 13:51:40 +00002314 if (LocaleCompare("flop",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002315 {
cristy947cb4c2011-10-20 18:41:46 +00002316 /*
2317 Flop image scanlines.
2318 */
cristy6fccee12011-10-20 18:43:18 +00002319 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002320 new_image=FlopImage(*image,exception);
2321 break;
2322 }
anthonydcf510d2011-10-30 13:51:40 +00002323 if (LocaleCompare("floodfill",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002324 {
2325 PixelInfo
2326 target;
2327
cristy947cb4c2011-10-20 18:41:46 +00002328 /*
2329 Floodfill image.
2330 */
cristy6fccee12011-10-20 18:43:18 +00002331 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002332 (void) ParsePageGeometry(*image,args[0],&geometry,exception);
cristy269c9412011-10-13 23:41:15 +00002333 (void) QueryColorCompliance(argv[2],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00002334 exception);
anthony805a2d42011-09-25 08:25:12 +00002335 (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
2336 geometry.y,*argv[0] == '-' ? MagickFalse : MagickTrue,exception);
2337 break;
2338 }
cristy947cb4c2011-10-20 18:41:46 +00002339 /* FUTURE: should be from ImageOption "format"
anthonydcf510d2011-10-30 13:51:40 +00002340 if (LocaleCompare("format",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002341 {
anthonydcf510d2011-10-30 13:51:40 +00002342 format=args[0];
cristy947cb4c2011-10-20 18:41:46 +00002343 break;
2344 }
2345 */
anthonydcf510d2011-10-30 13:51:40 +00002346 if (LocaleCompare("frame",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002347 {
2348 FrameInfo
2349 frame_info;
2350
cristy947cb4c2011-10-20 18:41:46 +00002351 /*
2352 Surround image with an ornamental border.
2353 */
cristy6fccee12011-10-20 18:43:18 +00002354 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002355 flags=ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00002356 frame_info.width=geometry.width;
2357 frame_info.height=geometry.height;
2358 if ((flags & HeightValue) == 0)
2359 frame_info.height=geometry.width;
2360 frame_info.outer_bevel=geometry.x;
2361 frame_info.inner_bevel=geometry.y;
2362 frame_info.x=(ssize_t) frame_info.width;
2363 frame_info.y=(ssize_t) frame_info.height;
2364 frame_info.width=(*image)->columns+2*frame_info.width;
2365 frame_info.height=(*image)->rows+2*frame_info.height;
anthony5f867ae2011-10-09 10:28:34 +00002366 new_image=FrameImage(*image,&frame_info,COMPOSE,exception);
anthony805a2d42011-09-25 08:25:12 +00002367 break;
2368 }
anthonydcf510d2011-10-30 13:51:40 +00002369 if (LocaleCompare("function",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002370 {
2371 char
2372 *arguments,
2373 token[MaxTextExtent];
2374
2375 const char
2376 *p;
2377
2378 double
2379 *parameters;
2380
2381 MagickFunction
2382 function;
2383
2384 register ssize_t
2385 x;
2386
2387 size_t
2388 number_parameters;
2389
cristy947cb4c2011-10-20 18:41:46 +00002390 /*
2391 Function Modify Image Values
2392 */
cristy6fccee12011-10-20 18:43:18 +00002393 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002394 function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
anthonydcf510d2011-10-30 13:51:40 +00002395 MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002396 arguments=InterpretImageProperties(image_info,*image,argv[2],
2397 exception);
2398 if (arguments == (char *) NULL)
2399 break;
2400 p=(char *) arguments;
2401 for (x=0; *p != '\0'; x++)
2402 {
2403 GetMagickToken(p,&p,token);
2404 if (*token == ',')
2405 GetMagickToken(p,&p,token);
2406 }
2407 number_parameters=(size_t) x;
2408 parameters=(double *) AcquireQuantumMemory(number_parameters,
2409 sizeof(*parameters));
2410 if (parameters == (double *) NULL)
2411 ThrowWandFatalException(ResourceLimitFatalError,
2412 "MemoryAllocationFailed",(*image)->filename);
2413 (void) ResetMagickMemory(parameters,0,number_parameters*
2414 sizeof(*parameters));
2415 p=(char *) arguments;
2416 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
2417 {
2418 GetMagickToken(p,&p,token);
2419 if (*token == ',')
2420 GetMagickToken(p,&p,token);
2421 parameters[x]=InterpretLocaleValue(token,(char **) NULL);
2422 }
2423 arguments=DestroyString(arguments);
2424 (void) FunctionImage(*image,function,number_parameters,parameters,
2425 exception);
2426 parameters=(double *) RelinquishMagickMemory(parameters);
2427 break;
2428 }
2429 break;
2430 }
2431 case 'g':
2432 {
anthonydcf510d2011-10-30 13:51:40 +00002433 if (LocaleCompare("gamma",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002434 {
cristy6fccee12011-10-20 18:43:18 +00002435 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002436 if (*argv[0] == '+')
anthonydcf510d2011-10-30 13:51:40 +00002437 (*image)->gamma=InterpretLocaleValue(args[0],(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002438 else
anthonydcf510d2011-10-30 13:51:40 +00002439 (void) GammaImage(*image,InterpretLocaleValue(args[0],
anthony805a2d42011-09-25 08:25:12 +00002440 (char **) NULL),exception);
2441 break;
2442 }
anthonydcf510d2011-10-30 13:51:40 +00002443 if ((LocaleCompare("gaussian-blur",option) == 0) ||
2444 (LocaleCompare("gaussian",option) == 0))
anthony805a2d42011-09-25 08:25:12 +00002445 {
cristy6fccee12011-10-20 18:43:18 +00002446 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002447 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002448 if ((flags & SigmaValue) == 0)
2449 geometry_info.sigma=1.0;
2450 if ((flags & XiValue) == 0)
2451 geometry_info.xi=0.0;
2452 new_image=GaussianBlurImage(*image,geometry_info.rho,
2453 geometry_info.sigma,geometry_info.xi,exception);
2454 break;
2455 }
anthonydcf510d2011-10-30 13:51:40 +00002456 if (LocaleCompare("geometry",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002457 {
2458 /*
anthony6613bf32011-10-15 07:24:44 +00002459 Record Image offset for composition,
2460 Resize last image. -- FUTURE depreciate this aspect
anthony805a2d42011-09-25 08:25:12 +00002461 */
cristy6fccee12011-10-20 18:43:18 +00002462 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002463 if (*argv[0] == '+')
2464 {
2465 if ((*image)->geometry != (char *) NULL)
2466 (*image)->geometry=DestroyString((*image)->geometry);
2467 break;
2468 }
anthonydcf510d2011-10-30 13:51:40 +00002469 flags=ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00002470 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
anthonydcf510d2011-10-30 13:51:40 +00002471 (void) CloneString(&(*image)->geometry,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002472 else
2473 new_image=ResizeImage(*image,geometry.width,geometry.height,
2474 (*image)->filter,(*image)->blur,exception);
2475 break;
2476 }
anthony805a2d42011-09-25 08:25:12 +00002477 break;
2478 }
2479 case 'h':
2480 {
anthonydcf510d2011-10-30 13:51:40 +00002481 if (LocaleCompare("highlight-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002482 {
anthonydcf510d2011-10-30 13:51:40 +00002483 (void) SetImageArtifact(*image,option,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002484 break;
2485 }
2486 break;
2487 }
2488 case 'i':
2489 {
anthonydcf510d2011-10-30 13:51:40 +00002490 if (LocaleCompare("identify",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002491 {
2492 char
2493 *text;
2494
cristy6fccee12011-10-20 18:43:18 +00002495 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002496 if (format == (char *) NULL)
2497 {
2498 (void) IdentifyImage(*image,stdout,image_info->verbose,
2499 exception);
2500 break;
2501 }
2502 text=InterpretImageProperties(image_info,*image,format,
2503 exception);
2504 if (text == (char *) NULL)
2505 break;
2506 (void) fputs(text,stdout);
2507 (void) fputc('\n',stdout);
2508 text=DestroyString(text);
2509 break;
2510 }
anthonydcf510d2011-10-30 13:51:40 +00002511 if (LocaleCompare("implode",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002512 {
cristy947cb4c2011-10-20 18:41:46 +00002513 /*
2514 Implode image.
2515 */
cristy6fccee12011-10-20 18:43:18 +00002516 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002517 (void) ParseGeometry(args[0],&geometry_info);
anthonya89dd172011-10-04 13:29:35 +00002518 new_image=ImplodeImage(*image,geometry_info.rho,
2519 interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00002520 break;
2521 }
anthonydcf510d2011-10-30 13:51:40 +00002522 if (LocaleCompare("interline-spacing",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002523 {
2524 if (*argv[0] == '+')
2525 (void) ParseGeometry("0",&geometry_info);
2526 else
anthonydcf510d2011-10-30 13:51:40 +00002527 (void) ParseGeometry(args[0],&geometry_info);
cristy947cb4c2011-10-20 18:41:46 +00002528 draw_info->interline_spacing=geometry_info.rho;
2529 break;
2530 }
anthonydcf510d2011-10-30 13:51:40 +00002531 if (LocaleCompare("interpolate",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002532 {
2533 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00002534 MagickInterpolateOptions,MagickFalse,args[0]);
cristy947cb4c2011-10-20 18:41:46 +00002535 break;
2536 }
anthonydcf510d2011-10-30 13:51:40 +00002537 if (LocaleCompare("interword-spacing",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002538 {
2539 if (*argv[0] == '+')
2540 (void) ParseGeometry("0",&geometry_info);
2541 else
anthonydcf510d2011-10-30 13:51:40 +00002542 (void) ParseGeometry(args[0],&geometry_info);
cristy947cb4c2011-10-20 18:41:46 +00002543 draw_info->interword_spacing=geometry_info.rho;
2544 break;
2545 }
2546 break;
2547 }
2548 case 'k':
2549 {
anthonydcf510d2011-10-30 13:51:40 +00002550 if (LocaleCompare("kerning",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002551 {
2552 if (*argv[0] == '+')
2553 (void) ParseGeometry("0",&geometry_info);
2554 else
anthonydcf510d2011-10-30 13:51:40 +00002555 (void) ParseGeometry(args[0],&geometry_info);
cristy947cb4c2011-10-20 18:41:46 +00002556 draw_info->kerning=geometry_info.rho;
2557 break;
2558 }
anthony805a2d42011-09-25 08:25:12 +00002559 break;
2560 }
2561 case 'l':
2562 {
anthonydcf510d2011-10-30 13:51:40 +00002563 if (LocaleCompare("lat",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002564 {
2565 /*
2566 Local adaptive threshold image.
2567 */
cristy6fccee12011-10-20 18:43:18 +00002568 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002569 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002570 if ((flags & PercentValue) != 0)
2571 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2572 new_image=AdaptiveThresholdImage(*image,(size_t)
2573 geometry_info.rho,(size_t) geometry_info.sigma,(double)
2574 geometry_info.xi,exception);
2575 break;
2576 }
anthonydcf510d2011-10-30 13:51:40 +00002577 if (LocaleCompare("level",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002578 {
2579 MagickRealType
2580 black_point,
2581 gamma,
2582 white_point;
2583
2584 MagickStatusType
2585 flags;
2586
cristy947cb4c2011-10-20 18:41:46 +00002587 /*
2588 Parse levels.
2589 */
cristy6fccee12011-10-20 18:43:18 +00002590 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002591 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002592 black_point=geometry_info.rho;
2593 white_point=(MagickRealType) QuantumRange;
2594 if ((flags & SigmaValue) != 0)
2595 white_point=geometry_info.sigma;
2596 gamma=1.0;
2597 if ((flags & XiValue) != 0)
2598 gamma=geometry_info.xi;
2599 if ((flags & PercentValue) != 0)
2600 {
2601 black_point*=(MagickRealType) (QuantumRange/100.0);
2602 white_point*=(MagickRealType) (QuantumRange/100.0);
2603 }
2604 if ((flags & SigmaValue) == 0)
2605 white_point=(MagickRealType) QuantumRange-black_point;
2606 if ((*argv[0] == '+') || ((flags & AspectValue) != 0))
2607 (void) LevelizeImage(*image,black_point,white_point,gamma,
2608 exception);
2609 else
2610 (void) LevelImage(*image,black_point,white_point,gamma,
2611 exception);
anthony805a2d42011-09-25 08:25:12 +00002612 break;
2613 }
anthonydcf510d2011-10-30 13:51:40 +00002614 if (LocaleCompare("level-colors",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002615 {
2616 char
2617 token[MaxTextExtent];
2618
2619 const char
2620 *p;
2621
2622 PixelInfo
2623 black_point,
2624 white_point;
2625
anthonydcf510d2011-10-30 13:51:40 +00002626 p=(const char *) args[0];
anthony805a2d42011-09-25 08:25:12 +00002627 GetMagickToken(p,&p,token); /* get black point color */
2628 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002629 (void) QueryColorCompliance(token,AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002630 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002631 else
cristy269c9412011-10-13 23:41:15 +00002632 (void) QueryColorCompliance("#000000",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002633 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002634 if (isalpha((int) token[0]) || (token[0] == '#'))
2635 GetMagickToken(p,&p,token);
2636 if (*token == '\0')
2637 white_point=black_point; /* set everything to that color */
2638 else
2639 {
2640 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2641 GetMagickToken(p,&p,token); /* Get white point color. */
2642 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002643 (void) QueryColorCompliance(token,AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002644 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002645 else
cristy269c9412011-10-13 23:41:15 +00002646 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002647 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002648 }
2649 (void) LevelImageColors(*image,&black_point,&white_point,
2650 *argv[0] == '+' ? MagickTrue : MagickFalse,exception);
2651 break;
2652 }
anthonydcf510d2011-10-30 13:51:40 +00002653 if (LocaleCompare("linear-stretch",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002654 {
2655 double
2656 black_point,
2657 white_point;
2658
2659 MagickStatusType
2660 flags;
2661
cristy6fccee12011-10-20 18:43:18 +00002662 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002663 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002664 black_point=geometry_info.rho;
2665 white_point=(MagickRealType) (*image)->columns*(*image)->rows;
2666 if ((flags & SigmaValue) != 0)
2667 white_point=geometry_info.sigma;
2668 if ((flags & PercentValue) != 0)
2669 {
2670 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2671 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2672 }
2673 if ((flags & SigmaValue) == 0)
2674 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2675 black_point;
2676 (void) LinearStretchImage(*image,black_point,white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002677 break;
2678 }
anthonydcf510d2011-10-30 13:51:40 +00002679 if (LocaleCompare("linewidth",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002680 {
anthonydcf510d2011-10-30 13:51:40 +00002681 draw_info->stroke_width=InterpretLocaleValue(args[0],
cristy947cb4c2011-10-20 18:41:46 +00002682 (char **) NULL);
2683 break;
2684 }
anthonydcf510d2011-10-30 13:51:40 +00002685 if (LocaleCompare("liquid-rescale",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002686 {
2687 /*
2688 Liquid rescale image.
2689 */
cristy6fccee12011-10-20 18:43:18 +00002690 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002691 flags=ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00002692 if ((flags & XValue) == 0)
2693 geometry.x=1;
2694 if ((flags & YValue) == 0)
2695 geometry.y=0;
2696 new_image=LiquidRescaleImage(*image,geometry.width,
2697 geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
2698 break;
2699 }
anthonydcf510d2011-10-30 13:51:40 +00002700 if (LocaleCompare("lowlight-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002701 {
anthonydcf510d2011-10-30 13:51:40 +00002702 (void) SetImageArtifact(*image,option,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002703 break;
2704 }
2705 break;
2706 }
2707 case 'm':
2708 {
anthonydcf510d2011-10-30 13:51:40 +00002709 if (LocaleCompare("map",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002710 {
2711 Image
2712 *remap_image;
2713
cristy947cb4c2011-10-20 18:41:46 +00002714 /*
2715 Transform image colors to match this set of colors.
2716 */
cristy6fccee12011-10-20 18:43:18 +00002717 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002718 if (*argv[0] == '+')
2719 break;
anthonydcf510d2011-10-30 13:51:40 +00002720 remap_image=GetImageCache(image_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00002721 if (remap_image == (Image *) NULL)
2722 break;
2723 (void) RemapImage(quantize_info,*image,remap_image,exception);
2724 remap_image=DestroyImage(remap_image);
2725 break;
2726 }
anthonydcf510d2011-10-30 13:51:40 +00002727 if (LocaleCompare("mask",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002728 {
2729 Image
2730 *mask;
2731
cristy6fccee12011-10-20 18:43:18 +00002732 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002733 if (*argv[0] == '+')
2734 {
cristy947cb4c2011-10-20 18:41:46 +00002735 /*
2736 Remove a mask.
2737 */
anthony805a2d42011-09-25 08:25:12 +00002738 (void) SetImageMask(*image,(Image *) NULL,exception);
2739 break;
2740 }
cristy947cb4c2011-10-20 18:41:46 +00002741 /*
2742 Set the image mask.
2743 */
anthonydcf510d2011-10-30 13:51:40 +00002744 mask=GetImageCache(image_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00002745 if (mask == (Image *) NULL)
2746 break;
2747 (void) SetImageMask(*image,mask,exception);
2748 mask=DestroyImage(mask);
2749 break;
2750 }
anthonydcf510d2011-10-30 13:51:40 +00002751 if (LocaleCompare("matte",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002752 {
cristy947cb4c2011-10-20 18:41:46 +00002753 (void) SetImageAlphaChannel(*image,(*argv[0] == '-') ?
2754 SetAlphaChannel : DeactivateAlphaChannel,exception);
anthony805a2d42011-09-25 08:25:12 +00002755 break;
2756 }
anthonydcf510d2011-10-30 13:51:40 +00002757 if (LocaleCompare("median",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002758 {
cristy947cb4c2011-10-20 18:41:46 +00002759 /*
2760 Median filter image.
2761 */
cristy6fccee12011-10-20 18:43:18 +00002762 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002763 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002764 if ((flags & SigmaValue) == 0)
2765 geometry_info.sigma=geometry_info.rho;
2766 new_image=StatisticImage(*image,MedianStatistic,(size_t)
2767 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2768 break;
2769 }
anthonydcf510d2011-10-30 13:51:40 +00002770 if (LocaleCompare("mode",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002771 {
2772 /*
cristy947cb4c2011-10-20 18:41:46 +00002773 Mode image.
anthony805a2d42011-09-25 08:25:12 +00002774 */
cristy6fccee12011-10-20 18:43:18 +00002775 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002776 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002777 if ((flags & SigmaValue) == 0)
2778 geometry_info.sigma=geometry_info.rho;
2779 new_image=StatisticImage(*image,ModeStatistic,(size_t)
2780 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2781 break;
2782 }
anthonydcf510d2011-10-30 13:51:40 +00002783 if (LocaleCompare("modulate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002784 {
cristy6fccee12011-10-20 18:43:18 +00002785 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002786 (void) ModulateImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00002787 break;
2788 }
anthonydcf510d2011-10-30 13:51:40 +00002789 if (LocaleCompare("monitor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002790 {
anthonyafbaed72011-10-26 12:05:04 +00002791 /* FUTURE: Why is this a per-image setting? */
anthony805a2d42011-09-25 08:25:12 +00002792 if (*argv[0] == '+')
2793 {
2794 (void) SetImageProgressMonitor(*image,
2795 (MagickProgressMonitor) NULL,(void *) NULL);
2796 break;
2797 }
2798 (void) SetImageProgressMonitor(*image,MonitorProgress,
2799 (void *) NULL);
2800 break;
2801 }
anthonydcf510d2011-10-30 13:51:40 +00002802 if (LocaleCompare("monochrome",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002803 {
cristy6fccee12011-10-20 18:43:18 +00002804 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002805 (void) SetImageType(*image,BilevelType,exception);
2806 break;
2807 }
anthonydcf510d2011-10-30 13:51:40 +00002808 if (LocaleCompare("morphology",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002809 {
2810 char
2811 token[MaxTextExtent];
2812
2813 const char
2814 *p;
2815
2816 KernelInfo
2817 *kernel;
2818
2819 MorphologyMethod
2820 method;
2821
2822 ssize_t
2823 iterations;
2824
cristy6fccee12011-10-20 18:43:18 +00002825 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002826 p=args[0];
anthony805a2d42011-09-25 08:25:12 +00002827 GetMagickToken(p,&p,token);
2828 method=(MorphologyMethod) ParseCommandOption(
2829 MagickMorphologyOptions,MagickFalse,token);
2830 iterations=1L;
2831 GetMagickToken(p,&p,token);
2832 if ((*p == ':') || (*p == ','))
2833 GetMagickToken(p,&p,token);
2834 if ((*p != '\0'))
2835 iterations=(ssize_t) StringToLong(p);
2836 kernel=AcquireKernelInfo(argv[2]);
2837 if (kernel == (KernelInfo *) NULL)
2838 {
2839 (void) ThrowMagickException(exception,GetMagickModule(),
2840 OptionError,"UnabletoParseKernel","morphology");
2841 status=MagickFalse;
2842 break;
2843 }
2844 new_image=MorphologyImage(*image,method,iterations,kernel,
2845 exception);
2846 kernel=DestroyKernelInfo(kernel);
2847 break;
2848 }
anthonydcf510d2011-10-30 13:51:40 +00002849 if (LocaleCompare("motion-blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002850 {
cristy947cb4c2011-10-20 18:41:46 +00002851 /*
2852 Motion blur image.
2853 */
cristy6fccee12011-10-20 18:43:18 +00002854 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002855 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002856 if ((flags & SigmaValue) == 0)
2857 geometry_info.sigma=1.0;
2858 new_image=MotionBlurImage(*image,geometry_info.rho,
2859 geometry_info.sigma,geometry_info.xi,geometry_info.psi,
2860 exception);
2861 break;
2862 }
2863 break;
2864 }
2865 case 'n':
2866 {
anthonydcf510d2011-10-30 13:51:40 +00002867 if (LocaleCompare("negate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002868 {
cristy6fccee12011-10-20 18:43:18 +00002869 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002870 (void) NegateImage(*image,*argv[0] == '+' ? MagickTrue :
2871 MagickFalse,exception);
2872 break;
2873 }
anthonydcf510d2011-10-30 13:51:40 +00002874 if (LocaleCompare("noise",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002875 {
cristy6fccee12011-10-20 18:43:18 +00002876 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002877 if (*argv[0] == '-')
2878 {
anthonydcf510d2011-10-30 13:51:40 +00002879 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002880 if ((flags & SigmaValue) == 0)
2881 geometry_info.sigma=geometry_info.rho;
2882 new_image=StatisticImage(*image,NonpeakStatistic,(size_t)
2883 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2884 }
2885 else
2886 {
2887 NoiseType
2888 noise;
2889
2890 noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
anthonydcf510d2011-10-30 13:51:40 +00002891 MagickFalse,args[0]);
anthony5f867ae2011-10-09 10:28:34 +00002892 new_image=AddNoiseImage(*image,noise,exception);
anthony805a2d42011-09-25 08:25:12 +00002893 }
2894 break;
2895 }
anthonydcf510d2011-10-30 13:51:40 +00002896 if (LocaleCompare("normalize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002897 {
cristy6fccee12011-10-20 18:43:18 +00002898 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002899 (void) NormalizeImage(*image,exception);
2900 break;
2901 }
2902 break;
2903 }
2904 case 'o':
2905 {
anthonydcf510d2011-10-30 13:51:40 +00002906 if (LocaleCompare("opaque",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002907 {
2908 PixelInfo
2909 target;
2910
cristy6fccee12011-10-20 18:43:18 +00002911 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002912 (void) QueryColorCompliance(args[0],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00002913 exception);
anthony805a2d42011-09-25 08:25:12 +00002914 (void) OpaquePaintImage(*image,&target,&fill,*argv[0] == '-' ?
2915 MagickFalse : MagickTrue,exception);
2916 break;
2917 }
anthonydcf510d2011-10-30 13:51:40 +00002918 if (LocaleCompare("ordered-dither",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002919 {
cristy6fccee12011-10-20 18:43:18 +00002920 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002921 (void) OrderedPosterizeImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00002922 break;
2923 }
2924 break;
2925 }
2926 case 'p':
2927 {
anthonydcf510d2011-10-30 13:51:40 +00002928 if (LocaleCompare("paint",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002929 {
cristy6fccee12011-10-20 18:43:18 +00002930 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002931 (void) ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002932 new_image=OilPaintImage(*image,geometry_info.rho,
2933 geometry_info.sigma,exception);
2934 break;
2935 }
anthonydcf510d2011-10-30 13:51:40 +00002936 if (LocaleCompare("polaroid",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002937 {
2938 double
2939 angle;
2940
2941 RandomInfo
2942 *random_info;
2943
cristy947cb4c2011-10-20 18:41:46 +00002944 /*
2945 Simulate a Polaroid picture.
2946 */
cristy6fccee12011-10-20 18:43:18 +00002947 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002948 random_info=AcquireRandomInfo();
2949 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2950 random_info=DestroyRandomInfo(random_info);
2951 if (*argv[0] == '-')
2952 {
2953 SetGeometryInfo(&geometry_info);
anthonydcf510d2011-10-30 13:51:40 +00002954 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002955 angle=geometry_info.rho;
2956 }
2957 new_image=PolaroidImage(*image,draw_info,angle,
2958 interpolate_method,exception);
2959 break;
2960 }
anthonydcf510d2011-10-30 13:51:40 +00002961 if (LocaleCompare("posterize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002962 {
cristy947cb4c2011-10-20 18:41:46 +00002963 /*
2964 Posterize image.
2965 */
cristy6fccee12011-10-20 18:43:18 +00002966 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002967 (void) PosterizeImage(*image,StringToUnsignedLong(args[0]),
anthony805a2d42011-09-25 08:25:12 +00002968 quantize_info->dither,exception);
2969 break;
2970 }
anthonydcf510d2011-10-30 13:51:40 +00002971 if (LocaleCompare("preview",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002972 {
2973 PreviewType
cristy947cb4c2011-10-20 18:41:46 +00002974 preview_type;
anthony170fce92011-10-20 11:50:23 +00002975
cristy947cb4c2011-10-20 18:41:46 +00002976 /*
2977 Preview image.
2978 */
cristy6fccee12011-10-20 18:43:18 +00002979 (void) SyncImageSettings(image_info,*image,exception);
cristy947cb4c2011-10-20 18:41:46 +00002980 if (*argv[0] == '+')
2981 preview_type=UndefinedPreview;
2982 else
anthony805a2d42011-09-25 08:25:12 +00002983 preview_type=(PreviewType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00002984 MagickPreviewOptions,MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002985 new_image=PreviewImage(*image,preview_type,exception);
2986 break;
2987 }
anthonydcf510d2011-10-30 13:51:40 +00002988 if (LocaleCompare("profile",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002989 {
2990 const char
2991 *name;
2992
2993 const StringInfo
2994 *profile;
2995
2996 Image
2997 *profile_image;
2998
2999 ImageInfo
3000 *profile_info;
3001
cristy6fccee12011-10-20 18:43:18 +00003002 (void) SyncImageSettings(image_info,*image,exception);
cristy947cb4c2011-10-20 18:41:46 +00003003 if (*argv[0] == '+')
anthony805a2d42011-09-25 08:25:12 +00003004 {
cristy947cb4c2011-10-20 18:41:46 +00003005 /*
3006 Remove a profile from the image.
3007 */
anthonydcf510d2011-10-30 13:51:40 +00003008 (void) ProfileImage(*image,args[0],(const unsigned char *)
cristy092d71c2011-10-14 18:01:29 +00003009 NULL,0,exception);
anthony805a2d42011-09-25 08:25:12 +00003010 break;
3011 }
cristy947cb4c2011-10-20 18:41:46 +00003012 /*
3013 Associate a profile with the image.
3014 */
anthony805a2d42011-09-25 08:25:12 +00003015 profile_info=CloneImageInfo(image_info);
3016 profile=GetImageProfile(*image,"iptc");
3017 if (profile != (StringInfo *) NULL)
3018 profile_info->profile=(void *) CloneStringInfo(profile);
anthonydcf510d2011-10-30 13:51:40 +00003019 profile_image=GetImageCache(profile_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003020 profile_info=DestroyImageInfo(profile_info);
3021 if (profile_image == (Image *) NULL)
3022 {
3023 StringInfo
3024 *profile;
3025
3026 profile_info=CloneImageInfo(image_info);
anthonydcf510d2011-10-30 13:51:40 +00003027 (void) CopyMagickString(profile_info->filename,args[0],
anthony805a2d42011-09-25 08:25:12 +00003028 MaxTextExtent);
3029 profile=FileToStringInfo(profile_info->filename,~0UL,exception);
3030 if (profile != (StringInfo *) NULL)
3031 {
3032 (void) ProfileImage(*image,profile_info->magick,
3033 GetStringInfoDatum(profile),(size_t)
cristy092d71c2011-10-14 18:01:29 +00003034 GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003035 profile=DestroyStringInfo(profile);
3036 }
3037 profile_info=DestroyImageInfo(profile_info);
3038 break;
3039 }
3040 ResetImageProfileIterator(profile_image);
3041 name=GetNextImageProfile(profile_image);
3042 while (name != (const char *) NULL)
3043 {
3044 profile=GetImageProfile(profile_image,name);
3045 if (profile != (StringInfo *) NULL)
3046 (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
cristy092d71c2011-10-14 18:01:29 +00003047 (size_t) GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003048 name=GetNextImageProfile(profile_image);
3049 }
3050 profile_image=DestroyImage(profile_image);
3051 break;
3052 }
3053 break;
3054 }
cristy947cb4c2011-10-20 18:41:46 +00003055 case 'q':
3056 {
anthonydcf510d2011-10-30 13:51:40 +00003057 if (LocaleCompare("quantize",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00003058 {
3059 if (*argv[0] == '+')
3060 {
3061 quantize_info->colorspace=UndefinedColorspace;
3062 break;
3063 }
3064 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00003065 MagickColorspaceOptions,MagickFalse,args[0]);
cristy947cb4c2011-10-20 18:41:46 +00003066 break;
3067 }
3068 break;
3069 }
anthony805a2d42011-09-25 08:25:12 +00003070 case 'r':
3071 {
anthonydcf510d2011-10-30 13:51:40 +00003072 if (LocaleCompare("radial-blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003073 {
cristy6fccee12011-10-20 18:43:18 +00003074 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003075 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003076 new_image=RadialBlurImage(*image,geometry_info.rho,
3077 geometry_info.sigma,exception);
3078 break;
3079 }
anthonydcf510d2011-10-30 13:51:40 +00003080 if (LocaleCompare("raise",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003081 {
anthonydcf510d2011-10-30 13:51:40 +00003082 flags=ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003083 if ((flags & SigmaValue) == 0)
3084 geometry.height=geometry.width;
3085 (void) RaiseImage(*image,&geometry,*argv[0] == '-' ? MagickTrue :
3086 MagickFalse,exception);
3087 break;
3088 }
anthonydcf510d2011-10-30 13:51:40 +00003089 if (LocaleCompare("random-threshold",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003090 {
cristy6fccee12011-10-20 18:43:18 +00003091 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003092 (void) RandomThresholdImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003093 break;
3094 }
anthonydcf510d2011-10-30 13:51:40 +00003095 if (LocaleCompare("recolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003096 {
3097 KernelInfo
3098 *kernel;
3099
cristy6fccee12011-10-20 18:43:18 +00003100 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003101 kernel=AcquireKernelInfo(args[0]);
anthony805a2d42011-09-25 08:25:12 +00003102 if (kernel == (KernelInfo *) NULL)
3103 break;
3104 new_image=ColorMatrixImage(*image,kernel,exception);
3105 kernel=DestroyKernelInfo(kernel);
3106 break;
3107 }
anthonydcf510d2011-10-30 13:51:40 +00003108 if (LocaleCompare("remap",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003109 {
3110 Image
3111 *remap_image;
3112
cristy6fccee12011-10-20 18:43:18 +00003113 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003114 if (*argv[0] == '+')
3115 break;
anthonydcf510d2011-10-30 13:51:40 +00003116 remap_image=GetImageCache(image_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003117 if (remap_image == (Image *) NULL)
3118 break;
3119 (void) RemapImage(quantize_info,*image,remap_image,exception);
3120 remap_image=DestroyImage(remap_image);
3121 break;
3122 }
anthonydcf510d2011-10-30 13:51:40 +00003123 if (LocaleCompare("repage",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003124 {
3125 if (*argv[0] == '+')
3126 {
3127 (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
3128 break;
3129 }
anthonydcf510d2011-10-30 13:51:40 +00003130 (void) ResetImagePage(*image,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003131 break;
3132 }
anthonydcf510d2011-10-30 13:51:40 +00003133 if (LocaleCompare("resample",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003134 {
anthonyafbaed72011-10-26 12:05:04 +00003135 /* FUTURE: remove blur - no longer used */
cristy6fccee12011-10-20 18:43:18 +00003136 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003137 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003138 if ((flags & SigmaValue) == 0)
3139 geometry_info.sigma=geometry_info.rho;
3140 new_image=ResampleImage(*image,geometry_info.rho,
3141 geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
3142 break;
3143 }
anthonydcf510d2011-10-30 13:51:40 +00003144 if (LocaleCompare("resize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003145 {
anthonyafbaed72011-10-26 12:05:04 +00003146 /* FUTURE: remove blur argument - no longer used */
cristy6fccee12011-10-20 18:43:18 +00003147 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003148 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003149 new_image=ResizeImage(*image,geometry.width,geometry.height,
3150 (*image)->filter,(*image)->blur,exception);
3151 break;
3152 }
anthonydcf510d2011-10-30 13:51:40 +00003153 if (LocaleCompare("roll",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003154 {
cristy6fccee12011-10-20 18:43:18 +00003155 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003156 (void) ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003157 new_image=RollImage(*image,geometry.x,geometry.y,exception);
3158 break;
3159 }
anthonydcf510d2011-10-30 13:51:40 +00003160 if (LocaleCompare("rotate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003161 {
anthonyafbaed72011-10-26 12:05:04 +00003162 /* special case rotation flags */
cristy6fccee12011-10-20 18:43:18 +00003163 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003164 if (strchr(args[0],'>') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00003165 if ((*image)->columns <= (*image)->rows)
3166 break;
anthonydcf510d2011-10-30 13:51:40 +00003167 if (strchr(args[0],'<') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00003168 if ((*image)->columns >= (*image)->rows)
3169 break;
anthonyafbaed72011-10-26 12:05:04 +00003170
anthonydcf510d2011-10-30 13:51:40 +00003171 (void) ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003172 new_image=RotateImage(*image,geometry_info.rho,exception);
3173 break;
3174 }
3175 break;
3176 }
3177 case 's':
3178 {
anthonydcf510d2011-10-30 13:51:40 +00003179 if (LocaleCompare("sample",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003180 {
cristy6fccee12011-10-20 18:43:18 +00003181 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003182 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003183 new_image=SampleImage(*image,geometry.width,geometry.height,
3184 exception);
3185 break;
3186 }
anthonydcf510d2011-10-30 13:51:40 +00003187 if (LocaleCompare("scale",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003188 {
cristy6fccee12011-10-20 18:43:18 +00003189 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003190 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003191 new_image=ScaleImage(*image,geometry.width,geometry.height,
3192 exception);
3193 break;
3194 }
anthonydcf510d2011-10-30 13:51:40 +00003195 if (LocaleCompare("selective-blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003196 {
cristy6fccee12011-10-20 18:43:18 +00003197 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003198 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003199 if ((flags & PercentValue) != 0)
3200 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3201 new_image=SelectiveBlurImage(*image,geometry_info.rho,
3202 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3203 break;
3204 }
anthonydcf510d2011-10-30 13:51:40 +00003205 if (LocaleCompare("separate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003206 {
3207 /*
3208 Break channels into separate images.
3209 WARNING: This can generate multiple images!
3210 */
cristy6fccee12011-10-20 18:43:18 +00003211 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003212 new_image=SeparateImages(*image,exception);
3213 break;
3214 }
anthonydcf510d2011-10-30 13:51:40 +00003215 if (LocaleCompare("sepia-tone",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003216 {
3217 double
3218 threshold;
3219
cristy6fccee12011-10-20 18:43:18 +00003220 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003221 threshold=SiPrefixToDouble(args[0],QuantumRange);
anthony805a2d42011-09-25 08:25:12 +00003222 new_image=SepiaToneImage(*image,threshold,exception);
3223 break;
3224 }
anthonydcf510d2011-10-30 13:51:40 +00003225 if (LocaleCompare("segment",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003226 {
cristy6fccee12011-10-20 18:43:18 +00003227 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003228 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003229 if ((flags & SigmaValue) == 0)
3230 geometry_info.sigma=1.0;
3231 (void) SegmentImage(*image,(*image)->colorspace,
3232 image_info->verbose,geometry_info.rho,geometry_info.sigma,
3233 exception);
3234 break;
3235 }
anthonydcf510d2011-10-30 13:51:40 +00003236 if (LocaleCompare("set",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003237 {
3238 char
3239 *value;
3240
anthony805a2d42011-09-25 08:25:12 +00003241 if (*argv[0] == '+')
3242 {
anthonydcf510d2011-10-30 13:51:40 +00003243 if (LocaleNCompare(args[0],"registry:",9) == 0)
3244 (void) DeleteImageRegistry(args[0]+9);
anthony805a2d42011-09-25 08:25:12 +00003245 else
anthonydcf510d2011-10-30 13:51:40 +00003246 if (LocaleNCompare(args[0],"argv[0]:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003247 {
anthonydcf510d2011-10-30 13:51:40 +00003248 (void) DeleteImageOption(image_info,args[0]+7);
3249 (void) DeleteImageArtifact(*image,args[0]+7);
anthony805a2d42011-09-25 08:25:12 +00003250 }
3251 else
anthonydcf510d2011-10-30 13:51:40 +00003252 (void) DeleteImageProperty(*image,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003253 break;
3254 }
3255 value=InterpretImageProperties(image_info,*image,argv[2],
3256 exception);
3257 if (value == (char *) NULL)
3258 break;
anthonydcf510d2011-10-30 13:51:40 +00003259 if (LocaleNCompare(args[0],"registry:",9) == 0)
3260 (void) SetImageRegistry(StringRegistryType,args[0]+9,value,
anthony805a2d42011-09-25 08:25:12 +00003261 exception);
3262 else
anthonydcf510d2011-10-30 13:51:40 +00003263 if (LocaleNCompare(args[0],"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003264 {
anthonydcf510d2011-10-30 13:51:40 +00003265 (void) SetImageOption(image_info,args[0]+7,value);
3266 (void) SetImageArtifact(*image,args[0]+7,value);
anthony805a2d42011-09-25 08:25:12 +00003267 }
3268 else
anthonydcf510d2011-10-30 13:51:40 +00003269 (void) SetImageProperty(*image,args[0],value,exception);
anthony805a2d42011-09-25 08:25:12 +00003270 value=DestroyString(value);
3271 break;
3272 }
anthonydcf510d2011-10-30 13:51:40 +00003273 if (LocaleCompare("shade",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003274 {
cristy6fccee12011-10-20 18:43:18 +00003275 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003276 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003277 if ((flags & SigmaValue) == 0)
3278 geometry_info.sigma=1.0;
3279 new_image=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue :
3280 MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
3281 break;
3282 }
anthonydcf510d2011-10-30 13:51:40 +00003283 if (LocaleCompare("shadow",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003284 {
cristy6fccee12011-10-20 18:43:18 +00003285 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003286 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003287 if ((flags & SigmaValue) == 0)
3288 geometry_info.sigma=1.0;
3289 if ((flags & XiValue) == 0)
3290 geometry_info.xi=4.0;
3291 if ((flags & PsiValue) == 0)
3292 geometry_info.psi=4.0;
3293 new_image=ShadowImage(*image,geometry_info.rho,
3294 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3295 ceil(geometry_info.psi-0.5),exception);
3296 break;
3297 }
anthonydcf510d2011-10-30 13:51:40 +00003298 if (LocaleCompare("sharpen",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003299 {
cristy6fccee12011-10-20 18:43:18 +00003300 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003301 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003302 if ((flags & SigmaValue) == 0)
3303 geometry_info.sigma=1.0;
3304 if ((flags & XiValue) == 0)
3305 geometry_info.xi=0.0;
3306 new_image=SharpenImage(*image,geometry_info.rho,
3307 geometry_info.sigma,geometry_info.xi,exception);
3308 break;
3309 }
anthonydcf510d2011-10-30 13:51:40 +00003310 if (LocaleCompare("shave",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003311 {
cristy6fccee12011-10-20 18:43:18 +00003312 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003313 flags=ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003314 new_image=ShaveImage(*image,&geometry,exception);
3315 break;
3316 }
anthonydcf510d2011-10-30 13:51:40 +00003317 if (LocaleCompare("shear",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003318 {
cristy6fccee12011-10-20 18:43:18 +00003319 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003320 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003321 if ((flags & SigmaValue) == 0)
3322 geometry_info.sigma=geometry_info.rho;
3323 new_image=ShearImage(*image,geometry_info.rho,
3324 geometry_info.sigma,exception);
3325 break;
3326 }
anthonydcf510d2011-10-30 13:51:40 +00003327 if (LocaleCompare("sigmoidal-contrast",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003328 {
cristy6fccee12011-10-20 18:43:18 +00003329 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003330 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003331 if ((flags & SigmaValue) == 0)
3332 geometry_info.sigma=(double) QuantumRange/2.0;
3333 if ((flags & PercentValue) != 0)
3334 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3335 100.0;
3336 (void) SigmoidalContrastImage(*image,(*argv[0] == '-') ?
3337 MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
3338 exception);
3339 break;
3340 }
anthonydcf510d2011-10-30 13:51:40 +00003341 if (LocaleCompare("sketch",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003342 {
cristy6fccee12011-10-20 18:43:18 +00003343 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003344 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003345 if ((flags & SigmaValue) == 0)
3346 geometry_info.sigma=1.0;
3347 new_image=SketchImage(*image,geometry_info.rho,
3348 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3349 break;
3350 }
anthonydcf510d2011-10-30 13:51:40 +00003351 if (LocaleCompare("solarize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003352 {
3353 double
3354 threshold;
3355
cristy6fccee12011-10-20 18:43:18 +00003356 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003357 threshold=SiPrefixToDouble(args[0],QuantumRange);
anthony805a2d42011-09-25 08:25:12 +00003358 (void) SolarizeImage(*image,threshold,exception);
3359 break;
3360 }
anthonydcf510d2011-10-30 13:51:40 +00003361 if (LocaleCompare("sparse-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003362 {
3363 SparseColorMethod
3364 method;
3365
3366 char
3367 *arguments;
3368
cristy6fccee12011-10-20 18:43:18 +00003369 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003370 method=(SparseColorMethod) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00003371 MagickSparseColorOptions,MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003372 arguments=InterpretImageProperties(image_info,*image,argv[2],
3373 exception);
3374 if (arguments == (char *) NULL)
3375 break;
3376 new_image=SparseColorOption(*image,method,arguments,
3377 argv[0][0] == '+' ? MagickTrue : MagickFalse,exception);
3378 arguments=DestroyString(arguments);
3379 break;
3380 }
anthonydcf510d2011-10-30 13:51:40 +00003381 if (LocaleCompare("splice",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003382 {
cristy6fccee12011-10-20 18:43:18 +00003383 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003384 (void) ParseGravityGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003385 new_image=SpliceImage(*image,&geometry,exception);
3386 break;
3387 }
anthonydcf510d2011-10-30 13:51:40 +00003388 if (LocaleCompare("spread",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003389 {
cristy6fccee12011-10-20 18:43:18 +00003390 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003391 (void) ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003392 new_image=SpreadImage(*image,geometry_info.rho,
3393 interpolate_method,exception);
3394 break;
3395 }
anthonydcf510d2011-10-30 13:51:40 +00003396 if (LocaleCompare("statistic",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003397 {
3398 StatisticType
3399 type;
3400
cristy6fccee12011-10-20 18:43:18 +00003401 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003402 type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
anthonydcf510d2011-10-30 13:51:40 +00003403 MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003404 (void) ParseGeometry(argv[2],&geometry_info);
3405 new_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
3406 (size_t) geometry_info.sigma,exception);
3407 break;
3408 }
anthonydcf510d2011-10-30 13:51:40 +00003409 if (LocaleCompare("strip",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003410 {
cristy6fccee12011-10-20 18:43:18 +00003411 (void) SyncImageSettings(image_info,*image,exception);
anthony6613bf32011-10-15 07:24:44 +00003412 (void) StripImage(*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003413 break;
3414 }
anthonydcf510d2011-10-30 13:51:40 +00003415 if (LocaleCompare("swirl",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003416 {
cristy6fccee12011-10-20 18:43:18 +00003417 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003418 (void) ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003419 new_image=SwirlImage(*image,geometry_info.rho,
3420 interpolate_method,exception);
3421 break;
3422 }
3423 break;
3424 }
3425 case 't':
3426 {
anthonydcf510d2011-10-30 13:51:40 +00003427 if (LocaleCompare("threshold",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003428 {
3429 double
3430 threshold;
3431
cristy6fccee12011-10-20 18:43:18 +00003432 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003433 if (*argv[0] == '+')
3434 threshold=(double) QuantumRange/2;
3435 else
anthonydcf510d2011-10-30 13:51:40 +00003436 threshold=SiPrefixToDouble(args[0],QuantumRange);
anthony6613bf32011-10-15 07:24:44 +00003437 (void) BilevelImage(*image,threshold,exception);
anthony805a2d42011-09-25 08:25:12 +00003438 break;
3439 }
anthonydcf510d2011-10-30 13:51:40 +00003440 if (LocaleCompare("thumbnail",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003441 {
3442 /*
3443 Thumbnail image.
3444 */
cristy6fccee12011-10-20 18:43:18 +00003445 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003446 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003447 new_image=ThumbnailImage(*image,geometry.width,geometry.height,
3448 exception);
3449 break;
3450 }
anthonydcf510d2011-10-30 13:51:40 +00003451 if (LocaleCompare("tint",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003452 {
cristy6fccee12011-10-20 18:43:18 +00003453 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003454 new_image=TintImage(*image,args[0],&fill,exception);
anthony805a2d42011-09-25 08:25:12 +00003455 break;
3456 }
anthonydcf510d2011-10-30 13:51:40 +00003457 if (LocaleCompare("transform",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003458 {
cristy6fccee12011-10-20 18:43:18 +00003459 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003460 new_image=AffineTransformImage(*image,&draw_info->affine,
3461 exception);
3462 break;
3463 }
anthonydcf510d2011-10-30 13:51:40 +00003464 if (LocaleCompare("transparent",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003465 {
3466 PixelInfo
3467 target;
3468
cristy6fccee12011-10-20 18:43:18 +00003469 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003470 (void) QueryColorCompliance(args[0],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00003471 exception);
anthony805a2d42011-09-25 08:25:12 +00003472 (void) TransparentPaintImage(*image,&target,(Quantum)
3473 TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue,
cristy82d7af52011-10-16 16:26:41 +00003474 exception);
anthony805a2d42011-09-25 08:25:12 +00003475 break;
3476 }
anthonydcf510d2011-10-30 13:51:40 +00003477 if (LocaleCompare("transpose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003478 {
cristy6fccee12011-10-20 18:43:18 +00003479 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003480 new_image=TransposeImage(*image,exception);
3481 break;
3482 }
anthonydcf510d2011-10-30 13:51:40 +00003483 if (LocaleCompare("transverse",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003484 {
cristy6fccee12011-10-20 18:43:18 +00003485 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003486 new_image=TransverseImage(*image,exception);
3487 break;
3488 }
anthonydcf510d2011-10-30 13:51:40 +00003489 if (LocaleCompare("treedepth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003490 {
anthonydcf510d2011-10-30 13:51:40 +00003491 quantize_info->tree_depth=StringToUnsignedLong(args[0]);
anthony805a2d42011-09-25 08:25:12 +00003492 break;
3493 }
anthonydcf510d2011-10-30 13:51:40 +00003494 if (LocaleCompare("trim",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003495 {
cristy6fccee12011-10-20 18:43:18 +00003496 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003497 new_image=TrimImage(*image,exception);
3498 break;
3499 }
anthonydcf510d2011-10-30 13:51:40 +00003500 if (LocaleCompare("type",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003501 {
anthonyab3a50c2011-10-27 11:48:57 +00003502 /* Note that "type" setting should have already been defined */
cristy6fccee12011-10-20 18:43:18 +00003503 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003504 (void) SetImageType(*image,type,exception);
3505 break;
3506 }
3507 break;
3508 }
3509 case 'u':
3510 {
anthonydcf510d2011-10-30 13:51:40 +00003511 if (LocaleCompare("unique",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003512 {
3513 if (*argv[0] == '+')
3514 {
3515 (void) DeleteImageArtifact(*image,"identify:unique-colors");
3516 break;
3517 }
3518 (void) SetImageArtifact(*image,"identify:unique-colors","true");
3519 (void) SetImageArtifact(*image,"verbose","true");
3520 break;
3521 }
anthonydcf510d2011-10-30 13:51:40 +00003522 if (LocaleCompare("unique-colors",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003523 {
cristy6fccee12011-10-20 18:43:18 +00003524 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003525 new_image=UniqueImageColors(*image,exception);
3526 break;
3527 }
anthonydcf510d2011-10-30 13:51:40 +00003528 if (LocaleCompare("unsharp",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003529 {
cristy6fccee12011-10-20 18:43:18 +00003530 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003531 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003532 if ((flags & SigmaValue) == 0)
3533 geometry_info.sigma=1.0;
3534 if ((flags & XiValue) == 0)
3535 geometry_info.xi=1.0;
3536 if ((flags & PsiValue) == 0)
3537 geometry_info.psi=0.05;
3538 new_image=UnsharpMaskImage(*image,geometry_info.rho,
3539 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3540 break;
3541 }
3542 break;
3543 }
3544 case 'v':
3545 {
anthonydcf510d2011-10-30 13:51:40 +00003546 if (LocaleCompare("verbose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003547 {
anthonydcf510d2011-10-30 13:51:40 +00003548 (void) SetImageArtifact(*image,option,
anthonyab3a50c2011-10-27 11:48:57 +00003549 *argv[0] == '+' ? "false" : "true");
anthony805a2d42011-09-25 08:25:12 +00003550 break;
3551 }
anthonydcf510d2011-10-30 13:51:40 +00003552 if (LocaleCompare("vignette",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003553 {
3554 /*
3555 Vignette image.
3556 */
cristy6fccee12011-10-20 18:43:18 +00003557 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003558 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003559 if ((flags & SigmaValue) == 0)
3560 geometry_info.sigma=1.0;
3561 if ((flags & XiValue) == 0)
3562 geometry_info.xi=0.1*(*image)->columns;
3563 if ((flags & PsiValue) == 0)
3564 geometry_info.psi=0.1*(*image)->rows;
3565 new_image=VignetteImage(*image,geometry_info.rho,
3566 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3567 ceil(geometry_info.psi-0.5),exception);
3568 break;
3569 }
anthonydcf510d2011-10-30 13:51:40 +00003570 if (LocaleCompare("virtual-pixel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003571 {
anthonyab3a50c2011-10-27 11:48:57 +00003572 /* setting already defined in image_info structure */
3573 SetImageVirtualPixelMethod(*image, image_info->virtual_pixel_method);
anthony805a2d42011-09-25 08:25:12 +00003574 break;
3575 }
3576 break;
3577 }
3578 case 'w':
3579 {
anthonydcf510d2011-10-30 13:51:40 +00003580 if (LocaleCompare("wave",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003581 {
cristy6fccee12011-10-20 18:43:18 +00003582 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003583 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003584 if ((flags & SigmaValue) == 0)
3585 geometry_info.sigma=1.0;
3586 new_image=WaveImage(*image,geometry_info.rho,
anthonya89dd172011-10-04 13:29:35 +00003587 geometry_info.sigma,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003588 break;
3589 }
anthonydcf510d2011-10-30 13:51:40 +00003590 if (LocaleCompare("white-threshold",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003591 {
cristy6fccee12011-10-20 18:43:18 +00003592 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003593 (void) WhiteThresholdImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003594 break;
3595 }
3596 break;
3597 }
3598 default:
3599 break;
3600 }
3601 /*
3602 Replace current image with any image that was generated
3603 */
3604 if (new_image != (Image *) NULL)
3605 ReplaceImageInListReturnLast(image,new_image);
3606
3607 /*
3608 Free resources.
3609 */
3610 quantize_info=DestroyQuantizeInfo(quantize_info);
3611 draw_info=DestroyDrawInfo(draw_info);
cristy82d7af52011-10-16 16:26:41 +00003612 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthonya89dd172011-10-04 13:29:35 +00003613 return(status == 0 ? MagickFalse : MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003614}
3615
3616/*
3617%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3618% %
3619% %
3620% %
3621+ S e q u e n c e O p e r a t i o n I m a g e s %
3622% %
3623% %
3624% %
3625%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3626%
3627% SequenceOperationImages() applies a single operation that apply to the
3628% entire image list (e.g. -append, -layers, -coalesce, etc.).
3629%
3630% The format of the MogrifyImage method is:
3631%
3632% MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3633% const int argc, const char **argv,Image **images,
3634% ExceptionInfo *exception)
3635%
3636% A description of each parameter follows:
3637%
3638% o image_info: the image info..
3639%
3640% o argc: Specifies a pointer to an integer describing the number of
3641% elements in the argument vector.
3642%
3643% o argv: Specifies a pointer to a text array containing the command line
3644% arguments.
3645%
3646% o images: pointer to pointer of the first image in image list.
3647%
3648% o exception: return any errors or warnings in this structure.
3649%
3650*/
3651WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3652 const int argc,const char **argv,Image **images,ExceptionInfo *exception)
3653{
3654
3655 MagickStatusType
3656 status;
3657
3658 QuantizeInfo
3659 *quantize_info;
3660
3661 assert(image_info != (ImageInfo *) NULL);
3662 assert(image_info->signature == MagickSignature);
3663 assert(images != (Image **) NULL);
3664 assert((*images)->previous == (Image *) NULL);
3665 assert((*images)->signature == MagickSignature);
3666 if ((*images)->debug != MagickFalse)
3667 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3668 (*images)->filename);
anthonya89dd172011-10-04 13:29:35 +00003669 if ((argc <= 0) || (*argv == (char *) NULL))
3670 return(MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003671 status=MagickTrue;
3672
3673 switch (*(argv[0]+1))
3674 {
3675 case 'a':
3676 {
3677 if (LocaleCompare("affinity",argv[0]+1) == 0)
3678 {
cristy6fccee12011-10-20 18:43:18 +00003679 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003680 if (*argv[0] == '+')
3681 {
3682 (void) RemapImages(quantize_info,*images,(Image *) NULL,
3683 exception);
3684 break;
3685 }
3686 break;
3687 }
3688 if (LocaleCompare("append",argv[0]+1) == 0)
3689 {
3690 Image
3691 *append_image;
3692
cristy6fccee12011-10-20 18:43:18 +00003693 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003694 append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue :
3695 MagickFalse,exception);
3696 if (append_image == (Image *) NULL)
3697 {
3698 status=MagickFalse;
3699 break;
3700 }
3701 *images=DestroyImageList(*images);
3702 *images=append_image;
3703 break;
3704 }
3705 if (LocaleCompare("average",argv[0]+1) == 0)
3706 {
3707 Image
3708 *average_image;
3709
3710 /*
3711 Average an image sequence (deprecated).
3712 */
cristy6fccee12011-10-20 18:43:18 +00003713 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003714 average_image=EvaluateImages(*images,MeanEvaluateOperator,
3715 exception);
3716 if (average_image == (Image *) NULL)
3717 {
3718 status=MagickFalse;
3719 break;
3720 }
3721 *images=DestroyImageList(*images);
3722 *images=average_image;
3723 break;
3724 }
3725 break;
3726 }
3727 case 'c':
3728 {
3729 if (LocaleCompare("channel",argv[0]+1) == 0)
3730 {
3731 ChannelType
3732 channel;
3733
3734 if (*argv[0] == '+')
3735 {
3736 channel=DefaultChannels;
3737 break;
3738 }
3739 channel=(ChannelType) ParseChannelOption(argv[1]);
3740 SetPixelChannelMap(*images,channel);
3741 break;
3742 }
3743 if (LocaleCompare("clut",argv[0]+1) == 0)
3744 {
3745 Image
3746 *clut_image,
3747 *image;
3748
cristy6fccee12011-10-20 18:43:18 +00003749 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003750 image=RemoveFirstImageFromList(images);
3751 clut_image=RemoveFirstImageFromList(images);
3752 if (clut_image == (Image *) NULL)
3753 {
3754 status=MagickFalse;
3755 break;
3756 }
anthonya89dd172011-10-04 13:29:35 +00003757 (void) ClutImage(image,clut_image,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003758 clut_image=DestroyImage(clut_image);
3759 *images=DestroyImageList(*images);
3760 *images=image;
3761 break;
3762 }
3763 if (LocaleCompare("coalesce",argv[0]+1) == 0)
3764 {
3765 Image
3766 *coalesce_image;
3767
cristy6fccee12011-10-20 18:43:18 +00003768 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003769 coalesce_image=CoalesceImages(*images,exception);
3770 if (coalesce_image == (Image *) NULL)
3771 {
3772 status=MagickFalse;
3773 break;
3774 }
3775 *images=DestroyImageList(*images);
3776 *images=coalesce_image;
3777 break;
3778 }
3779 if (LocaleCompare("combine",argv[0]+1) == 0)
3780 {
3781 Image
3782 *combine_image;
3783
cristy6fccee12011-10-20 18:43:18 +00003784 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003785 combine_image=CombineImages(*images,exception);
3786 if (combine_image == (Image *) NULL)
3787 {
3788 status=MagickFalse;
3789 break;
3790 }
3791 *images=DestroyImageList(*images);
3792 *images=combine_image;
3793 break;
3794 }
3795 if (LocaleCompare("composite",argv[0]+1) == 0)
3796 {
3797 Image
3798 *mask_image,
3799 *composite_image,
3800 *image;
3801
3802 RectangleInfo
3803 geometry;
3804
anthony5f867ae2011-10-09 10:28:34 +00003805 ComposeOperator
3806 compose;
3807
3808 const char*
3809 value;
3810
3811 value=GetImageOption(image_info,"compose");
3812 if (value != (const char *) NULL)
3813 compose=(CompositeOperator) ParseCommandOption(
3814 MagickComposeOptions,MagickFalse,value);
3815 else
3816 compose=OverCompositeOp; /* use Over not image->compose */
3817
3818 const char*
3819 value=GetImageOption(image_info,"compose");
3820
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
cristy6fccee12011-10-20 18:43:18 +00003828 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003829 image=RemoveFirstImageFromList(images);
3830 composite_image=RemoveFirstImageFromList(images);
3831 if (composite_image == (Image *) NULL)
3832 {
3833 status=MagickFalse;
3834 break;
3835 }
3836 (void) TransformImage(&composite_image,(char *) NULL,
anthony6613bf32011-10-15 07:24:44 +00003837 composite_image->geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003838 SetGeometry(composite_image,&geometry);
3839 (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
3840 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
3841 &geometry);
3842 mask_image=RemoveFirstImageFromList(images);
3843 if (mask_image != (Image *) NULL)
3844 {
anthony5f867ae2011-10-09 10:28:34 +00003845 if ((compose == DisplaceCompositeOp) ||
3846 (compose == DistortCompositeOp))
anthony805a2d42011-09-25 08:25:12 +00003847 {
3848 /*
3849 Merge Y displacement into X displacement image.
3850 */
3851 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
anthony6613bf32011-10-15 07:24:44 +00003852 mask_image,0,0,exception);
anthony805a2d42011-09-25 08:25:12 +00003853 mask_image=DestroyImage(mask_image);
3854 }
3855 else
3856 {
3857 /*
3858 Set a blending mask for the composition.
3859 Posible error, what if image->mask already set.
3860 */
3861 image->mask=mask_image;
3862 (void) NegateImage(image->mask,MagickFalse,exception);
3863 }
3864 }
anthony5f867ae2011-10-09 10:28:34 +00003865 (void) CompositeImage(image,compose,composite_image,
anthony6613bf32011-10-15 07:24:44 +00003866 geometry.x,geometry.y,exception);
anthony805a2d42011-09-25 08:25:12 +00003867 if (mask_image != (Image *) NULL)
3868 mask_image=image->mask=DestroyImage(image->mask);
3869 composite_image=DestroyImage(composite_image);
anthony805a2d42011-09-25 08:25:12 +00003870 *images=DestroyImageList(*images);
3871 *images=image;
3872 break;
3873 }
3874 break;
3875 }
3876 case 'd':
3877 {
3878 if (LocaleCompare("deconstruct",argv[0]+1) == 0)
3879 {
3880 Image
3881 *deconstruct_image;
3882
cristy6fccee12011-10-20 18:43:18 +00003883 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003884 deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
3885 exception);
3886 if (deconstruct_image == (Image *) NULL)
3887 {
3888 status=MagickFalse;
3889 break;
3890 }
3891 *images=DestroyImageList(*images);
3892 *images=deconstruct_image;
3893 break;
3894 }
3895 if (LocaleCompare("delete",argv[0]+1) == 0)
3896 {
3897 if (*argv[0] == '+')
3898 DeleteImages(images,"-1",exception);
3899 else
3900 DeleteImages(images,argv[1],exception);
3901 break;
3902 }
3903 if (LocaleCompare("dither",argv[0]+1) == 0)
3904 {
3905 if (*argv[0] == '+')
3906 {
3907 quantize_info->dither=MagickFalse;
3908 break;
3909 }
3910 quantize_info->dither=MagickTrue;
3911 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
3912 MagickDitherOptions,MagickFalse,argv[1]);
3913 break;
3914 }
3915 if (LocaleCompare("duplicate",argv[0]+1) == 0)
3916 {
3917 Image
3918 *duplicate_images;
3919
3920 if (*argv[0] == '+')
3921 duplicate_images=DuplicateImages(*images,1,"-1",exception);
3922 else
3923 {
3924 const char
3925 *p;
3926
3927 size_t
3928 number_duplicates;
3929
3930 number_duplicates=(size_t) StringToLong(argv[1]);
3931 p=strchr(argv[1],',');
3932 if (p == (const char *) NULL)
3933 duplicate_images=DuplicateImages(*images,number_duplicates,
3934 "-1",exception);
3935 else
3936 duplicate_images=DuplicateImages(*images,number_duplicates,p,
3937 exception);
3938 }
3939 AppendImageToList(images, duplicate_images);
cristy6fccee12011-10-20 18:43:18 +00003940 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003941 break;
3942 }
3943 break;
3944 }
3945 case 'e':
3946 {
3947 if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0)
3948 {
3949 Image
3950 *evaluate_image;
3951
3952 MagickEvaluateOperator
3953 op;
3954
3955 (void) SyncImageSettings(image_info,*images);
3956 op=(MagickEvaluateOperator) ParseCommandOption(
3957 MagickEvaluateOptions,MagickFalse,argv[1]);
3958 evaluate_image=EvaluateImages(*images,op,exception);
3959 if (evaluate_image == (Image *) NULL)
3960 {
3961 status=MagickFalse;
3962 break;
3963 }
3964 *images=DestroyImageList(*images);
3965 *images=evaluate_image;
3966 break;
3967 }
3968 break;
3969 }
3970 case 'f':
3971 {
3972 if (LocaleCompare("fft",argv[0]+1) == 0)
3973 {
3974 Image
3975 *fourier_image;
3976
3977 /*
3978 Implements the discrete Fourier transform (DFT).
3979 */
3980 (void) SyncImageSettings(image_info,*images);
3981 fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ?
3982 MagickTrue : MagickFalse,exception);
3983 if (fourier_image == (Image *) NULL)
3984 break;
3985 *images=DestroyImage(*images);
3986 *images=fourier_image;
3987 break;
3988 }
3989 if (LocaleCompare("flatten",argv[0]+1) == 0)
3990 {
3991 Image
3992 *flatten_image;
3993
cristy6fccee12011-10-20 18:43:18 +00003994 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003995 flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
3996 if (flatten_image == (Image *) NULL)
3997 break;
3998 *images=DestroyImageList(*images);
3999 *images=flatten_image;
4000 break;
4001 }
4002 if (LocaleCompare("fx",argv[0]+1) == 0)
4003 {
4004 Image
4005 *fx_image;
4006
cristy6fccee12011-10-20 18:43:18 +00004007 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004008 fx_image=FxImage(*images,argv[1],exception);
4009 if (fx_image == (Image *) NULL)
4010 {
4011 status=MagickFalse;
4012 break;
4013 }
4014 *images=DestroyImageList(*images);
4015 *images=fx_image;
4016 break;
4017 }
4018 break;
4019 }
4020 case 'h':
4021 {
4022 if (LocaleCompare("hald-clut",argv[0]+1) == 0)
4023 {
4024 Image
4025 *hald_image,
4026 *image;
4027
cristy6fccee12011-10-20 18:43:18 +00004028 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004029 image=RemoveFirstImageFromList(images);
4030 hald_image=RemoveFirstImageFromList(images);
4031 if (hald_image == (Image *) NULL)
4032 {
4033 status=MagickFalse;
4034 break;
4035 }
4036 (void) HaldClutImage(image,hald_image,exception);
4037 hald_image=DestroyImage(hald_image);
4038 if (*images != (Image *) NULL)
4039 *images=DestroyImageList(*images);
4040 *images=image;
4041 break;
4042 }
4043 break;
4044 }
4045 case 'i':
4046 {
4047 if (LocaleCompare("ift",argv[0]+1) == 0)
4048 {
4049 Image
4050 *fourier_image,
4051 *magnitude_image,
4052 *phase_image;
4053
4054 /*
4055 Implements the inverse fourier discrete Fourier transform (DFT).
4056 */
cristy6fccee12011-10-20 18:43:18 +00004057 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004058 magnitude_image=RemoveFirstImageFromList(images);
4059 phase_image=RemoveFirstImageFromList(images);
4060 if (phase_image == (Image *) NULL)
4061 {
4062 status=MagickFalse;
4063 break;
4064 }
4065 fourier_image=InverseFourierTransformImage(magnitude_image,
4066 phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception);
4067 if (fourier_image == (Image *) NULL)
4068 break;
4069 if (*images != (Image *) NULL)
4070 *images=DestroyImage(*images);
4071 *images=fourier_image;
4072 break;
4073 }
4074 if (LocaleCompare("insert",argv[0]+1) == 0)
4075 {
4076 Image
4077 *p,
4078 *q;
4079
4080 index=0;
4081 if (*argv[0] != '+')
4082 index=(ssize_t) StringToLong(argv[1]);
4083 p=RemoveLastImageFromList(images);
4084 if (p == (Image *) NULL)
4085 {
4086 (void) ThrowMagickException(exception,GetMagickModule(),
4087 OptionError,"NoSuchImage","`%s'",argv[1]);
4088 status=MagickFalse;
4089 break;
4090 }
4091 q=p;
4092 if (index == 0)
4093 PrependImageToList(images,q);
4094 else
4095 if (index == (ssize_t) GetImageListLength(*images))
4096 AppendImageToList(images,q);
4097 else
4098 {
4099 q=GetImageFromList(*images,index-1);
4100 if (q == (Image *) NULL)
4101 {
4102 (void) ThrowMagickException(exception,GetMagickModule(),
4103 OptionError,"NoSuchImage","`%s'",argv[1]);
4104 status=MagickFalse;
4105 break;
4106 }
4107 InsertImageInList(&q,p);
4108 }
4109 *images=GetFirstImageInList(q);
4110 break;
4111 }
4112 if (LocaleCompare("interpolate",argv[0]+1) == 0)
4113 {
4114 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
4115 MagickInterpolateOptions,MagickFalse,argv[1]);
4116 break;
4117 }
4118 break;
4119 }
4120 case 'l':
4121 {
4122 if (LocaleCompare("layers",argv[0]+1) == 0)
4123 {
4124 Image
4125 *layers;
4126
4127 ImageLayerMethod
4128 method;
4129
cristy6fccee12011-10-20 18:43:18 +00004130 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004131 layers=(Image *) NULL;
4132 method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
4133 MagickFalse,argv[1]);
4134 switch (method)
4135 {
4136 case CoalesceLayer:
4137 {
4138 layers=CoalesceImages(*images,exception);
4139 break;
4140 }
4141 case CompareAnyLayer:
4142 case CompareClearLayer:
4143 case CompareOverlayLayer:
4144 default:
4145 {
4146 layers=CompareImagesLayers(*images,method,exception);
4147 break;
4148 }
4149 case MergeLayer:
4150 case FlattenLayer:
4151 case MosaicLayer:
4152 case TrimBoundsLayer:
4153 {
4154 layers=MergeImageLayers(*images,method,exception);
4155 break;
4156 }
4157 case DisposeLayer:
4158 {
4159 layers=DisposeImages(*images,exception);
4160 break;
4161 }
4162 case OptimizeImageLayer:
4163 {
4164 layers=OptimizeImageLayers(*images,exception);
4165 break;
4166 }
4167 case OptimizePlusLayer:
4168 {
4169 layers=OptimizePlusImageLayers(*images,exception);
4170 break;
4171 }
4172 case OptimizeTransLayer:
4173 {
4174 OptimizeImageTransparency(*images,exception);
4175 break;
4176 }
4177 case RemoveDupsLayer:
4178 {
4179 RemoveDuplicateLayers(images,exception);
4180 break;
4181 }
4182 case RemoveZeroLayer:
4183 {
4184 RemoveZeroDelayLayers(images,exception);
4185 break;
4186 }
4187 case OptimizeLayer:
4188 {
4189 /*
4190 General Purpose, GIF Animation Optimizer.
4191 */
4192 layers=CoalesceImages(*images,exception);
4193 if (layers == (Image *) NULL)
4194 {
4195 status=MagickFalse;
4196 break;
4197 }
4198 *images=DestroyImageList(*images);
4199 *images=layers;
4200 layers=OptimizeImageLayers(*images,exception);
4201 if (layers == (Image *) NULL)
4202 {
4203 status=MagickFalse;
4204 break;
4205 }
4206 *images=DestroyImageList(*images);
4207 *images=layers;
4208 layers=(Image *) NULL;
4209 OptimizeImageTransparency(*images,exception);
4210 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4211 exception);
4212 break;
4213 }
4214 case CompositeLayer:
4215 {
anthony805a2d42011-09-25 08:25:12 +00004216 Image
4217 *source;
4218
4219 RectangleInfo
4220 geometry;
4221
anthony5f867ae2011-10-09 10:28:34 +00004222 ComposeOperator
4223 compose;
4224
4225 const char*
4226 value;
4227
4228 value=GetImageOption(image_info,"compose");
4229 if (value != (const char *) NULL)
4230 compose=(CompositeOperator) ParseCommandOption(
4231 MagickComposeOptions,MagickFalse,value);
4232 else
4233 compose=OverCompositeOp; /* use Over not image->compose */
4234
anthony805a2d42011-09-25 08:25:12 +00004235 /*
4236 Split image sequence at the first 'NULL:' image.
4237 */
4238 source=(*images);
4239 while (source != (Image *) NULL)
4240 {
4241 source=GetNextImageInList(source);
4242 if ((source != (Image *) NULL) &&
4243 (LocaleCompare(source->magick,"NULL") == 0))
4244 break;
4245 }
4246 if (source != (Image *) NULL)
4247 {
4248 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4249 (GetNextImageInList(source) == (Image *) NULL))
4250 source=(Image *) NULL;
4251 else
4252 {
4253 /*
4254 Separate the two lists, junk the null: image.
4255 */
4256 source=SplitImageList(source->previous);
4257 DeleteImageFromList(&source);
4258 }
4259 }
4260 if (source == (Image *) NULL)
4261 {
4262 (void) ThrowMagickException(exception,GetMagickModule(),
4263 OptionError,"MissingNullSeparator","layers Composite");
4264 status=MagickFalse;
4265 break;
4266 }
4267 /*
4268 Adjust offset with gravity and virtual canvas.
4269 */
4270 SetGeometry(*images,&geometry);
4271 (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
4272 geometry.width=source->page.width != 0 ?
4273 source->page.width : source->columns;
4274 geometry.height=source->page.height != 0 ?
4275 source->page.height : source->rows;
4276 GravityAdjustGeometry((*images)->page.width != 0 ?
4277 (*images)->page.width : (*images)->columns,
4278 (*images)->page.height != 0 ? (*images)->page.height :
4279 (*images)->rows,(*images)->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004280
4281 /*
4282 Compose the two image sequences together
4283 */
anthony805a2d42011-09-25 08:25:12 +00004284 CompositeLayers(*images,compose,source,geometry.x,geometry.y,
4285 exception);
4286 source=DestroyImageList(source);
4287 break;
4288 }
4289 }
4290 if (layers == (Image *) NULL)
4291 break;
anthony805a2d42011-09-25 08:25:12 +00004292 *images=DestroyImageList(*images);
4293 *images=layers;
4294 break;
4295 }
4296 break;
4297 }
4298 case 'm':
4299 {
4300 if (LocaleCompare("map",argv[0]+1) == 0)
4301 {
cristy6fccee12011-10-20 18:43:18 +00004302 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004303 if (*argv[0] == '+')
4304 {
4305 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4306 exception);
4307 break;
4308 }
4309 break;
4310 }
4311 if (LocaleCompare("maximum",argv[0]+1) == 0)
4312 {
4313 Image
4314 *maximum_image;
4315
4316 /*
4317 Maximum image sequence (deprecated).
4318 */
cristy6fccee12011-10-20 18:43:18 +00004319 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004320 maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
4321 if (maximum_image == (Image *) NULL)
4322 {
4323 status=MagickFalse;
4324 break;
4325 }
4326 *images=DestroyImageList(*images);
4327 *images=maximum_image;
4328 break;
4329 }
4330 if (LocaleCompare("minimum",argv[0]+1) == 0)
4331 {
4332 Image
4333 *minimum_image;
4334
4335 /*
4336 Minimum image sequence (deprecated).
4337 */
cristy6fccee12011-10-20 18:43:18 +00004338 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004339 minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
4340 if (minimum_image == (Image *) NULL)
4341 {
4342 status=MagickFalse;
4343 break;
4344 }
4345 *images=DestroyImageList(*images);
4346 *images=minimum_image;
4347 break;
4348 }
4349 if (LocaleCompare("morph",argv[0]+1) == 0)
4350 {
4351 Image
4352 *morph_image;
4353
cristy6fccee12011-10-20 18:43:18 +00004354 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004355 morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]),
4356 exception);
4357 if (morph_image == (Image *) NULL)
4358 {
4359 status=MagickFalse;
4360 break;
4361 }
4362 *images=DestroyImageList(*images);
4363 *images=morph_image;
4364 break;
4365 }
4366 if (LocaleCompare("mosaic",argv[0]+1) == 0)
4367 {
4368 Image
4369 *mosaic_image;
4370
cristy6fccee12011-10-20 18:43:18 +00004371 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004372 mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
4373 if (mosaic_image == (Image *) NULL)
4374 {
4375 status=MagickFalse;
4376 break;
4377 }
4378 *images=DestroyImageList(*images);
4379 *images=mosaic_image;
4380 break;
4381 }
4382 break;
4383 }
4384 case 'p':
4385 {
4386 if (LocaleCompare("print",argv[0]+1) == 0)
4387 {
4388 char
4389 *string;
4390
cristy6fccee12011-10-20 18:43:18 +00004391 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004392 string=InterpretImageProperties(image_info,*images,argv[1],
4393 exception);
4394 if (string == (char *) NULL)
4395 break;
4396 (void) FormatLocaleFile(stdout,"%s",string);
4397 string=DestroyString(string);
4398 }
4399 if (LocaleCompare("process",argv[0]+1) == 0)
4400 {
4401 char
4402 **arguments;
4403
4404 int
4405 j,
4406 number_arguments;
4407
cristy6fccee12011-10-20 18:43:18 +00004408 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004409 arguments=StringToArgv(argv[1],&number_arguments);
4410 if (arguments == (char **) NULL)
4411 break;
4412 if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
4413 {
4414 char
4415 breaker,
4416 quote,
4417 *token;
4418
4419 const char
4420 *arguments;
4421
4422 int
4423 next,
4424 status;
4425
4426 size_t
4427 length;
4428
4429 TokenInfo
4430 *token_info;
4431
4432 /*
4433 Support old style syntax, filter="-option arg".
4434 */
4435 length=strlen(argv[1]);
4436 token=(char *) NULL;
4437 if (~length >= (MaxTextExtent-1))
4438 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4439 sizeof(*token));
4440 if (token == (char *) NULL)
4441 break;
4442 next=0;
4443 arguments=argv[1];
4444 token_info=AcquireTokenInfo();
4445 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4446 "\"",'\0',&breaker,&next,&quote);
4447 token_info=DestroyTokenInfo(token_info);
4448 if (status == 0)
4449 {
4450 const char
4451 *argv;
4452
4453 argv=(&(arguments[next]));
4454 (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
4455 exception);
4456 }
4457 token=DestroyString(token);
4458 break;
4459 }
4460 (void) SubstituteString(&arguments[1],"-","");
4461 (void) InvokeDynamicImageFilter(arguments[1],&(*images),
4462 number_arguments-2,(const char **) arguments+2,exception);
4463 for (j=0; j < number_arguments; j++)
4464 arguments[j]=DestroyString(arguments[j]);
4465 arguments=(char **) RelinquishMagickMemory(arguments);
4466 break;
4467 }
4468 break;
4469 }
4470 case 'r':
4471 {
4472 if (LocaleCompare("reverse",argv[0]+1) == 0)
4473 {
4474 ReverseImageList(images);
anthony805a2d42011-09-25 08:25:12 +00004475 break;
4476 }
4477 break;
4478 }
4479 case 's':
4480 {
4481 if (LocaleCompare("smush",argv[0]+1) == 0)
4482 {
4483 Image
4484 *smush_image;
4485
4486 ssize_t
4487 offset;
4488
cristy6fccee12011-10-20 18:43:18 +00004489 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004490 offset=(ssize_t) StringToLong(argv[1]);
4491 smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue :
4492 MagickFalse,offset,exception);
4493 if (smush_image == (Image *) NULL)
4494 {
4495 status=MagickFalse;
4496 break;
4497 }
4498 *images=DestroyImageList(*images);
4499 *images=smush_image;
4500 break;
4501 }
4502 if (LocaleCompare("swap",argv[0]+1) == 0)
4503 {
4504 Image
4505 *p,
4506 *q,
4507 *swap;
4508
4509 ssize_t
4510 swap_index;
4511
4512 index=(-1);
4513 swap_index=(-2);
4514 if (*argv[0] != '+')
4515 {
4516 GeometryInfo
4517 geometry_info;
4518
4519 MagickStatusType
4520 flags;
4521
4522 swap_index=(-1);
4523 flags=ParseGeometry(argv[1],&geometry_info);
4524 index=(ssize_t) geometry_info.rho;
4525 if ((flags & SigmaValue) != 0)
4526 swap_index=(ssize_t) geometry_info.sigma;
4527 }
4528 p=GetImageFromList(*images,index);
4529 q=GetImageFromList(*images,swap_index);
4530 if ((p == (Image *) NULL) || (q == (Image *) NULL))
4531 {
4532 (void) ThrowMagickException(exception,GetMagickModule(),
4533 OptionError,"NoSuchImage","`%s'",(*images)->filename);
4534 status=MagickFalse;
4535 break;
4536 }
4537 if (p == q)
4538 break;
4539 swap=CloneImage(p,0,0,MagickTrue,exception);
4540 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
4541 ReplaceImageInList(&q,swap);
4542 *images=GetFirstImageInList(q);
4543 break;
4544 }
4545 break;
4546 }
4547 case 'w':
4548 {
4549 if (LocaleCompare("write",argv[0]+1) == 0)
4550 {
4551 char
4552 key[MaxTextExtent];
4553
4554 Image
4555 *write_images;
4556
4557 ImageInfo
4558 *write_info;
4559
cristy6fccee12011-10-20 18:43:18 +00004560 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004561 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]);
4562 (void) DeleteImageRegistry(key);
4563 write_images=(*images);
4564 if (*argv[0] == '+')
4565 write_images=CloneImageList(*images,exception);
4566 write_info=CloneImageInfo(image_info);
4567 status&=WriteImages(write_info,write_images,argv[1],exception);
4568 write_info=DestroyImageInfo(write_info);
4569 if (*argv[0] == '+')
4570 write_images=DestroyImageList(write_images);
4571 break;
4572 }
4573 break;
4574 }
4575 default:
4576 break;
4577 }
4578 quantize_info=DestroyQuantizeInfo(quantize_info);
4579
cristy82d7af52011-10-16 16:26:41 +00004580 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthony805a2d42011-09-25 08:25:12 +00004581 return(status != 0 ? MagickTrue : MagickFalse);
4582}
cristy0a0ca4f2011-09-28 01:15:28 +00004583#endif