blob: fa7ae0a0f5149998e826ab0514482f0ed54dd698 [file] [log] [blame]
anthony805a2d42011-09-25 08:25:12 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% OOO PPPP EEEE RRRR AA TTTTTT III OOO N N %
7% O O P P E R R A A TT I O O NN N %
8% O O PPPP EEE RRRR AAAA TT I O O N N N %
9% O O P E R R A A TT I O O N NN %
10% OOO P EEEE R RR A A TT III OOO N N %
11% %
12% %
13% MagickWand Module Methods %
14% %
15% Software Design %
16% John Cristy %
cristy0a0ca4f2011-09-28 01:15:28 +000017% September 2011 %
anthony805a2d42011-09-25 08:25:12 +000018% %
19% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
anthony805a2d42011-09-25 08:25:12 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% Apply the given options (settings, and simple, or sequence operations) to
37% the given image(s) according to the current "image_info" and "draw_info"
38% settings.
39%
40% The final goal is to allow the execution in a strict one option at a time
41% manner that is needed for 'pipelining and file scripting' of options in
42% IMv7.
43%
44% Anthony Thyssen, Sept 2011
45*/
cristyc689f1f2011-10-05 21:13:24 +000046#if 0
anthony805a2d42011-09-25 08:25:12 +000047
48/*
49 Include declarations.
50*/
51#include "MagickWand/studio.h"
52#include "MagickWand/MagickWand.h"
53#include "MagickWand/mogrify-private.h"
54#include "MagickCore/monitor-private.h"
55#include "MagickCore/thread-private.h"
56#include "MagickCore/string-private.h"
57
58/*
59 Define declarations.
60*/
61#define UndefinedCompressionQuality 0UL
62/*
63 Constant declaration. (temporary exports)
64*/
65static const char
66 BackgroundColor[] = "#fff", /* white */
67 BorderColor[] = "#dfdfdf", /* gray */
68 MatteColor[] = "#bdbdbd"; /* gray */
69
70/*
71** Function to report on the progress of image operations
72*/
73static MagickBooleanType MonitorProgress(const char *text,
74 const MagickOffsetType offset,const MagickSizeType extent,
75 void *wand_unused(client_data))
76{
77 char
78 message[MaxTextExtent],
79 tag[MaxTextExtent];
80
81 const char
82 *locale_message;
83
84 register char
85 *p;
86
87 if (extent < 2)
88 return(MagickTrue);
89 (void) CopyMagickMemory(tag,text,MaxTextExtent);
90 p=strrchr(tag,'/');
91 if (p != (char *) NULL)
92 *p='\0';
93 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
94 locale_message=GetLocaleMessage(message);
95 if (locale_message == message)
96 locale_message=tag;
97 if (p == (char *) NULL)
98 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
99 locale_message,(long) offset,(unsigned long) extent,(long)
100 (100L*offset/(extent-1)));
101 else
102 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
103 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
104 (100L*offset/(extent-1)));
105 if (offset == (MagickOffsetType) (extent-1))
106 (void) FormatLocaleFile(stderr,"\n");
107 (void) fflush(stderr);
108 return(MagickTrue);
109}
110
111/*
112** GetImageCache() will read an image into a image cache if not already
113** present then return the image that is in the cache under that filename.
114*/
115static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
116 ExceptionInfo *exception)
117{
118 char
119 key[MaxTextExtent];
120
121 ExceptionInfo
122 *sans_exception;
123
124 Image
125 *image;
126
127 ImageInfo
128 *read_info;
129
130 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
131 sans_exception=AcquireExceptionInfo();
132 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
133 sans_exception=DestroyExceptionInfo(sans_exception);
134 if (image != (Image *) NULL)
135 return(image);
136 read_info=CloneImageInfo(image_info);
137 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
138 image=ReadImage(read_info,exception);
139 read_info=DestroyImageInfo(read_info);
140 if (image != (Image *) NULL)
141 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
142 return(image);
143}
144
145/*
anthonya89dd172011-10-04 13:29:35 +0000146 SparseColorOption() parse the complex -sparse-color argument into an
147 an array of floating point values than call SparseColorImage().
148 Argument is a complex mix of floating-point pixel coodinates, and color
149 specifications (or direct floating point numbers). The number of floats
150 needed to represent a color varies depending on teh current channel
151 setting.
anthony805a2d42011-09-25 08:25:12 +0000152*/
153static Image *SparseColorOption(const Image *image,
154 const SparseColorMethod method,const char *arguments,
155 const MagickBooleanType color_from_image,ExceptionInfo *exception)
156{
157 char
158 token[MaxTextExtent];
159
160 const char
161 *p;
162
163 double
164 *sparse_arguments;
165
166 Image
167 *sparse_image;
168
169 PixelInfo
170 color;
171
172 MagickBooleanType
173 error;
174
175 register size_t
176 x;
177
178 size_t
179 number_arguments,
180 number_colors;
181
182 assert(image != (Image *) NULL);
183 assert(image->signature == MagickSignature);
184 if (image->debug != MagickFalse)
185 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
186 assert(exception != (ExceptionInfo *) NULL);
187 assert(exception->signature == MagickSignature);
188 /*
189 Limit channels according to image - and add up number of color channel.
190 */
191 number_colors=0;
192 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
193 number_colors++;
194 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
195 number_colors++;
196 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
197 number_colors++;
198 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
199 (image->colorspace == CMYKColorspace))
200 number_colors++;
201 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
202 (image->matte != MagickFalse))
203 number_colors++;
204
205 /*
206 Read string, to determine number of arguments needed,
207 */
208 p=arguments;
209 x=0;
210 while( *p != '\0' )
211 {
212 GetMagickToken(p,&p,token);
213 if ( token[0] == ',' ) continue;
214 if ( isalpha((int) token[0]) || token[0] == '#' ) {
215 if ( color_from_image ) {
216 (void) ThrowMagickException(exception,GetMagickModule(),
217 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
218 "Color arg given, when colors are coming from image");
219 return( (Image *)NULL);
220 }
221 x += number_colors; /* color argument */
222 }
223 else {
224 x++; /* floating point argument */
225 }
226 }
227 error=MagickTrue;
228 if ( color_from_image ) {
229 /* just the control points are being given */
230 error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse;
231 number_arguments=(x/2)*(2+number_colors);
232 }
233 else {
234 /* control points and color values */
235 error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
236 number_arguments=x;
237 }
238 if ( error ) {
239 (void) ThrowMagickException(exception,GetMagickModule(),
240 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
241 "Invalid number of Arguments");
242 return( (Image *)NULL);
243 }
244
245 /* Allocate and fill in the floating point arguments */
246 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
247 sizeof(*sparse_arguments));
248 if (sparse_arguments == (double *) NULL) {
249 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
250 "MemoryAllocationFailed","%s","SparseColorOption");
251 return( (Image *)NULL);
252 }
253 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
254 sizeof(*sparse_arguments));
255 p=arguments;
256 x=0;
257 while( *p != '\0' && x < number_arguments ) {
258 /* X coordinate */
259 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
260 if ( token[0] == '\0' ) break;
261 if ( isalpha((int) token[0]) || token[0] == '#' ) {
262 (void) ThrowMagickException(exception,GetMagickModule(),
263 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
264 "Color found, instead of X-coord");
265 error = MagickTrue;
266 break;
267 }
cristydbdd0e32011-11-04 23:29:40 +0000268 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000269 /* Y coordinate */
270 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
271 if ( token[0] == '\0' ) break;
272 if ( isalpha((int) token[0]) || token[0] == '#' ) {
273 (void) ThrowMagickException(exception,GetMagickModule(),
274 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
275 "Color found, instead of Y-coord");
276 error = MagickTrue;
277 break;
278 }
cristydbdd0e32011-11-04 23:29:40 +0000279 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000280 /* color values for this control point */
281#if 0
282 if ( (color_from_image ) {
283 /* get color from image */
284 /* HOW??? */
285 }
286 else
287#endif
288 {
289 /* color name or function given in string argument */
290 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
291 if ( token[0] == '\0' ) break;
292 if ( isalpha((int) token[0]) || token[0] == '#' ) {
293 /* Color string given */
cristy269c9412011-10-13 23:41:15 +0000294 (void) QueryColorCompliance(token,AllCompliance,&color,
anthonya89dd172011-10-04 13:29:35 +0000295 exception);
anthony805a2d42011-09-25 08:25:12 +0000296 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
297 sparse_arguments[x++] = QuantumScale*color.red;
298 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
299 sparse_arguments[x++] = QuantumScale*color.green;
300 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
301 sparse_arguments[x++] = QuantumScale*color.blue;
302 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
303 (image->colorspace == CMYKColorspace))
304 sparse_arguments[x++] = QuantumScale*color.black;
305 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
306 (image->matte != MagickFalse))
307 sparse_arguments[x++] = QuantumScale*color.alpha;
308 }
309 else {
310 /* Colors given as a set of floating point values - experimental */
311 /* NB: token contains the first floating point value to use! */
312 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
313 {
314 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
315 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
316 break;
cristydbdd0e32011-11-04 23:29:40 +0000317 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000318 token[0] = ','; /* used this token - get another */
319 }
320 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
321 {
322 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
323 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
324 break;
cristydbdd0e32011-11-04 23:29:40 +0000325 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000326 token[0] = ','; /* used this token - get another */
327 }
328 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
329 {
330 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
331 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
332 break;
cristydbdd0e32011-11-04 23:29:40 +0000333 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000334 token[0] = ','; /* used this token - get another */
335 }
336 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
337 (image->colorspace == CMYKColorspace))
338 {
339 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
340 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
341 break;
cristydbdd0e32011-11-04 23:29:40 +0000342 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000343 token[0] = ','; /* used this token - get another */
344 }
345 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
346 (image->matte != MagickFalse))
347 {
348 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
349 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
350 break;
cristydbdd0e32011-11-04 23:29:40 +0000351 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000352 token[0] = ','; /* used this token - get another */
353 }
354 }
355 }
356 }
357 if ( number_arguments != x && !error ) {
358 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
359 "InvalidArgument","`%s': %s","sparse-color","Argument Parsing Error");
360 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
361 return( (Image *)NULL);
362 }
363 if ( error )
364 return( (Image *)NULL);
365
366 /* Call the Interpolation function with the parsed arguments */
367 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
368 exception);
369 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
370 return( sparse_image );
371}
372
373/*
374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375% %
376% %
377% %
anthony1afdc7a2011-10-05 11:54:28 +0000378+ A p p l y S e t t i n g O p t i o n %
anthony805a2d42011-09-25 08:25:12 +0000379% %
380% %
381% %
382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
383%
anthonydcf510d2011-10-30 13:51:40 +0000384% ApplySettingOption() applies a single settings option into a CLI wand
385% holding the image_info, draw_info, quantize_info structures that will be
386% later used when processing images.
anthony805a2d42011-09-25 08:25:12 +0000387%
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)
cristy9b34e302011-11-05 02:15:45 +0000560 limit=(MagickSizeType) SiPrefixToDoubleInterval(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 {
cristy9b34e302011-11-05 02:15:45 +0000567 (void) SetImageOption(image_info,option,IfSetOption ? arg :
568 (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 {
cristy9b34e302011-11-05 02:15:45 +0000835 image_info->fuzz=StringToDoubleInterval(arg,(double) QuantumRange+
836 1.0);
anthonydcf510d2011-10-30 13:51:40 +0000837 (void) SetImageOption(image_info,option,arg);
cristy947cb4c2011-10-20 18:41:46 +0000838 break;
839 }
840 image_info->fuzz=0.0;
841 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +0000842 break;
843 }
844 break;
845 }
846 case 'g':
847 {
anthony74b1cfc2011-10-06 12:44:16 +0000848 if (LocaleCompare("gravity",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000849 {
anthonydcf510d2011-10-30 13:51:40 +0000850 /* FUTURE gravity also set in image via SyncImageSettings() */
851 const char
852 value;
853
854 value = IfSetOption ? arg : "none";
855 (void) SetImageOption(image_info,option,value);
anthony6dc09cd2011-10-12 08:56:49 +0000856 draw_info->gravity=(GravityType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +0000857 MagickGravityOptions,MagickFalse,value);
anthony805a2d42011-09-25 08:25:12 +0000858 break;
859 }
anthony74b1cfc2011-10-06 12:44:16 +0000860 if (LocaleCompare("green-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000861 {
anthonydcf510d2011-10-30 13:51:40 +0000862 /* Image chromaticity X,Y NB: Y=X if Y not defined
863 Used by many coders
864 */
865 (void) SetImageOption(image_info,option,
866 IfSetOption ? arg : "0.0");
anthony805a2d42011-09-25 08:25:12 +0000867 break;
868 }
869 break;
870 }
871 case 'i':
872 {
anthony74b1cfc2011-10-06 12:44:16 +0000873 if (LocaleCompare("intent",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000874 {
anthonydcf510d2011-10-30 13:51:40 +0000875 /* FUTURE: sets image->rendering_intent in SyncImagesSettings
876 Which is only used by coders: MIFF, MPC, BMP, PNG
877 and for image profile call to AcquireTransformThreadSet()
878 */
879 (void) SetImageOption(image_info,option,
880 IfSetOption ? arg : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000881 break;
882 }
anthony74b1cfc2011-10-06 12:44:16 +0000883 if (LocaleCompare("interlace",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000884 {
anthonydcf510d2011-10-30 13:51:40 +0000885 /* sets image attibute interlace via SyncImageSettings()
886 Also image_info is directly used by coders
887 */
888 const char
889 value;
890
891 value = IfSetOption ? arg : "undefined";
892 (void) SetImageOption(image_info,option, value);
anthony805a2d42011-09-25 08:25:12 +0000893 image_info->interlace=(InterlaceType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +0000894 MagickInterlaceOptions,MagickFalse,arg);
895 (void) SetImageOption(image_info,option,arg);
anthony805a2d42011-09-25 08:25:12 +0000896 break;
897 }
anthony74b1cfc2011-10-06 12:44:16 +0000898 if (LocaleCompare("interline-spacing",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000899 {
anthonydcf510d2011-10-30 13:51:40 +0000900 const char
901 value;
902
903 value = IfSetOption ? arg : "0"; /* undefined? */
904 (void) SetImageOption(image_info,option, value);
cristy9b34e302011-11-05 02:15:45 +0000905 draw_info->interline_spacing=StringToDouble(value,(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);
cristy9b34e302011-11-05 02:15:45 +0000925 draw_info->interword_spacing=StringToDouble(value,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000926 break;
927 }
928 break;
929 }
930 case 'k':
931 {
anthony74b1cfc2011-10-06 12:44:16 +0000932 if (LocaleCompare("kerning",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000933 {
anthonydcf510d2011-10-30 13:51:40 +0000934 const char
935 value;
936
937 value = IfSetOption ? arg : "0"; /* undefined? */
938 (void) SetImageOption(image_info,option, value);
cristydbdd0e32011-11-04 23:29:40 +0000939 draw_info->kerning=StringToDouble(value,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000940 break;
941 }
942 break;
943 }
944 case 'l':
945 {
anthony74b1cfc2011-10-06 12:44:16 +0000946 if (LocaleCompare("label",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000947 {
anthonydcf510d2011-10-30 13:51:40 +0000948 /* only used for new images */
949 (void) SetImageOption(image_info,option,
950 IfSetOption ? arg : (char *)NULL);
anthony805a2d42011-09-25 08:25:12 +0000951 break;
952 }
anthony74b1cfc2011-10-06 12:44:16 +0000953 if (LocaleCompare("limit",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000954 {
955 MagickSizeType
956 limit;
957
958 ResourceType
959 type;
960
anthonydcf510d2011-10-30 13:51:40 +0000961 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000962 break;
963 type=(ResourceType) ParseCommandOption(MagickResourceOptions,
anthonydcf510d2011-10-30 13:51:40 +0000964 MagickFalse,arg);
anthony805a2d42011-09-25 08:25:12 +0000965 limit=MagickResourceInfinity;
966 if (LocaleCompare("unlimited",argv[2]) != 0)
cristy9b34e302011-11-05 02:15:45 +0000967 limit=(MagickSizeType) SiPrefixToDoubleInterval(argv[2],
968 100.0);
anthony805a2d42011-09-25 08:25:12 +0000969 (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)
cristydbdd0e32011-11-04 23:29:40 +00001184 StringToDouble(arg,(char **) NULL);
anthonydcf510d2011-10-30 13:51:40 +00001185 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);
cristydbdd0e32011-11-04 23:29:40 +00001337 draw_info->stroke_width=StringToDouble(value,(char **) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001338 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
cristy9b34e302011-11-05 02:15:45 +00002118 threshold=StringToDoubleInterval(args[0],(double) QuantumRange+1.0);
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);
cristydbdd0e32011-11-04 23:29:40 +00002203 arguments[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002204 }
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]);
cristy9b34e302011-11-05 02:15:45 +00002279 constant=StringToDoubleInterval(argv[2],(double) QuantumRange+1.0);
anthony805a2d42011-09-25 08:25:12 +00002280 (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);
cristydbdd0e32011-11-04 23:29:40 +00002421 parameters[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002422 }
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] == '+')
cristydbdd0e32011-11-04 23:29:40 +00002437 (*image)->gamma=StringToDouble(args[0],(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002438 else
cristydbdd0e32011-11-04 23:29:40 +00002439 (void) GammaImage(*image,StringToDouble(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 {
cristydbdd0e32011-11-04 23:29:40 +00002681 draw_info->stroke_width=StringToDouble(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 {
cristye9e3d382011-12-14 01:50:13 +00002938 const char
2939 *caption;
2940
anthony805a2d42011-09-25 08:25:12 +00002941 double
2942 angle;
2943
2944 RandomInfo
2945 *random_info;
2946
cristy947cb4c2011-10-20 18:41:46 +00002947 /*
2948 Simulate a Polaroid picture.
2949 */
cristy6fccee12011-10-20 18:43:18 +00002950 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002951 random_info=AcquireRandomInfo();
2952 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2953 random_info=DestroyRandomInfo(random_info);
2954 if (*argv[0] == '-')
2955 {
2956 SetGeometryInfo(&geometry_info);
anthonydcf510d2011-10-30 13:51:40 +00002957 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002958 angle=geometry_info.rho;
2959 }
cristye9e3d382011-12-14 01:50:13 +00002960 caption=GetImageProperty(*image,"caption",exception);
2961 new_image=PolaroidImage(*image,draw_info,caption,angle,
anthony805a2d42011-09-25 08:25:12 +00002962 interpolate_method,exception);
2963 break;
2964 }
anthonydcf510d2011-10-30 13:51:40 +00002965 if (LocaleCompare("posterize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002966 {
cristy947cb4c2011-10-20 18:41:46 +00002967 /*
2968 Posterize image.
2969 */
cristy6fccee12011-10-20 18:43:18 +00002970 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00002971 (void) PosterizeImage(*image,StringToUnsignedLong(args[0]),
anthony805a2d42011-09-25 08:25:12 +00002972 quantize_info->dither,exception);
2973 break;
2974 }
anthonydcf510d2011-10-30 13:51:40 +00002975 if (LocaleCompare("preview",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002976 {
2977 PreviewType
cristy947cb4c2011-10-20 18:41:46 +00002978 preview_type;
anthony170fce92011-10-20 11:50:23 +00002979
cristy947cb4c2011-10-20 18:41:46 +00002980 /*
2981 Preview image.
2982 */
cristy6fccee12011-10-20 18:43:18 +00002983 (void) SyncImageSettings(image_info,*image,exception);
cristy947cb4c2011-10-20 18:41:46 +00002984 if (*argv[0] == '+')
2985 preview_type=UndefinedPreview;
2986 else
anthony805a2d42011-09-25 08:25:12 +00002987 preview_type=(PreviewType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00002988 MagickPreviewOptions,MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00002989 new_image=PreviewImage(*image,preview_type,exception);
2990 break;
2991 }
anthonydcf510d2011-10-30 13:51:40 +00002992 if (LocaleCompare("profile",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00002993 {
2994 const char
2995 *name;
2996
2997 const StringInfo
2998 *profile;
2999
3000 Image
3001 *profile_image;
3002
3003 ImageInfo
3004 *profile_info;
3005
cristy6fccee12011-10-20 18:43:18 +00003006 (void) SyncImageSettings(image_info,*image,exception);
cristy947cb4c2011-10-20 18:41:46 +00003007 if (*argv[0] == '+')
anthony805a2d42011-09-25 08:25:12 +00003008 {
cristy947cb4c2011-10-20 18:41:46 +00003009 /*
3010 Remove a profile from the image.
3011 */
anthonydcf510d2011-10-30 13:51:40 +00003012 (void) ProfileImage(*image,args[0],(const unsigned char *)
cristy092d71c2011-10-14 18:01:29 +00003013 NULL,0,exception);
anthony805a2d42011-09-25 08:25:12 +00003014 break;
3015 }
cristy947cb4c2011-10-20 18:41:46 +00003016 /*
3017 Associate a profile with the image.
3018 */
anthony805a2d42011-09-25 08:25:12 +00003019 profile_info=CloneImageInfo(image_info);
3020 profile=GetImageProfile(*image,"iptc");
3021 if (profile != (StringInfo *) NULL)
3022 profile_info->profile=(void *) CloneStringInfo(profile);
anthonydcf510d2011-10-30 13:51:40 +00003023 profile_image=GetImageCache(profile_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003024 profile_info=DestroyImageInfo(profile_info);
3025 if (profile_image == (Image *) NULL)
3026 {
3027 StringInfo
3028 *profile;
3029
3030 profile_info=CloneImageInfo(image_info);
anthonydcf510d2011-10-30 13:51:40 +00003031 (void) CopyMagickString(profile_info->filename,args[0],
anthony805a2d42011-09-25 08:25:12 +00003032 MaxTextExtent);
3033 profile=FileToStringInfo(profile_info->filename,~0UL,exception);
3034 if (profile != (StringInfo *) NULL)
3035 {
3036 (void) ProfileImage(*image,profile_info->magick,
3037 GetStringInfoDatum(profile),(size_t)
cristy092d71c2011-10-14 18:01:29 +00003038 GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003039 profile=DestroyStringInfo(profile);
3040 }
3041 profile_info=DestroyImageInfo(profile_info);
3042 break;
3043 }
3044 ResetImageProfileIterator(profile_image);
3045 name=GetNextImageProfile(profile_image);
3046 while (name != (const char *) NULL)
3047 {
3048 profile=GetImageProfile(profile_image,name);
3049 if (profile != (StringInfo *) NULL)
3050 (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
cristy092d71c2011-10-14 18:01:29 +00003051 (size_t) GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003052 name=GetNextImageProfile(profile_image);
3053 }
3054 profile_image=DestroyImage(profile_image);
3055 break;
3056 }
3057 break;
3058 }
cristy947cb4c2011-10-20 18:41:46 +00003059 case 'q':
3060 {
anthonydcf510d2011-10-30 13:51:40 +00003061 if (LocaleCompare("quantize",option) == 0)
cristy947cb4c2011-10-20 18:41:46 +00003062 {
3063 if (*argv[0] == '+')
3064 {
3065 quantize_info->colorspace=UndefinedColorspace;
3066 break;
3067 }
3068 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00003069 MagickColorspaceOptions,MagickFalse,args[0]);
cristy947cb4c2011-10-20 18:41:46 +00003070 break;
3071 }
3072 break;
3073 }
anthony805a2d42011-09-25 08:25:12 +00003074 case 'r':
3075 {
anthonydcf510d2011-10-30 13:51:40 +00003076 if (LocaleCompare("radial-blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003077 {
cristy6fccee12011-10-20 18:43:18 +00003078 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003079 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003080 new_image=RadialBlurImage(*image,geometry_info.rho,
3081 geometry_info.sigma,exception);
3082 break;
3083 }
anthonydcf510d2011-10-30 13:51:40 +00003084 if (LocaleCompare("raise",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003085 {
anthonydcf510d2011-10-30 13:51:40 +00003086 flags=ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003087 if ((flags & SigmaValue) == 0)
3088 geometry.height=geometry.width;
3089 (void) RaiseImage(*image,&geometry,*argv[0] == '-' ? MagickTrue :
3090 MagickFalse,exception);
3091 break;
3092 }
anthonydcf510d2011-10-30 13:51:40 +00003093 if (LocaleCompare("random-threshold",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003094 {
cristy6fccee12011-10-20 18:43:18 +00003095 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003096 (void) RandomThresholdImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003097 break;
3098 }
anthonydcf510d2011-10-30 13:51:40 +00003099 if (LocaleCompare("recolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003100 {
3101 KernelInfo
3102 *kernel;
3103
cristy6fccee12011-10-20 18:43:18 +00003104 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003105 kernel=AcquireKernelInfo(args[0]);
anthony805a2d42011-09-25 08:25:12 +00003106 if (kernel == (KernelInfo *) NULL)
3107 break;
3108 new_image=ColorMatrixImage(*image,kernel,exception);
3109 kernel=DestroyKernelInfo(kernel);
3110 break;
3111 }
anthonydcf510d2011-10-30 13:51:40 +00003112 if (LocaleCompare("remap",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003113 {
3114 Image
3115 *remap_image;
3116
cristy6fccee12011-10-20 18:43:18 +00003117 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003118 if (*argv[0] == '+')
3119 break;
anthonydcf510d2011-10-30 13:51:40 +00003120 remap_image=GetImageCache(image_info,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003121 if (remap_image == (Image *) NULL)
3122 break;
3123 (void) RemapImage(quantize_info,*image,remap_image,exception);
3124 remap_image=DestroyImage(remap_image);
3125 break;
3126 }
anthonydcf510d2011-10-30 13:51:40 +00003127 if (LocaleCompare("repage",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003128 {
3129 if (*argv[0] == '+')
3130 {
3131 (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
3132 break;
3133 }
anthonydcf510d2011-10-30 13:51:40 +00003134 (void) ResetImagePage(*image,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003135 break;
3136 }
anthonydcf510d2011-10-30 13:51:40 +00003137 if (LocaleCompare("resample",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003138 {
anthonyafbaed72011-10-26 12:05:04 +00003139 /* FUTURE: remove blur - no longer used */
cristy6fccee12011-10-20 18:43:18 +00003140 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003141 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003142 if ((flags & SigmaValue) == 0)
3143 geometry_info.sigma=geometry_info.rho;
3144 new_image=ResampleImage(*image,geometry_info.rho,
3145 geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
3146 break;
3147 }
anthonydcf510d2011-10-30 13:51:40 +00003148 if (LocaleCompare("resize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003149 {
anthonyafbaed72011-10-26 12:05:04 +00003150 /* FUTURE: remove blur argument - no longer used */
cristy6fccee12011-10-20 18:43:18 +00003151 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003152 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003153 new_image=ResizeImage(*image,geometry.width,geometry.height,
3154 (*image)->filter,(*image)->blur,exception);
3155 break;
3156 }
anthonydcf510d2011-10-30 13:51:40 +00003157 if (LocaleCompare("roll",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003158 {
cristy6fccee12011-10-20 18:43:18 +00003159 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003160 (void) ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003161 new_image=RollImage(*image,geometry.x,geometry.y,exception);
3162 break;
3163 }
anthonydcf510d2011-10-30 13:51:40 +00003164 if (LocaleCompare("rotate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003165 {
anthonyafbaed72011-10-26 12:05:04 +00003166 /* special case rotation flags */
cristy6fccee12011-10-20 18:43:18 +00003167 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003168 if (strchr(args[0],'>') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00003169 if ((*image)->columns <= (*image)->rows)
3170 break;
anthonydcf510d2011-10-30 13:51:40 +00003171 if (strchr(args[0],'<') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00003172 if ((*image)->columns >= (*image)->rows)
3173 break;
anthonyafbaed72011-10-26 12:05:04 +00003174
anthonydcf510d2011-10-30 13:51:40 +00003175 (void) ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003176 new_image=RotateImage(*image,geometry_info.rho,exception);
3177 break;
3178 }
3179 break;
3180 }
3181 case 's':
3182 {
anthonydcf510d2011-10-30 13:51:40 +00003183 if (LocaleCompare("sample",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003184 {
cristy6fccee12011-10-20 18:43:18 +00003185 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003186 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003187 new_image=SampleImage(*image,geometry.width,geometry.height,
3188 exception);
3189 break;
3190 }
anthonydcf510d2011-10-30 13:51:40 +00003191 if (LocaleCompare("scale",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003192 {
cristy6fccee12011-10-20 18:43:18 +00003193 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003194 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003195 new_image=ScaleImage(*image,geometry.width,geometry.height,
3196 exception);
3197 break;
3198 }
anthonydcf510d2011-10-30 13:51:40 +00003199 if (LocaleCompare("selective-blur",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003200 {
cristy6fccee12011-10-20 18:43:18 +00003201 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003202 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003203 if ((flags & PercentValue) != 0)
3204 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3205 new_image=SelectiveBlurImage(*image,geometry_info.rho,
3206 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3207 break;
3208 }
anthonydcf510d2011-10-30 13:51:40 +00003209 if (LocaleCompare("separate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003210 {
3211 /*
3212 Break channels into separate images.
3213 WARNING: This can generate multiple images!
3214 */
cristy6fccee12011-10-20 18:43:18 +00003215 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003216 new_image=SeparateImages(*image,exception);
3217 break;
3218 }
anthonydcf510d2011-10-30 13:51:40 +00003219 if (LocaleCompare("sepia-tone",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003220 {
3221 double
3222 threshold;
3223
cristy6fccee12011-10-20 18:43:18 +00003224 (void) SyncImageSettings(image_info,*image,exception);
cristy9b34e302011-11-05 02:15:45 +00003225 threshold=StringToDoubleInterval(args[0],(double) QuantumRange+1.0);
anthony805a2d42011-09-25 08:25:12 +00003226 new_image=SepiaToneImage(*image,threshold,exception);
3227 break;
3228 }
anthonydcf510d2011-10-30 13:51:40 +00003229 if (LocaleCompare("segment",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003230 {
cristy6fccee12011-10-20 18:43:18 +00003231 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003232 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003233 if ((flags & SigmaValue) == 0)
3234 geometry_info.sigma=1.0;
3235 (void) SegmentImage(*image,(*image)->colorspace,
3236 image_info->verbose,geometry_info.rho,geometry_info.sigma,
3237 exception);
3238 break;
3239 }
anthonydcf510d2011-10-30 13:51:40 +00003240 if (LocaleCompare("set",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003241 {
3242 char
3243 *value;
3244
anthony805a2d42011-09-25 08:25:12 +00003245 if (*argv[0] == '+')
3246 {
anthonydcf510d2011-10-30 13:51:40 +00003247 if (LocaleNCompare(args[0],"registry:",9) == 0)
3248 (void) DeleteImageRegistry(args[0]+9);
anthony805a2d42011-09-25 08:25:12 +00003249 else
anthonydcf510d2011-10-30 13:51:40 +00003250 if (LocaleNCompare(args[0],"argv[0]:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003251 {
anthonydcf510d2011-10-30 13:51:40 +00003252 (void) DeleteImageOption(image_info,args[0]+7);
3253 (void) DeleteImageArtifact(*image,args[0]+7);
anthony805a2d42011-09-25 08:25:12 +00003254 }
3255 else
anthonydcf510d2011-10-30 13:51:40 +00003256 (void) DeleteImageProperty(*image,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003257 break;
3258 }
3259 value=InterpretImageProperties(image_info,*image,argv[2],
3260 exception);
3261 if (value == (char *) NULL)
3262 break;
anthonydcf510d2011-10-30 13:51:40 +00003263 if (LocaleNCompare(args[0],"registry:",9) == 0)
3264 (void) SetImageRegistry(StringRegistryType,args[0]+9,value,
anthony805a2d42011-09-25 08:25:12 +00003265 exception);
3266 else
anthonydcf510d2011-10-30 13:51:40 +00003267 if (LocaleNCompare(args[0],"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003268 {
anthonydcf510d2011-10-30 13:51:40 +00003269 (void) SetImageOption(image_info,args[0]+7,value);
3270 (void) SetImageArtifact(*image,args[0]+7,value);
anthony805a2d42011-09-25 08:25:12 +00003271 }
3272 else
anthonydcf510d2011-10-30 13:51:40 +00003273 (void) SetImageProperty(*image,args[0],value,exception);
anthony805a2d42011-09-25 08:25:12 +00003274 value=DestroyString(value);
3275 break;
3276 }
anthonydcf510d2011-10-30 13:51:40 +00003277 if (LocaleCompare("shade",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003278 {
cristy6fccee12011-10-20 18:43:18 +00003279 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003280 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003281 if ((flags & SigmaValue) == 0)
3282 geometry_info.sigma=1.0;
3283 new_image=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue :
3284 MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
3285 break;
3286 }
anthonydcf510d2011-10-30 13:51:40 +00003287 if (LocaleCompare("shadow",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003288 {
cristy6fccee12011-10-20 18:43:18 +00003289 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003290 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003291 if ((flags & SigmaValue) == 0)
3292 geometry_info.sigma=1.0;
3293 if ((flags & XiValue) == 0)
3294 geometry_info.xi=4.0;
3295 if ((flags & PsiValue) == 0)
3296 geometry_info.psi=4.0;
3297 new_image=ShadowImage(*image,geometry_info.rho,
cristyeb6e6582011-12-09 09:14:23 +00003298 geometry_info.sigma,(*image)->bias,(ssize_t)
3299 ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5),
3300 exception);
anthony805a2d42011-09-25 08:25:12 +00003301 break;
3302 }
anthonydcf510d2011-10-30 13:51:40 +00003303 if (LocaleCompare("sharpen",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003304 {
cristy6fccee12011-10-20 18:43:18 +00003305 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003306 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003307 if ((flags & SigmaValue) == 0)
3308 geometry_info.sigma=1.0;
3309 if ((flags & XiValue) == 0)
3310 geometry_info.xi=0.0;
3311 new_image=SharpenImage(*image,geometry_info.rho,
3312 geometry_info.sigma,geometry_info.xi,exception);
3313 break;
3314 }
anthonydcf510d2011-10-30 13:51:40 +00003315 if (LocaleCompare("shave",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003316 {
cristy6fccee12011-10-20 18:43:18 +00003317 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003318 flags=ParsePageGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003319 new_image=ShaveImage(*image,&geometry,exception);
3320 break;
3321 }
anthonydcf510d2011-10-30 13:51:40 +00003322 if (LocaleCompare("shear",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003323 {
cristy6fccee12011-10-20 18:43:18 +00003324 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003325 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003326 if ((flags & SigmaValue) == 0)
3327 geometry_info.sigma=geometry_info.rho;
3328 new_image=ShearImage(*image,geometry_info.rho,
3329 geometry_info.sigma,exception);
3330 break;
3331 }
anthonydcf510d2011-10-30 13:51:40 +00003332 if (LocaleCompare("sigmoidal-contrast",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003333 {
cristy6fccee12011-10-20 18:43:18 +00003334 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003335 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003336 if ((flags & SigmaValue) == 0)
3337 geometry_info.sigma=(double) QuantumRange/2.0;
3338 if ((flags & PercentValue) != 0)
3339 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3340 100.0;
3341 (void) SigmoidalContrastImage(*image,(*argv[0] == '-') ?
3342 MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
3343 exception);
3344 break;
3345 }
anthonydcf510d2011-10-30 13:51:40 +00003346 if (LocaleCompare("sketch",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003347 {
cristy6fccee12011-10-20 18:43:18 +00003348 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003349 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003350 if ((flags & SigmaValue) == 0)
3351 geometry_info.sigma=1.0;
3352 new_image=SketchImage(*image,geometry_info.rho,
3353 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3354 break;
3355 }
anthonydcf510d2011-10-30 13:51:40 +00003356 if (LocaleCompare("solarize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003357 {
3358 double
3359 threshold;
3360
cristy6fccee12011-10-20 18:43:18 +00003361 (void) SyncImageSettings(image_info,*image,exception);
cristy9b34e302011-11-05 02:15:45 +00003362 threshold=StringToDoubleInterval(args[0],(double) QuantumRange+1.0);
anthony805a2d42011-09-25 08:25:12 +00003363 (void) SolarizeImage(*image,threshold,exception);
3364 break;
3365 }
anthonydcf510d2011-10-30 13:51:40 +00003366 if (LocaleCompare("sparse-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003367 {
3368 SparseColorMethod
3369 method;
3370
3371 char
3372 *arguments;
3373
cristy6fccee12011-10-20 18:43:18 +00003374 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003375 method=(SparseColorMethod) ParseCommandOption(
anthonydcf510d2011-10-30 13:51:40 +00003376 MagickSparseColorOptions,MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003377 arguments=InterpretImageProperties(image_info,*image,argv[2],
3378 exception);
3379 if (arguments == (char *) NULL)
3380 break;
3381 new_image=SparseColorOption(*image,method,arguments,
3382 argv[0][0] == '+' ? MagickTrue : MagickFalse,exception);
3383 arguments=DestroyString(arguments);
3384 break;
3385 }
anthonydcf510d2011-10-30 13:51:40 +00003386 if (LocaleCompare("splice",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003387 {
cristy6fccee12011-10-20 18:43:18 +00003388 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003389 (void) ParseGravityGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003390 new_image=SpliceImage(*image,&geometry,exception);
3391 break;
3392 }
anthonydcf510d2011-10-30 13:51:40 +00003393 if (LocaleCompare("spread",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003394 {
cristy6fccee12011-10-20 18:43:18 +00003395 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003396 (void) ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003397 new_image=SpreadImage(*image,geometry_info.rho,
3398 interpolate_method,exception);
3399 break;
3400 }
anthonydcf510d2011-10-30 13:51:40 +00003401 if (LocaleCompare("statistic",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003402 {
3403 StatisticType
3404 type;
3405
cristy6fccee12011-10-20 18:43:18 +00003406 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003407 type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
anthonydcf510d2011-10-30 13:51:40 +00003408 MagickFalse,args[0]);
anthony805a2d42011-09-25 08:25:12 +00003409 (void) ParseGeometry(argv[2],&geometry_info);
3410 new_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
3411 (size_t) geometry_info.sigma,exception);
3412 break;
3413 }
anthonydcf510d2011-10-30 13:51:40 +00003414 if (LocaleCompare("strip",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003415 {
cristy6fccee12011-10-20 18:43:18 +00003416 (void) SyncImageSettings(image_info,*image,exception);
anthony6613bf32011-10-15 07:24:44 +00003417 (void) StripImage(*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003418 break;
3419 }
anthonydcf510d2011-10-30 13:51:40 +00003420 if (LocaleCompare("swirl",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003421 {
cristy6fccee12011-10-20 18:43:18 +00003422 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003423 (void) ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003424 new_image=SwirlImage(*image,geometry_info.rho,
3425 interpolate_method,exception);
3426 break;
3427 }
3428 break;
3429 }
3430 case 't':
3431 {
anthonydcf510d2011-10-30 13:51:40 +00003432 if (LocaleCompare("threshold",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003433 {
3434 double
3435 threshold;
3436
cristy6fccee12011-10-20 18:43:18 +00003437 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003438 if (*argv[0] == '+')
3439 threshold=(double) QuantumRange/2;
3440 else
cristy9b34e302011-11-05 02:15:45 +00003441 threshold=StringToDoubleInterval(args[0],(double) QuantumRange+1.0);
anthony6613bf32011-10-15 07:24:44 +00003442 (void) BilevelImage(*image,threshold,exception);
anthony805a2d42011-09-25 08:25:12 +00003443 break;
3444 }
anthonydcf510d2011-10-30 13:51:40 +00003445 if (LocaleCompare("thumbnail",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003446 {
3447 /*
3448 Thumbnail image.
3449 */
cristy6fccee12011-10-20 18:43:18 +00003450 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003451 (void) ParseRegionGeometry(*image,args[0],&geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003452 new_image=ThumbnailImage(*image,geometry.width,geometry.height,
3453 exception);
3454 break;
3455 }
anthonydcf510d2011-10-30 13:51:40 +00003456 if (LocaleCompare("tint",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003457 {
cristy6fccee12011-10-20 18:43:18 +00003458 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003459 new_image=TintImage(*image,args[0],&fill,exception);
anthony805a2d42011-09-25 08:25:12 +00003460 break;
3461 }
anthonydcf510d2011-10-30 13:51:40 +00003462 if (LocaleCompare("transform",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003463 {
cristy6fccee12011-10-20 18:43:18 +00003464 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003465 new_image=AffineTransformImage(*image,&draw_info->affine,
3466 exception);
3467 break;
3468 }
anthonydcf510d2011-10-30 13:51:40 +00003469 if (LocaleCompare("transparent",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003470 {
3471 PixelInfo
3472 target;
3473
cristy6fccee12011-10-20 18:43:18 +00003474 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003475 (void) QueryColorCompliance(args[0],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00003476 exception);
anthony805a2d42011-09-25 08:25:12 +00003477 (void) TransparentPaintImage(*image,&target,(Quantum)
3478 TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue,
cristy82d7af52011-10-16 16:26:41 +00003479 exception);
anthony805a2d42011-09-25 08:25:12 +00003480 break;
3481 }
anthonydcf510d2011-10-30 13:51:40 +00003482 if (LocaleCompare("transpose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003483 {
cristy6fccee12011-10-20 18:43:18 +00003484 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003485 new_image=TransposeImage(*image,exception);
3486 break;
3487 }
anthonydcf510d2011-10-30 13:51:40 +00003488 if (LocaleCompare("transverse",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003489 {
cristy6fccee12011-10-20 18:43:18 +00003490 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003491 new_image=TransverseImage(*image,exception);
3492 break;
3493 }
anthonydcf510d2011-10-30 13:51:40 +00003494 if (LocaleCompare("treedepth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003495 {
anthonydcf510d2011-10-30 13:51:40 +00003496 quantize_info->tree_depth=StringToUnsignedLong(args[0]);
anthony805a2d42011-09-25 08:25:12 +00003497 break;
3498 }
anthonydcf510d2011-10-30 13:51:40 +00003499 if (LocaleCompare("trim",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003500 {
cristy6fccee12011-10-20 18:43:18 +00003501 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003502 new_image=TrimImage(*image,exception);
3503 break;
3504 }
anthonydcf510d2011-10-30 13:51:40 +00003505 if (LocaleCompare("type",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003506 {
anthonyab3a50c2011-10-27 11:48:57 +00003507 /* Note that "type" setting should have already been defined */
cristy6fccee12011-10-20 18:43:18 +00003508 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003509 (void) SetImageType(*image,type,exception);
3510 break;
3511 }
3512 break;
3513 }
3514 case 'u':
3515 {
anthonydcf510d2011-10-30 13:51:40 +00003516 if (LocaleCompare("unique",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003517 {
3518 if (*argv[0] == '+')
3519 {
3520 (void) DeleteImageArtifact(*image,"identify:unique-colors");
3521 break;
3522 }
3523 (void) SetImageArtifact(*image,"identify:unique-colors","true");
3524 (void) SetImageArtifact(*image,"verbose","true");
3525 break;
3526 }
anthonydcf510d2011-10-30 13:51:40 +00003527 if (LocaleCompare("unique-colors",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003528 {
cristy6fccee12011-10-20 18:43:18 +00003529 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003530 new_image=UniqueImageColors(*image,exception);
3531 break;
3532 }
anthonydcf510d2011-10-30 13:51:40 +00003533 if (LocaleCompare("unsharp",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003534 {
cristy6fccee12011-10-20 18:43:18 +00003535 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003536 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003537 if ((flags & SigmaValue) == 0)
3538 geometry_info.sigma=1.0;
3539 if ((flags & XiValue) == 0)
3540 geometry_info.xi=1.0;
3541 if ((flags & PsiValue) == 0)
3542 geometry_info.psi=0.05;
3543 new_image=UnsharpMaskImage(*image,geometry_info.rho,
3544 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3545 break;
3546 }
3547 break;
3548 }
3549 case 'v':
3550 {
anthonydcf510d2011-10-30 13:51:40 +00003551 if (LocaleCompare("verbose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003552 {
anthonydcf510d2011-10-30 13:51:40 +00003553 (void) SetImageArtifact(*image,option,
anthonyab3a50c2011-10-27 11:48:57 +00003554 *argv[0] == '+' ? "false" : "true");
anthony805a2d42011-09-25 08:25:12 +00003555 break;
3556 }
anthonydcf510d2011-10-30 13:51:40 +00003557 if (LocaleCompare("vignette",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003558 {
3559 /*
3560 Vignette image.
3561 */
cristy6fccee12011-10-20 18:43:18 +00003562 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003563 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003564 if ((flags & SigmaValue) == 0)
3565 geometry_info.sigma=1.0;
3566 if ((flags & XiValue) == 0)
3567 geometry_info.xi=0.1*(*image)->columns;
3568 if ((flags & PsiValue) == 0)
3569 geometry_info.psi=0.1*(*image)->rows;
3570 new_image=VignetteImage(*image,geometry_info.rho,
cristyeb6e6582011-12-09 09:14:23 +00003571 geometry_info.sigma,(*image)->bias,(ssize_t)
3572 ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5),
3573 exception);
anthony805a2d42011-09-25 08:25:12 +00003574 break;
3575 }
anthonydcf510d2011-10-30 13:51:40 +00003576 if (LocaleCompare("virtual-pixel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003577 {
anthonyab3a50c2011-10-27 11:48:57 +00003578 /* setting already defined in image_info structure */
3579 SetImageVirtualPixelMethod(*image, image_info->virtual_pixel_method);
anthony805a2d42011-09-25 08:25:12 +00003580 break;
3581 }
3582 break;
3583 }
3584 case 'w':
3585 {
anthonydcf510d2011-10-30 13:51:40 +00003586 if (LocaleCompare("wave",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003587 {
cristy6fccee12011-10-20 18:43:18 +00003588 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003589 flags=ParseGeometry(args[0],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003590 if ((flags & SigmaValue) == 0)
3591 geometry_info.sigma=1.0;
3592 new_image=WaveImage(*image,geometry_info.rho,
anthonya89dd172011-10-04 13:29:35 +00003593 geometry_info.sigma,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003594 break;
3595 }
anthonydcf510d2011-10-30 13:51:40 +00003596 if (LocaleCompare("white-threshold",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00003597 {
cristy6fccee12011-10-20 18:43:18 +00003598 (void) SyncImageSettings(image_info,*image,exception);
anthonydcf510d2011-10-30 13:51:40 +00003599 (void) WhiteThresholdImage(*image,args[0],exception);
anthony805a2d42011-09-25 08:25:12 +00003600 break;
3601 }
3602 break;
3603 }
3604 default:
3605 break;
3606 }
3607 /*
3608 Replace current image with any image that was generated
3609 */
3610 if (new_image != (Image *) NULL)
3611 ReplaceImageInListReturnLast(image,new_image);
3612
3613 /*
3614 Free resources.
3615 */
3616 quantize_info=DestroyQuantizeInfo(quantize_info);
3617 draw_info=DestroyDrawInfo(draw_info);
cristy82d7af52011-10-16 16:26:41 +00003618 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthonya89dd172011-10-04 13:29:35 +00003619 return(status == 0 ? MagickFalse : MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003620}
3621
3622/*
3623%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3624% %
3625% %
3626% %
3627+ S e q u e n c e O p e r a t i o n I m a g e s %
3628% %
3629% %
3630% %
3631%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3632%
3633% SequenceOperationImages() applies a single operation that apply to the
3634% entire image list (e.g. -append, -layers, -coalesce, etc.).
3635%
3636% The format of the MogrifyImage method is:
3637%
3638% MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3639% const int argc, const char **argv,Image **images,
3640% ExceptionInfo *exception)
3641%
3642% A description of each parameter follows:
3643%
3644% o image_info: the image info..
3645%
3646% o argc: Specifies a pointer to an integer describing the number of
3647% elements in the argument vector.
3648%
3649% o argv: Specifies a pointer to a text array containing the command line
3650% arguments.
3651%
3652% o images: pointer to pointer of the first image in image list.
3653%
3654% o exception: return any errors or warnings in this structure.
3655%
3656*/
3657WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3658 const int argc,const char **argv,Image **images,ExceptionInfo *exception)
3659{
3660
3661 MagickStatusType
3662 status;
3663
3664 QuantizeInfo
3665 *quantize_info;
3666
3667 assert(image_info != (ImageInfo *) NULL);
3668 assert(image_info->signature == MagickSignature);
3669 assert(images != (Image **) NULL);
3670 assert((*images)->previous == (Image *) NULL);
3671 assert((*images)->signature == MagickSignature);
3672 if ((*images)->debug != MagickFalse)
3673 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3674 (*images)->filename);
anthonya89dd172011-10-04 13:29:35 +00003675 if ((argc <= 0) || (*argv == (char *) NULL))
3676 return(MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003677 status=MagickTrue;
3678
3679 switch (*(argv[0]+1))
3680 {
3681 case 'a':
3682 {
3683 if (LocaleCompare("affinity",argv[0]+1) == 0)
3684 {
cristy6fccee12011-10-20 18:43:18 +00003685 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003686 if (*argv[0] == '+')
3687 {
3688 (void) RemapImages(quantize_info,*images,(Image *) NULL,
3689 exception);
3690 break;
3691 }
3692 break;
3693 }
3694 if (LocaleCompare("append",argv[0]+1) == 0)
3695 {
3696 Image
3697 *append_image;
3698
cristy6fccee12011-10-20 18:43:18 +00003699 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003700 append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue :
3701 MagickFalse,exception);
3702 if (append_image == (Image *) NULL)
3703 {
3704 status=MagickFalse;
3705 break;
3706 }
3707 *images=DestroyImageList(*images);
3708 *images=append_image;
3709 break;
3710 }
3711 if (LocaleCompare("average",argv[0]+1) == 0)
3712 {
3713 Image
3714 *average_image;
3715
3716 /*
3717 Average an image sequence (deprecated).
3718 */
cristy6fccee12011-10-20 18:43:18 +00003719 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003720 average_image=EvaluateImages(*images,MeanEvaluateOperator,
3721 exception);
3722 if (average_image == (Image *) NULL)
3723 {
3724 status=MagickFalse;
3725 break;
3726 }
3727 *images=DestroyImageList(*images);
3728 *images=average_image;
3729 break;
3730 }
3731 break;
3732 }
3733 case 'c':
3734 {
3735 if (LocaleCompare("channel",argv[0]+1) == 0)
3736 {
3737 ChannelType
3738 channel;
3739
3740 if (*argv[0] == '+')
3741 {
3742 channel=DefaultChannels;
3743 break;
3744 }
3745 channel=(ChannelType) ParseChannelOption(argv[1]);
3746 SetPixelChannelMap(*images,channel);
3747 break;
3748 }
3749 if (LocaleCompare("clut",argv[0]+1) == 0)
3750 {
3751 Image
3752 *clut_image,
3753 *image;
3754
cristy6fccee12011-10-20 18:43:18 +00003755 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003756 image=RemoveFirstImageFromList(images);
3757 clut_image=RemoveFirstImageFromList(images);
3758 if (clut_image == (Image *) NULL)
3759 {
3760 status=MagickFalse;
3761 break;
3762 }
anthonya89dd172011-10-04 13:29:35 +00003763 (void) ClutImage(image,clut_image,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003764 clut_image=DestroyImage(clut_image);
3765 *images=DestroyImageList(*images);
3766 *images=image;
3767 break;
3768 }
3769 if (LocaleCompare("coalesce",argv[0]+1) == 0)
3770 {
3771 Image
3772 *coalesce_image;
3773
cristy6fccee12011-10-20 18:43:18 +00003774 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003775 coalesce_image=CoalesceImages(*images,exception);
3776 if (coalesce_image == (Image *) NULL)
3777 {
3778 status=MagickFalse;
3779 break;
3780 }
3781 *images=DestroyImageList(*images);
3782 *images=coalesce_image;
3783 break;
3784 }
3785 if (LocaleCompare("combine",argv[0]+1) == 0)
3786 {
3787 Image
3788 *combine_image;
3789
cristy6fccee12011-10-20 18:43:18 +00003790 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003791 combine_image=CombineImages(*images,exception);
3792 if (combine_image == (Image *) NULL)
3793 {
3794 status=MagickFalse;
3795 break;
3796 }
3797 *images=DestroyImageList(*images);
3798 *images=combine_image;
3799 break;
3800 }
3801 if (LocaleCompare("composite",argv[0]+1) == 0)
3802 {
3803 Image
3804 *mask_image,
3805 *composite_image,
3806 *image;
3807
3808 RectangleInfo
3809 geometry;
3810
anthony5f867ae2011-10-09 10:28:34 +00003811 ComposeOperator
3812 compose;
3813
3814 const char*
3815 value;
3816
3817 value=GetImageOption(image_info,"compose");
3818 if (value != (const char *) NULL)
3819 compose=(CompositeOperator) ParseCommandOption(
3820 MagickComposeOptions,MagickFalse,value);
3821 else
3822 compose=OverCompositeOp; /* use Over not image->compose */
3823
3824 const char*
3825 value=GetImageOption(image_info,"compose");
3826
3827 if (value != (const char *) NULL)
3828 compose=(CompositeOperator) ParseCommandOption(
3829 MagickComposeOptions,MagickFalse,value);
3830 else
3831 compose=OverCompositeOp; /* use Over not image->compose */
3832
3833
cristy6fccee12011-10-20 18:43:18 +00003834 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003835 image=RemoveFirstImageFromList(images);
3836 composite_image=RemoveFirstImageFromList(images);
3837 if (composite_image == (Image *) NULL)
3838 {
3839 status=MagickFalse;
3840 break;
3841 }
3842 (void) TransformImage(&composite_image,(char *) NULL,
anthony6613bf32011-10-15 07:24:44 +00003843 composite_image->geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003844 SetGeometry(composite_image,&geometry);
3845 (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
3846 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
3847 &geometry);
3848 mask_image=RemoveFirstImageFromList(images);
3849 if (mask_image != (Image *) NULL)
3850 {
anthony5f867ae2011-10-09 10:28:34 +00003851 if ((compose == DisplaceCompositeOp) ||
3852 (compose == DistortCompositeOp))
anthony805a2d42011-09-25 08:25:12 +00003853 {
3854 /*
3855 Merge Y displacement into X displacement image.
3856 */
3857 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
anthony6613bf32011-10-15 07:24:44 +00003858 mask_image,0,0,exception);
anthony805a2d42011-09-25 08:25:12 +00003859 mask_image=DestroyImage(mask_image);
3860 }
3861 else
3862 {
3863 /*
3864 Set a blending mask for the composition.
3865 Posible error, what if image->mask already set.
3866 */
3867 image->mask=mask_image;
3868 (void) NegateImage(image->mask,MagickFalse,exception);
3869 }
3870 }
anthony5f867ae2011-10-09 10:28:34 +00003871 (void) CompositeImage(image,compose,composite_image,
anthony6613bf32011-10-15 07:24:44 +00003872 geometry.x,geometry.y,exception);
anthony805a2d42011-09-25 08:25:12 +00003873 if (mask_image != (Image *) NULL)
3874 mask_image=image->mask=DestroyImage(image->mask);
3875 composite_image=DestroyImage(composite_image);
anthony805a2d42011-09-25 08:25:12 +00003876 *images=DestroyImageList(*images);
3877 *images=image;
3878 break;
3879 }
3880 break;
3881 }
3882 case 'd':
3883 {
3884 if (LocaleCompare("deconstruct",argv[0]+1) == 0)
3885 {
3886 Image
3887 *deconstruct_image;
3888
cristy6fccee12011-10-20 18:43:18 +00003889 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003890 deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
3891 exception);
3892 if (deconstruct_image == (Image *) NULL)
3893 {
3894 status=MagickFalse;
3895 break;
3896 }
3897 *images=DestroyImageList(*images);
3898 *images=deconstruct_image;
3899 break;
3900 }
3901 if (LocaleCompare("delete",argv[0]+1) == 0)
3902 {
3903 if (*argv[0] == '+')
3904 DeleteImages(images,"-1",exception);
3905 else
3906 DeleteImages(images,argv[1],exception);
3907 break;
3908 }
3909 if (LocaleCompare("dither",argv[0]+1) == 0)
3910 {
3911 if (*argv[0] == '+')
3912 {
3913 quantize_info->dither=MagickFalse;
3914 break;
3915 }
3916 quantize_info->dither=MagickTrue;
3917 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
3918 MagickDitherOptions,MagickFalse,argv[1]);
3919 break;
3920 }
3921 if (LocaleCompare("duplicate",argv[0]+1) == 0)
3922 {
3923 Image
3924 *duplicate_images;
3925
3926 if (*argv[0] == '+')
3927 duplicate_images=DuplicateImages(*images,1,"-1",exception);
3928 else
3929 {
3930 const char
3931 *p;
3932
3933 size_t
3934 number_duplicates;
3935
3936 number_duplicates=(size_t) StringToLong(argv[1]);
3937 p=strchr(argv[1],',');
3938 if (p == (const char *) NULL)
3939 duplicate_images=DuplicateImages(*images,number_duplicates,
3940 "-1",exception);
3941 else
3942 duplicate_images=DuplicateImages(*images,number_duplicates,p,
3943 exception);
3944 }
3945 AppendImageToList(images, duplicate_images);
cristy6fccee12011-10-20 18:43:18 +00003946 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003947 break;
3948 }
3949 break;
3950 }
3951 case 'e':
3952 {
3953 if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0)
3954 {
3955 Image
3956 *evaluate_image;
3957
3958 MagickEvaluateOperator
3959 op;
3960
3961 (void) SyncImageSettings(image_info,*images);
3962 op=(MagickEvaluateOperator) ParseCommandOption(
3963 MagickEvaluateOptions,MagickFalse,argv[1]);
3964 evaluate_image=EvaluateImages(*images,op,exception);
3965 if (evaluate_image == (Image *) NULL)
3966 {
3967 status=MagickFalse;
3968 break;
3969 }
3970 *images=DestroyImageList(*images);
3971 *images=evaluate_image;
3972 break;
3973 }
3974 break;
3975 }
3976 case 'f':
3977 {
3978 if (LocaleCompare("fft",argv[0]+1) == 0)
3979 {
3980 Image
3981 *fourier_image;
3982
3983 /*
3984 Implements the discrete Fourier transform (DFT).
3985 */
3986 (void) SyncImageSettings(image_info,*images);
3987 fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ?
3988 MagickTrue : MagickFalse,exception);
3989 if (fourier_image == (Image *) NULL)
3990 break;
3991 *images=DestroyImage(*images);
3992 *images=fourier_image;
3993 break;
3994 }
3995 if (LocaleCompare("flatten",argv[0]+1) == 0)
3996 {
3997 Image
3998 *flatten_image;
3999
cristy6fccee12011-10-20 18:43:18 +00004000 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004001 flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
4002 if (flatten_image == (Image *) NULL)
4003 break;
4004 *images=DestroyImageList(*images);
4005 *images=flatten_image;
4006 break;
4007 }
4008 if (LocaleCompare("fx",argv[0]+1) == 0)
4009 {
4010 Image
4011 *fx_image;
4012
cristy6fccee12011-10-20 18:43:18 +00004013 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004014 fx_image=FxImage(*images,argv[1],exception);
4015 if (fx_image == (Image *) NULL)
4016 {
4017 status=MagickFalse;
4018 break;
4019 }
4020 *images=DestroyImageList(*images);
4021 *images=fx_image;
4022 break;
4023 }
4024 break;
4025 }
4026 case 'h':
4027 {
4028 if (LocaleCompare("hald-clut",argv[0]+1) == 0)
4029 {
4030 Image
4031 *hald_image,
4032 *image;
4033
cristy6fccee12011-10-20 18:43:18 +00004034 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004035 image=RemoveFirstImageFromList(images);
4036 hald_image=RemoveFirstImageFromList(images);
4037 if (hald_image == (Image *) NULL)
4038 {
4039 status=MagickFalse;
4040 break;
4041 }
4042 (void) HaldClutImage(image,hald_image,exception);
4043 hald_image=DestroyImage(hald_image);
4044 if (*images != (Image *) NULL)
4045 *images=DestroyImageList(*images);
4046 *images=image;
4047 break;
4048 }
4049 break;
4050 }
4051 case 'i':
4052 {
4053 if (LocaleCompare("ift",argv[0]+1) == 0)
4054 {
4055 Image
4056 *fourier_image,
4057 *magnitude_image,
4058 *phase_image;
4059
4060 /*
4061 Implements the inverse fourier discrete Fourier transform (DFT).
4062 */
cristy6fccee12011-10-20 18:43:18 +00004063 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004064 magnitude_image=RemoveFirstImageFromList(images);
4065 phase_image=RemoveFirstImageFromList(images);
4066 if (phase_image == (Image *) NULL)
4067 {
4068 status=MagickFalse;
4069 break;
4070 }
4071 fourier_image=InverseFourierTransformImage(magnitude_image,
4072 phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception);
4073 if (fourier_image == (Image *) NULL)
4074 break;
4075 if (*images != (Image *) NULL)
4076 *images=DestroyImage(*images);
4077 *images=fourier_image;
4078 break;
4079 }
4080 if (LocaleCompare("insert",argv[0]+1) == 0)
4081 {
4082 Image
4083 *p,
4084 *q;
4085
4086 index=0;
4087 if (*argv[0] != '+')
4088 index=(ssize_t) StringToLong(argv[1]);
4089 p=RemoveLastImageFromList(images);
4090 if (p == (Image *) NULL)
4091 {
4092 (void) ThrowMagickException(exception,GetMagickModule(),
4093 OptionError,"NoSuchImage","`%s'",argv[1]);
4094 status=MagickFalse;
4095 break;
4096 }
4097 q=p;
4098 if (index == 0)
4099 PrependImageToList(images,q);
4100 else
4101 if (index == (ssize_t) GetImageListLength(*images))
4102 AppendImageToList(images,q);
4103 else
4104 {
4105 q=GetImageFromList(*images,index-1);
4106 if (q == (Image *) NULL)
4107 {
4108 (void) ThrowMagickException(exception,GetMagickModule(),
4109 OptionError,"NoSuchImage","`%s'",argv[1]);
4110 status=MagickFalse;
4111 break;
4112 }
4113 InsertImageInList(&q,p);
4114 }
4115 *images=GetFirstImageInList(q);
4116 break;
4117 }
4118 if (LocaleCompare("interpolate",argv[0]+1) == 0)
4119 {
4120 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
4121 MagickInterpolateOptions,MagickFalse,argv[1]);
4122 break;
4123 }
4124 break;
4125 }
4126 case 'l':
4127 {
4128 if (LocaleCompare("layers",argv[0]+1) == 0)
4129 {
4130 Image
4131 *layers;
4132
4133 ImageLayerMethod
4134 method;
4135
cristy6fccee12011-10-20 18:43:18 +00004136 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004137 layers=(Image *) NULL;
4138 method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
4139 MagickFalse,argv[1]);
4140 switch (method)
4141 {
4142 case CoalesceLayer:
4143 {
4144 layers=CoalesceImages(*images,exception);
4145 break;
4146 }
4147 case CompareAnyLayer:
4148 case CompareClearLayer:
4149 case CompareOverlayLayer:
4150 default:
4151 {
4152 layers=CompareImagesLayers(*images,method,exception);
4153 break;
4154 }
4155 case MergeLayer:
4156 case FlattenLayer:
4157 case MosaicLayer:
4158 case TrimBoundsLayer:
4159 {
4160 layers=MergeImageLayers(*images,method,exception);
4161 break;
4162 }
4163 case DisposeLayer:
4164 {
4165 layers=DisposeImages(*images,exception);
4166 break;
4167 }
4168 case OptimizeImageLayer:
4169 {
4170 layers=OptimizeImageLayers(*images,exception);
4171 break;
4172 }
4173 case OptimizePlusLayer:
4174 {
4175 layers=OptimizePlusImageLayers(*images,exception);
4176 break;
4177 }
4178 case OptimizeTransLayer:
4179 {
4180 OptimizeImageTransparency(*images,exception);
4181 break;
4182 }
4183 case RemoveDupsLayer:
4184 {
4185 RemoveDuplicateLayers(images,exception);
4186 break;
4187 }
4188 case RemoveZeroLayer:
4189 {
4190 RemoveZeroDelayLayers(images,exception);
4191 break;
4192 }
4193 case OptimizeLayer:
4194 {
4195 /*
4196 General Purpose, GIF Animation Optimizer.
4197 */
4198 layers=CoalesceImages(*images,exception);
4199 if (layers == (Image *) NULL)
4200 {
4201 status=MagickFalse;
4202 break;
4203 }
4204 *images=DestroyImageList(*images);
4205 *images=layers;
4206 layers=OptimizeImageLayers(*images,exception);
4207 if (layers == (Image *) NULL)
4208 {
4209 status=MagickFalse;
4210 break;
4211 }
4212 *images=DestroyImageList(*images);
4213 *images=layers;
4214 layers=(Image *) NULL;
4215 OptimizeImageTransparency(*images,exception);
4216 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4217 exception);
4218 break;
4219 }
4220 case CompositeLayer:
4221 {
anthony805a2d42011-09-25 08:25:12 +00004222 Image
4223 *source;
4224
4225 RectangleInfo
4226 geometry;
4227
anthony5f867ae2011-10-09 10:28:34 +00004228 ComposeOperator
4229 compose;
4230
4231 const char*
4232 value;
4233
4234 value=GetImageOption(image_info,"compose");
4235 if (value != (const char *) NULL)
4236 compose=(CompositeOperator) ParseCommandOption(
4237 MagickComposeOptions,MagickFalse,value);
4238 else
4239 compose=OverCompositeOp; /* use Over not image->compose */
4240
anthony805a2d42011-09-25 08:25:12 +00004241 /*
4242 Split image sequence at the first 'NULL:' image.
4243 */
4244 source=(*images);
4245 while (source != (Image *) NULL)
4246 {
4247 source=GetNextImageInList(source);
4248 if ((source != (Image *) NULL) &&
4249 (LocaleCompare(source->magick,"NULL") == 0))
4250 break;
4251 }
4252 if (source != (Image *) NULL)
4253 {
4254 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4255 (GetNextImageInList(source) == (Image *) NULL))
4256 source=(Image *) NULL;
4257 else
4258 {
4259 /*
4260 Separate the two lists, junk the null: image.
4261 */
4262 source=SplitImageList(source->previous);
4263 DeleteImageFromList(&source);
4264 }
4265 }
4266 if (source == (Image *) NULL)
4267 {
4268 (void) ThrowMagickException(exception,GetMagickModule(),
4269 OptionError,"MissingNullSeparator","layers Composite");
4270 status=MagickFalse;
4271 break;
4272 }
4273 /*
4274 Adjust offset with gravity and virtual canvas.
4275 */
4276 SetGeometry(*images,&geometry);
4277 (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
4278 geometry.width=source->page.width != 0 ?
4279 source->page.width : source->columns;
4280 geometry.height=source->page.height != 0 ?
4281 source->page.height : source->rows;
4282 GravityAdjustGeometry((*images)->page.width != 0 ?
4283 (*images)->page.width : (*images)->columns,
4284 (*images)->page.height != 0 ? (*images)->page.height :
4285 (*images)->rows,(*images)->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004286
4287 /*
4288 Compose the two image sequences together
4289 */
anthony805a2d42011-09-25 08:25:12 +00004290 CompositeLayers(*images,compose,source,geometry.x,geometry.y,
4291 exception);
4292 source=DestroyImageList(source);
4293 break;
4294 }
4295 }
4296 if (layers == (Image *) NULL)
4297 break;
anthony805a2d42011-09-25 08:25:12 +00004298 *images=DestroyImageList(*images);
4299 *images=layers;
4300 break;
4301 }
4302 break;
4303 }
4304 case 'm':
4305 {
4306 if (LocaleCompare("map",argv[0]+1) == 0)
4307 {
cristy6fccee12011-10-20 18:43:18 +00004308 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004309 if (*argv[0] == '+')
4310 {
4311 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4312 exception);
4313 break;
4314 }
4315 break;
4316 }
4317 if (LocaleCompare("maximum",argv[0]+1) == 0)
4318 {
4319 Image
4320 *maximum_image;
4321
4322 /*
4323 Maximum image sequence (deprecated).
4324 */
cristy6fccee12011-10-20 18:43:18 +00004325 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004326 maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
4327 if (maximum_image == (Image *) NULL)
4328 {
4329 status=MagickFalse;
4330 break;
4331 }
4332 *images=DestroyImageList(*images);
4333 *images=maximum_image;
4334 break;
4335 }
4336 if (LocaleCompare("minimum",argv[0]+1) == 0)
4337 {
4338 Image
4339 *minimum_image;
4340
4341 /*
4342 Minimum image sequence (deprecated).
4343 */
cristy6fccee12011-10-20 18:43:18 +00004344 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004345 minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
4346 if (minimum_image == (Image *) NULL)
4347 {
4348 status=MagickFalse;
4349 break;
4350 }
4351 *images=DestroyImageList(*images);
4352 *images=minimum_image;
4353 break;
4354 }
4355 if (LocaleCompare("morph",argv[0]+1) == 0)
4356 {
4357 Image
4358 *morph_image;
4359
cristy6fccee12011-10-20 18:43:18 +00004360 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004361 morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]),
4362 exception);
4363 if (morph_image == (Image *) NULL)
4364 {
4365 status=MagickFalse;
4366 break;
4367 }
4368 *images=DestroyImageList(*images);
4369 *images=morph_image;
4370 break;
4371 }
4372 if (LocaleCompare("mosaic",argv[0]+1) == 0)
4373 {
4374 Image
4375 *mosaic_image;
4376
cristy6fccee12011-10-20 18:43:18 +00004377 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004378 mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
4379 if (mosaic_image == (Image *) NULL)
4380 {
4381 status=MagickFalse;
4382 break;
4383 }
4384 *images=DestroyImageList(*images);
4385 *images=mosaic_image;
4386 break;
4387 }
4388 break;
4389 }
4390 case 'p':
4391 {
4392 if (LocaleCompare("print",argv[0]+1) == 0)
4393 {
4394 char
4395 *string;
4396
cristy6fccee12011-10-20 18:43:18 +00004397 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004398 string=InterpretImageProperties(image_info,*images,argv[1],
4399 exception);
4400 if (string == (char *) NULL)
4401 break;
4402 (void) FormatLocaleFile(stdout,"%s",string);
4403 string=DestroyString(string);
4404 }
4405 if (LocaleCompare("process",argv[0]+1) == 0)
4406 {
4407 char
4408 **arguments;
4409
4410 int
4411 j,
4412 number_arguments;
4413
cristy6fccee12011-10-20 18:43:18 +00004414 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004415 arguments=StringToArgv(argv[1],&number_arguments);
4416 if (arguments == (char **) NULL)
4417 break;
4418 if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
4419 {
4420 char
4421 breaker,
4422 quote,
4423 *token;
4424
4425 const char
4426 *arguments;
4427
4428 int
4429 next,
4430 status;
4431
4432 size_t
4433 length;
4434
4435 TokenInfo
4436 *token_info;
4437
4438 /*
4439 Support old style syntax, filter="-option arg".
4440 */
4441 length=strlen(argv[1]);
4442 token=(char *) NULL;
4443 if (~length >= (MaxTextExtent-1))
4444 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4445 sizeof(*token));
4446 if (token == (char *) NULL)
4447 break;
4448 next=0;
4449 arguments=argv[1];
4450 token_info=AcquireTokenInfo();
4451 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4452 "\"",'\0',&breaker,&next,&quote);
4453 token_info=DestroyTokenInfo(token_info);
4454 if (status == 0)
4455 {
4456 const char
4457 *argv;
4458
4459 argv=(&(arguments[next]));
4460 (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
4461 exception);
4462 }
4463 token=DestroyString(token);
4464 break;
4465 }
4466 (void) SubstituteString(&arguments[1],"-","");
4467 (void) InvokeDynamicImageFilter(arguments[1],&(*images),
4468 number_arguments-2,(const char **) arguments+2,exception);
4469 for (j=0; j < number_arguments; j++)
4470 arguments[j]=DestroyString(arguments[j]);
4471 arguments=(char **) RelinquishMagickMemory(arguments);
4472 break;
4473 }
4474 break;
4475 }
4476 case 'r':
4477 {
4478 if (LocaleCompare("reverse",argv[0]+1) == 0)
4479 {
4480 ReverseImageList(images);
anthony805a2d42011-09-25 08:25:12 +00004481 break;
4482 }
4483 break;
4484 }
4485 case 's':
4486 {
4487 if (LocaleCompare("smush",argv[0]+1) == 0)
4488 {
4489 Image
4490 *smush_image;
4491
4492 ssize_t
4493 offset;
4494
cristy6fccee12011-10-20 18:43:18 +00004495 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004496 offset=(ssize_t) StringToLong(argv[1]);
4497 smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue :
4498 MagickFalse,offset,exception);
4499 if (smush_image == (Image *) NULL)
4500 {
4501 status=MagickFalse;
4502 break;
4503 }
4504 *images=DestroyImageList(*images);
4505 *images=smush_image;
4506 break;
4507 }
4508 if (LocaleCompare("swap",argv[0]+1) == 0)
4509 {
4510 Image
4511 *p,
4512 *q,
4513 *swap;
4514
4515 ssize_t
4516 swap_index;
4517
4518 index=(-1);
4519 swap_index=(-2);
4520 if (*argv[0] != '+')
4521 {
4522 GeometryInfo
4523 geometry_info;
4524
4525 MagickStatusType
4526 flags;
4527
4528 swap_index=(-1);
4529 flags=ParseGeometry(argv[1],&geometry_info);
4530 index=(ssize_t) geometry_info.rho;
4531 if ((flags & SigmaValue) != 0)
4532 swap_index=(ssize_t) geometry_info.sigma;
4533 }
4534 p=GetImageFromList(*images,index);
4535 q=GetImageFromList(*images,swap_index);
4536 if ((p == (Image *) NULL) || (q == (Image *) NULL))
4537 {
4538 (void) ThrowMagickException(exception,GetMagickModule(),
4539 OptionError,"NoSuchImage","`%s'",(*images)->filename);
4540 status=MagickFalse;
4541 break;
4542 }
4543 if (p == q)
4544 break;
4545 swap=CloneImage(p,0,0,MagickTrue,exception);
4546 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
4547 ReplaceImageInList(&q,swap);
4548 *images=GetFirstImageInList(q);
4549 break;
4550 }
4551 break;
4552 }
4553 case 'w':
4554 {
4555 if (LocaleCompare("write",argv[0]+1) == 0)
4556 {
4557 char
4558 key[MaxTextExtent];
4559
4560 Image
4561 *write_images;
4562
4563 ImageInfo
4564 *write_info;
4565
cristy6fccee12011-10-20 18:43:18 +00004566 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004567 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]);
4568 (void) DeleteImageRegistry(key);
4569 write_images=(*images);
4570 if (*argv[0] == '+')
4571 write_images=CloneImageList(*images,exception);
4572 write_info=CloneImageInfo(image_info);
4573 status&=WriteImages(write_info,write_images,argv[1],exception);
4574 write_info=DestroyImageInfo(write_info);
4575 if (*argv[0] == '+')
4576 write_images=DestroyImageList(write_images);
4577 break;
4578 }
4579 break;
4580 }
4581 default:
4582 break;
4583 }
4584 quantize_info=DestroyQuantizeInfo(quantize_info);
4585
cristy82d7af52011-10-16 16:26:41 +00004586 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthony805a2d42011-09-25 08:25:12 +00004587 return(status != 0 ? MagickTrue : MagickFalse);
4588}
cristy0a0ca4f2011-09-28 01:15:28 +00004589#endif