blob: 9c1d99ae3d3137cc21ca6578c13e2d3832f131cc [file] [log] [blame]
anthony805a2d42011-09-25 08:25:12 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% OOO PPPP EEEE RRRR AA TTTTTT III OOO N N %
7% O O P P E R R A A TT I O O NN N %
8% O O PPPP EEE RRRR AAAA TT I O O N N N %
9% O O P E R R A A TT I O O N NN %
10% OOO P EEEE R RR A A TT III OOO N N %
11% %
12% %
13% MagickWand Module Methods %
14% %
15% Software Design %
16% John Cristy %
cristy0a0ca4f2011-09-28 01:15:28 +000017% September 2011 %
anthony805a2d42011-09-25 08:25:12 +000018% %
19% %
20% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% Apply the given options (settings, and simple, or sequence operations) to
37% the given image(s) according to the current "image_info" and "draw_info"
38% settings.
39%
40% The final goal is to allow the execution in a strict one option at a time
41% manner that is needed for 'pipelining and file scripting' of options in
42% IMv7.
43%
44% Anthony Thyssen, Sept 2011
45*/
cristyc689f1f2011-10-05 21:13:24 +000046#if 0
anthony805a2d42011-09-25 08:25:12 +000047
48/*
49 Include declarations.
50*/
51#include "MagickWand/studio.h"
52#include "MagickWand/MagickWand.h"
53#include "MagickWand/mogrify-private.h"
54#include "MagickCore/monitor-private.h"
55#include "MagickCore/thread-private.h"
56#include "MagickCore/string-private.h"
57
58/*
59 Define declarations.
60*/
61#define UndefinedCompressionQuality 0UL
62/*
63 Constant declaration. (temporary exports)
64*/
65static const char
66 BackgroundColor[] = "#fff", /* white */
67 BorderColor[] = "#dfdfdf", /* gray */
68 MatteColor[] = "#bdbdbd"; /* gray */
69
70/*
71** Function to report on the progress of image operations
72*/
73static MagickBooleanType MonitorProgress(const char *text,
74 const MagickOffsetType offset,const MagickSizeType extent,
75 void *wand_unused(client_data))
76{
77 char
78 message[MaxTextExtent],
79 tag[MaxTextExtent];
80
81 const char
82 *locale_message;
83
84 register char
85 *p;
86
87 if (extent < 2)
88 return(MagickTrue);
89 (void) CopyMagickMemory(tag,text,MaxTextExtent);
90 p=strrchr(tag,'/');
91 if (p != (char *) NULL)
92 *p='\0';
93 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
94 locale_message=GetLocaleMessage(message);
95 if (locale_message == message)
96 locale_message=tag;
97 if (p == (char *) NULL)
98 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
99 locale_message,(long) offset,(unsigned long) extent,(long)
100 (100L*offset/(extent-1)));
101 else
102 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
103 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
104 (100L*offset/(extent-1)));
105 if (offset == (MagickOffsetType) (extent-1))
106 (void) FormatLocaleFile(stderr,"\n");
107 (void) fflush(stderr);
108 return(MagickTrue);
109}
110
111/*
112** GetImageCache() will read an image into a image cache if not already
113** present then return the image that is in the cache under that filename.
114*/
115static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
116 ExceptionInfo *exception)
117{
118 char
119 key[MaxTextExtent];
120
121 ExceptionInfo
122 *sans_exception;
123
124 Image
125 *image;
126
127 ImageInfo
128 *read_info;
129
130 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
131 sans_exception=AcquireExceptionInfo();
132 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
133 sans_exception=DestroyExceptionInfo(sans_exception);
134 if (image != (Image *) NULL)
135 return(image);
136 read_info=CloneImageInfo(image_info);
137 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
138 image=ReadImage(read_info,exception);
139 read_info=DestroyImageInfo(read_info);
140 if (image != (Image *) NULL)
141 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
142 return(image);
143}
144
145/*
anthonya89dd172011-10-04 13:29:35 +0000146 SparseColorOption() parse the complex -sparse-color argument into an
147 an array of floating point values than call SparseColorImage().
148 Argument is a complex mix of floating-point pixel coodinates, and color
149 specifications (or direct floating point numbers). The number of floats
150 needed to represent a color varies depending on teh current channel
151 setting.
anthony805a2d42011-09-25 08:25:12 +0000152*/
153static Image *SparseColorOption(const Image *image,
154 const SparseColorMethod method,const char *arguments,
155 const MagickBooleanType color_from_image,ExceptionInfo *exception)
156{
157 char
158 token[MaxTextExtent];
159
160 const char
161 *p;
162
163 double
164 *sparse_arguments;
165
166 Image
167 *sparse_image;
168
169 PixelInfo
170 color;
171
172 MagickBooleanType
173 error;
174
175 register size_t
176 x;
177
178 size_t
179 number_arguments,
180 number_colors;
181
182 assert(image != (Image *) NULL);
183 assert(image->signature == MagickSignature);
184 if (image->debug != MagickFalse)
185 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
186 assert(exception != (ExceptionInfo *) NULL);
187 assert(exception->signature == MagickSignature);
188 /*
189 Limit channels according to image - and add up number of color channel.
190 */
191 number_colors=0;
192 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
193 number_colors++;
194 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
195 number_colors++;
196 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
197 number_colors++;
198 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
199 (image->colorspace == CMYKColorspace))
200 number_colors++;
201 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
202 (image->matte != MagickFalse))
203 number_colors++;
204
205 /*
206 Read string, to determine number of arguments needed,
207 */
208 p=arguments;
209 x=0;
210 while( *p != '\0' )
211 {
212 GetMagickToken(p,&p,token);
213 if ( token[0] == ',' ) continue;
214 if ( isalpha((int) token[0]) || token[0] == '#' ) {
215 if ( color_from_image ) {
216 (void) ThrowMagickException(exception,GetMagickModule(),
217 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
218 "Color arg given, when colors are coming from image");
219 return( (Image *)NULL);
220 }
221 x += number_colors; /* color argument */
222 }
223 else {
224 x++; /* floating point argument */
225 }
226 }
227 error=MagickTrue;
228 if ( color_from_image ) {
229 /* just the control points are being given */
230 error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse;
231 number_arguments=(x/2)*(2+number_colors);
232 }
233 else {
234 /* control points and color values */
235 error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
236 number_arguments=x;
237 }
238 if ( error ) {
239 (void) ThrowMagickException(exception,GetMagickModule(),
240 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
241 "Invalid number of Arguments");
242 return( (Image *)NULL);
243 }
244
245 /* Allocate and fill in the floating point arguments */
246 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
247 sizeof(*sparse_arguments));
248 if (sparse_arguments == (double *) NULL) {
249 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
250 "MemoryAllocationFailed","%s","SparseColorOption");
251 return( (Image *)NULL);
252 }
253 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
254 sizeof(*sparse_arguments));
255 p=arguments;
256 x=0;
257 while( *p != '\0' && x < number_arguments ) {
258 /* X coordinate */
259 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
260 if ( token[0] == '\0' ) break;
261 if ( isalpha((int) token[0]) || token[0] == '#' ) {
262 (void) ThrowMagickException(exception,GetMagickModule(),
263 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
264 "Color found, instead of X-coord");
265 error = MagickTrue;
266 break;
267 }
268 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
269 /* Y coordinate */
270 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
271 if ( token[0] == '\0' ) break;
272 if ( isalpha((int) token[0]) || token[0] == '#' ) {
273 (void) ThrowMagickException(exception,GetMagickModule(),
274 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
275 "Color found, instead of Y-coord");
276 error = MagickTrue;
277 break;
278 }
279 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
280 /* color values for this control point */
281#if 0
282 if ( (color_from_image ) {
283 /* get color from image */
284 /* HOW??? */
285 }
286 else
287#endif
288 {
289 /* color name or function given in string argument */
290 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
291 if ( token[0] == '\0' ) break;
292 if ( isalpha((int) token[0]) || token[0] == '#' ) {
293 /* Color string given */
cristy269c9412011-10-13 23:41:15 +0000294 (void) QueryColorCompliance(token,AllCompliance,&color,
anthonya89dd172011-10-04 13:29:35 +0000295 exception);
anthony805a2d42011-09-25 08:25:12 +0000296 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
297 sparse_arguments[x++] = QuantumScale*color.red;
298 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
299 sparse_arguments[x++] = QuantumScale*color.green;
300 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
301 sparse_arguments[x++] = QuantumScale*color.blue;
302 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
303 (image->colorspace == CMYKColorspace))
304 sparse_arguments[x++] = QuantumScale*color.black;
305 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
306 (image->matte != MagickFalse))
307 sparse_arguments[x++] = QuantumScale*color.alpha;
308 }
309 else {
310 /* Colors given as a set of floating point values - experimental */
311 /* NB: token contains the first floating point value to use! */
312 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
313 {
314 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
315 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
316 break;
317 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
318 token[0] = ','; /* used this token - get another */
319 }
320 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
321 {
322 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
323 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
324 break;
325 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
326 token[0] = ','; /* used this token - get another */
327 }
328 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
329 {
330 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
331 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
332 break;
333 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
334 token[0] = ','; /* used this token - get another */
335 }
336 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
337 (image->colorspace == CMYKColorspace))
338 {
339 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
340 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
341 break;
342 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
343 token[0] = ','; /* used this token - get another */
344 }
345 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
346 (image->matte != MagickFalse))
347 {
348 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
349 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
350 break;
351 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
352 token[0] = ','; /* used this token - get another */
353 }
354 }
355 }
356 }
357 if ( number_arguments != x && !error ) {
358 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
359 "InvalidArgument","`%s': %s","sparse-color","Argument Parsing Error");
360 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
361 return( (Image *)NULL);
362 }
363 if ( error )
364 return( (Image *)NULL);
365
366 /* Call the Interpolation function with the parsed arguments */
367 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
368 exception);
369 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
370 return( sparse_image );
371}
372
373/*
374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375% %
376% %
377% %
anthony1afdc7a2011-10-05 11:54:28 +0000378+ A p p l y S e t t i n g O p t i o n %
anthony805a2d42011-09-25 08:25:12 +0000379% %
380% %
381% %
382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
383%
anthony1afdc7a2011-10-05 11:54:28 +0000384% ApplySettingOption() saves the given single settings option into a CLI wand
385% holding the image_info, draw_info, quantize_info structures that is later
386% used for reading, processing, and writing images.
anthony805a2d42011-09-25 08:25:12 +0000387%
anthony1afdc7a2011-10-05 11:54:28 +0000388% No image in the wand is actually modified (setting options only)
anthony805a2d42011-09-25 08:25:12 +0000389%
anthony1afdc7a2011-10-05 11:54:28 +0000390% The format of the ApplySettingOption method is:
391%
392% MagickBooleanType ApplySettingOption(MagickWand *wand,
anthony805a2d42011-09-25 08:25:12 +0000393% const int argc, const char **argv,ExceptionInfo *exception)
394%
395% A description of each parameter follows:
396%
anthony1afdc7a2011-10-05 11:54:28 +0000397% o wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +0000398%
399% o argc: Specifies a pointer to an integer describing the number of
400% elements in the argument vector.
401%
402% o argv: Specifies a pointer to a text array containing the command line
403% arguments.
404%
405% o exception: return any errors or warnings in this structure.
406%
407*/
anthony74b1cfc2011-10-06 12:44:16 +0000408WandExport MagickBooleanType ApplySettingsOption(ImageInfo *image_info,
cristy0a0ca4f2011-09-28 01:15:28 +0000409 const int argc,const char **argv,ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000410{
411 GeometryInfo
412 geometry_info;
413
anthony1afdc7a2011-10-05 11:54:28 +0000414 ImageInfo
415 *image_info;
416
417 DrawInfo
anthony74b1cfc2011-10-06 12:44:16 +0000418 *draw_info;
419
420 const char
421 *option;
anthony1afdc7a2011-10-05 11:54:28 +0000422
423 assert(wand != (MagickWand *) NULL);
424 assert(wand->signature == WandSignature);
425 assert(wand->draw_info != (DrawInfo *) NULL); /* ensure it is a CLI wand */
426 assert(wand->quantize_info == (QuantizeInfo *) NULL);
427 if (wand->debug != MagickFalse)
428 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
anthony805a2d42011-09-25 08:25:12 +0000429 if (argc < 0)
430 return(MagickTrue);
anthony1afdc7a2011-10-05 11:54:28 +0000431
anthony74b1cfc2011-10-06 12:44:16 +0000432 option=argv[0]+1;
anthony1afdc7a2011-10-05 11:54:28 +0000433 image_info=wand->image_info;
434 draw_info=wand->_info;
435
anthony74b1cfc2011-10-06 12:44:16 +0000436#define IfSetOption ((*argv[0])=='-')
437
438 switch (*option)
anthony805a2d42011-09-25 08:25:12 +0000439 {
440 case 'a':
441 {
anthony74b1cfc2011-10-06 12:44:16 +0000442 if (LocaleCompare("adjoin",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000443 {
anthony74b1cfc2011-10-06 12:44:16 +0000444 image_info->adjoin = IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000445 break;
446 }
anthony74b1cfc2011-10-06 12:44:16 +0000447 if (LocaleCompare("affine",option) == 0)
anthony1afdc7a2011-10-05 11:54:28 +0000448 {
anthonyafbaed72011-10-26 12:05:04 +0000449 /* draw_info setting only */
anthony74b1cfc2011-10-06 12:44:16 +0000450 if (IfSetOption)
anthony1afdc7a2011-10-05 11:54:28 +0000451 (void) ParseAffineGeometry(argv[1],draw_info->affine,
452 exception);
anthony74b1cfc2011-10-06 12:44:16 +0000453 else
454 GetAffineMatrix(draw_info->affine);
anthony1afdc7a2011-10-05 11:54:28 +0000455 break;
456 }
anthony74b1cfc2011-10-06 12:44:16 +0000457 if (LocaleCompare("antialias",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000458 {
anthony1afdc7a2011-10-05 11:54:28 +0000459 image_info->antialias =
460 draw_info->stroke_antialias =
461 draw_info->text_antialias =
anthony74b1cfc2011-10-06 12:44:16 +0000462 IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000463 break;
464 }
anthony74b1cfc2011-10-06 12:44:16 +0000465 if (LocaleCompare("authenticate",option) == 0)
anthony5f867ae2011-10-09 10:28:34 +0000466 {
anthony74b1cfc2011-10-06 12:44:16 +0000467 (void) SetImageOption(image_info,option,
anthonyafbaed72011-10-26 12:05:04 +0000468 IfSetOption ? argv[1] : (char*) NULL);
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 {
anthonyafbaed72011-10-26 12:05:04 +0000484 (void) SetImageOption(image_info,option,argv[1]);
485 (void) QueryColorCompliance(argv[1],AllCompliance,
486 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,
501 IfSetOption ? argv[1] : "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,
517 IfSetOption ? argv[1] : "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 {
anthony74b1cfc2011-10-06 12:44:16 +0000525 (void) SetImageOption(image_info,option,argv[1]);
526 (void) QueryColorCompliance(argv[1],AllCompliece,
527 &image_info->border_color,exception);
528 (void) QueryColorCompliance(argv[1],AllCompliance,
529 &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
543 *value = IfSetOption ? argv[1] : "none";
544 (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;
559 if (LocaleCompare("unlimited",argv[1]) != 0)
560 limit=(MagickSizeType) SiPrefixToDouble(argv[1],100.0);
561 (void) SetMagickResourceLimit(MemoryResource,limit);
562 (void) SetMagickResourceLimit(MapResource,2*limit);
563 break;
564 }
anthony74b1cfc2011-10-06 12:44:16 +0000565 if (LocaleCompare("caption",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000566 {
anthony74b1cfc2011-10-06 12:44:16 +0000567 (void) SetImageOption(image_info,option,
anthony6dc09cd2011-10-12 08:56:49 +0000568 IfSetOption ? argv[1] : (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) (
575 IfSetOption ? ParseChannelOption(argv[1]) : 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(
588 MagickColorspaceOptions,MagickFalse,argv[1])
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,
anthony6dc09cd2011-10-12 08:56:49 +0000594 IfSetOption ? argv[1] : (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,
anthony6dc09cd2011-10-12 08:56:49 +0000604 IfSetOption ? argv[1] : (const char*)NULL);
anthony965524b2011-10-07 12:34:14 +0000605 image_info->compose=(CompositeOperator) ParseCommandOption(
anthony5f867ae2011-10-09 10:28:34 +0000606 MagickComposeOptions,MagickFalse,
607 IfSetOption ? argv[1] : "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(
622 MagickCompressOptions,MagickFalse,argv[1]);
623 (void) SetImageOption(image_info,option,argv[1]);
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)
637 (void) SetLogEventMask(IfSetOption?argv[1]:"none");
638 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 */
anthony805a2d42011-09-25 08:25:12 +0000647 if (LocaleNCompare(argv[1],"registry:",9) == 0)
648 {
anthony5f867ae2011-10-09 10:28:34 +0000649 if (IfSetOption)
650 (void) DefineImageRegistry(StringRegistryType,argv[1]+9,
651 exception);
652 else
cristyd15e6592011-10-15 00:13:06 +0000653 (void) DefineImageOption(image_info,argv[1],exception);
anthony805a2d42011-09-25 08:25:12 +0000654 break;
655 }
anthony5f867ae2011-10-09 10:28:34 +0000656 if (IfSetOption)
cristyd15e6592011-10-15 00:13:06 +0000657 (void) DefineImageOption(image_info,argv[1],exception);
anthony5f867ae2011-10-09 10:28:34 +0000658 else
cristyd15e6592011-10-15 00:13:06 +0000659 (void) DeleteImageOption(image_info,argv[1],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,
668 IfSetOption ? argv[1] : "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 {
anthony5f867ae2011-10-09 10:28:34 +0000677 (void) CloneString(&image_info->density,argv[1]);
678 (void) CloneString(&draw_info->density,argv[1]);
679 (void) SetImageOption(image_info,option,argv[1]);
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 {
anthony5f867ae2011-10-09 10:28:34 +0000691 /* This is also a SimpleImageOperator! */
692 image_info->depth=IsSetOption?StringToUnsignedLong(argv[1])
693 :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,
700 IfSetOption ? argv[1] : "undefined");
701 draw_info->direction=(DirectionType) ParseCommandOption(
702 MagickDirectionOptions,MagickFalse,
703 IfSetOption ? argv[1] : "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,
710 IfSetOption ? argv[1] :(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,
716 IfSetOption ? argv[1] : "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,
723 IfSetOption ? argv[1] : "none");
724 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,
728 IfSetOption ? argv[1] : "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,
740 IfSetOption ? argv[1] : "undefined");
741 (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
749 value=IfSetOption?argv[1]:"undefined";
750 (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,
758 IfSetOption?argv[1]:(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,
768 IfSetOption ? argv[1] : (const char *) NULL);
769 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
783 value = IfSetOption ? argv[1] : "none";
784 (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,
800 IfSetOption ? argv[1] : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000801 break;
802 }
cristy947cb4c2011-10-20 18:41:46 +0000803 if (LocaleCompare("font",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000804 {
anthony6dc09cd2011-10-12 08:56:49 +0000805 (void) CloneString(&draw_info->font,
806 IfSetOption ? argv[1] : (const char *) NULL);
807 (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 {
cristy947cb4c2011-10-20 18:41:46 +0000812 /* FUTURE: why the ping test, the user could set ping after this! */
anthony805a2d42011-09-25 08:25:12 +0000813 register const char
814 *q;
815
816 for (q=strchr(argv[1],'%'); q != (char *) NULL; q=strchr(q+1,'%'))
817 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
818 image_info->ping=MagickFalse;
cristy947cb4c2011-10-20 18:41:46 +0000819 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000820 break;
821 }
anthony74b1cfc2011-10-06 12:44:16 +0000822 if (LocaleCompare("fuzz",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000823 {
anthony6613bf32011-10-15 07:24:44 +0000824 /* FUTURE: image_info and ImageOption!
825 Option used to set image fuzz! unless blank canvas (from color)
cristy947cb4c2011-10-20 18:41:46 +0000826 image attribute used for color compare operations
827 Can't find anything using image_info->fuzz (except cloning)!
anthony6613bf32011-10-15 07:24:44 +0000828 */
829 if (IfSetOption)
cristy947cb4c2011-10-20 18:41:46 +0000830 {
831 image_info->fuzz=SiPrefixToDouble(argv[1],(double) QuantumRange+1.0);
832 (void) SetImageOption(image_info,option,argv[1]);
833 break;
834 }
835 image_info->fuzz=0.0;
836 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +0000837 break;
838 }
839 break;
840 }
841 case 'g':
842 {
anthony74b1cfc2011-10-06 12:44:16 +0000843 if (LocaleCompare("gravity",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000844 {
cristy947cb4c2011-10-20 18:41:46 +0000845 if (*argv[0] == '+')
846 {
847 (void) SetImageOption(image_info,option,"undefined");
848 draw_info->gravity=UndefinedGravity;
849 break;
850 }
851 (void) SetImageOption(image_info,option,argv[1]);
anthony6dc09cd2011-10-12 08:56:49 +0000852 draw_info->gravity=(GravityType) ParseCommandOption(
cristy947cb4c2011-10-20 18:41:46 +0000853 MagickGravityOptions,MagickFalse,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000854 break;
855 }
anthony74b1cfc2011-10-06 12:44:16 +0000856 if (LocaleCompare("green-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000857 {
cristy947cb4c2011-10-20 18:41:46 +0000858 if (*argv[0] == '+')
859 {
860 (void) SetImageOption(image_info,option,"0.0");
861 break;
862 }
863 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000864 break;
865 }
866 break;
867 }
868 case 'i':
869 {
anthony74b1cfc2011-10-06 12:44:16 +0000870 if (LocaleCompare("intent",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000871 {
cristy947cb4c2011-10-20 18:41:46 +0000872 if (*argv[0] == '+')
873 {
874 (void) SetImageOption(image_info,option,"undefined");
875 break;
876 }
877 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000878 break;
879 }
anthony74b1cfc2011-10-06 12:44:16 +0000880 if (LocaleCompare("interlace",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000881 {
cristy947cb4c2011-10-20 18:41:46 +0000882 if (*argv[0] == '+')
883 {
884 image_info->interlace=UndefinedInterlace;
885 (void) SetImageOption(image_info,option,"undefined");
886 break;
887 }
anthony805a2d42011-09-25 08:25:12 +0000888 image_info->interlace=(InterlaceType) ParseCommandOption(
cristy947cb4c2011-10-20 18:41:46 +0000889 MagickInterlaceOptions,MagickFalse,argv[1]);
890 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000891 break;
892 }
anthony74b1cfc2011-10-06 12:44:16 +0000893 if (LocaleCompare("interline-spacing",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000894 {
cristy947cb4c2011-10-20 18:41:46 +0000895 if (*argv[0] == '+')
896 {
897 (void) SetImageOption(image_info,option,"undefined");
898 break;
899 }
900 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000901 break;
902 }
anthony74b1cfc2011-10-06 12:44:16 +0000903 if (LocaleCompare("interpolate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000904 {
cristy947cb4c2011-10-20 18:41:46 +0000905 if (*argv[0] == '+')
906 {
907 (void) SetImageOption(image_info,option,"undefined");
908 break;
909 }
910 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000911 break;
912 }
cristy947cb4c2011-10-20 18:41:46 +0000913 if (LocaleCompare("interword-spacing",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000914 {
cristy947cb4c2011-10-20 18:41:46 +0000915 if (*argv[0] == '+')
916 {
917 (void) SetImageOption(image_info,option,"undefined");
918 break;
919 }
920 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000921 break;
922 }
923 break;
924 }
925 case 'k':
926 {
anthony74b1cfc2011-10-06 12:44:16 +0000927 if (LocaleCompare("kerning",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000928 {
cristy947cb4c2011-10-20 18:41:46 +0000929 if (*argv[0] == '+')
930 {
931 (void) SetImageOption(image_info,option,"undefined");
932 break;
933 }
934 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000935 break;
936 }
937 break;
938 }
939 case 'l':
940 {
anthony74b1cfc2011-10-06 12:44:16 +0000941 if (LocaleCompare("label",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000942 {
cristy947cb4c2011-10-20 18:41:46 +0000943 if (*argv[0] == '+')
944 {
945 (void) DeleteImageOption(image_info,option);
946 break;
947 }
948 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000949 break;
950 }
anthony74b1cfc2011-10-06 12:44:16 +0000951 if (LocaleCompare("limit",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000952 {
953 MagickSizeType
954 limit;
955
956 ResourceType
957 type;
958
cristy947cb4c2011-10-20 18:41:46 +0000959 if (*argv[0] == '+')
anthony805a2d42011-09-25 08:25:12 +0000960 break;
961 type=(ResourceType) ParseCommandOption(MagickResourceOptions,
962 MagickFalse,argv[1]);
963 limit=MagickResourceInfinity;
964 if (LocaleCompare("unlimited",argv[2]) != 0)
965 limit=(MagickSizeType) SiPrefixToDouble(argv[2],100.0);
966 (void) SetMagickResourceLimit(type,limit);
967 break;
968 }
anthony74b1cfc2011-10-06 12:44:16 +0000969 if (LocaleCompare("list",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000970 {
971 ssize_t
972 list;
973
cristy947cb4c2011-10-20 18:41:46 +0000974 /*
975 Display configuration list.
976 */
anthony805a2d42011-09-25 08:25:12 +0000977 list=ParseCommandOption(MagickListOptions,MagickFalse,argv[1]);
978 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 {
cristy947cb4c2011-10-20 18:41:46 +00001061 if (*argv[0] == '+')
1062 break;
1063 (void) SetLogFormat(argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001064 break;
1065 }
anthony74b1cfc2011-10-06 12:44:16 +00001066 if (LocaleCompare("loop",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001067 {
cristy947cb4c2011-10-20 18:41:46 +00001068 if (*argv[0] == '+')
1069 {
1070 (void) SetImageOption(image_info,option,"0");
1071 break;
1072 }
1073 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001074 break;
1075 }
1076 break;
1077 }
1078 case 'm':
1079 {
cristy947cb4c2011-10-20 18:41:46 +00001080 if (LocaleCompare("matte",option) == 0)
1081 {
1082 if (*argv[0] == '+')
1083 {
1084 (void) SetImageOption(image_info,option,"false");
1085 break;
1086 }
1087 (void) SetImageOption(image_info,option,"true");
1088 break;
1089 }
anthony74b1cfc2011-10-06 12:44:16 +00001090 if (LocaleCompare("mattecolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001091 {
cristy947cb4c2011-10-20 18:41:46 +00001092 if (*argv[0] == '+')
1093 {
1094 (void) SetImageOption(image_info,option,argv[1]);
1095 (void) QueryColorCompliance(MatteColor,AllCompliance,
1096 &image_info->matte_color,exception);
1097 break;
1098 }
anthony74b1cfc2011-10-06 12:44:16 +00001099 (void) SetImageOption(image_info,option,argv[1]);
cristy947cb4c2011-10-20 18:41:46 +00001100 (void) QueryColorCompliance(argv[1],AllCompliance,&image_info->matte_color,
1101 exception);
anthony805a2d42011-09-25 08:25:12 +00001102 break;
1103 }
anthony74b1cfc2011-10-06 12:44:16 +00001104 if (LocaleCompare("monitor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001105 {
1106 (void) SetImageInfoProgressMonitor(image_info,MonitorProgress,
1107 (void *) NULL);
1108 break;
1109 }
anthony74b1cfc2011-10-06 12:44:16 +00001110 if (LocaleCompare("monochrome",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001111 {
cristy947cb4c2011-10-20 18:41:46 +00001112 image_info->monochrome=(*argv[0] == '-') ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +00001113 break;
1114 }
1115 break;
1116 }
1117 case 'o':
1118 {
anthony74b1cfc2011-10-06 12:44:16 +00001119 if (LocaleCompare("orient",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001120 {
cristy947cb4c2011-10-20 18:41:46 +00001121 if (*argv[0] == '+')
1122 {
1123 image_info->orientation=UndefinedOrientation;
1124 (void) SetImageOption(image_info,option,"undefined");
1125 break;
1126 }
1127 image_info->orientation=(OrientationType) ParseCommandOption(
1128 MagickOrientationOptions,MagickFalse,argv[1]);
1129 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001130 break;
1131 }
1132 }
1133 case 'p':
1134 {
anthony74b1cfc2011-10-06 12:44:16 +00001135 if (LocaleCompare("page",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001136 {
1137 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
cristy947cb4c2011-10-20 18:41:46 +00001150 if (*argv[0] == '+')
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);
1160 canonical_page=GetPageGeometry(argv[1]);
1161 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 }
cristy947cb4c2011-10-20 18:41:46 +00001173 if (LocaleCompare("pen",option) == 0)
1174 {
1175 if (*argv[0] == '+')
1176 {
1177 (void) SetImageOption(image_info,option,"none");
1178 break;
1179 }
1180 (void) SetImageOption(image_info,option,argv[1]);
1181 break;
1182 }
anthony74b1cfc2011-10-06 12:44:16 +00001183 if (LocaleCompare("ping",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001184 {
anthonyafbaed72011-10-26 12:05:04 +00001185 image_info->ping= IsSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +00001186 break;
1187 }
anthony74b1cfc2011-10-06 12:44:16 +00001188 if (LocaleCompare("pointsize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001189 {
cristy947cb4c2011-10-20 18:41:46 +00001190 if (*argv[0] == '+')
1191 geometry_info.rho=0.0;
1192 else
1193 (void) ParseGeometry(argv[1],&geometry_info);
1194 image_info->pointsize=geometry_info.rho;
anthony805a2d42011-09-25 08:25:12 +00001195 break;
1196 }
anthony74b1cfc2011-10-06 12:44:16 +00001197 if (LocaleCompare("precision",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001198 {
1199 (void) SetMagickPrecision(StringToInteger(argv[1]));
1200 break;
1201 }
anthony74b1cfc2011-10-06 12:44:16 +00001202 if (LocaleCompare("preview",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001203 {
cristy947cb4c2011-10-20 18:41:46 +00001204 /*
1205 Preview image.
1206 */
1207 if (*argv[0] == '+')
1208 {
1209 image_info->preview_type=UndefinedPreview;
1210 break;
1211 }
1212 image_info->preview_type=(PreviewType) ParseCommandOption(
1213 MagickPreviewOptions,MagickFalse,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001214 break;
1215 }
1216 break;
1217 }
1218 case 'q':
1219 {
anthony74b1cfc2011-10-06 12:44:16 +00001220 if (LocaleCompare("quality",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001221 {
cristy947cb4c2011-10-20 18:41:46 +00001222 /*
1223 Set image compression quality.
1224 */
1225 if (*argv[0] == '+')
anthony805a2d42011-09-25 08:25:12 +00001226 {
cristy947cb4c2011-10-20 18:41:46 +00001227 image_info->quality=UndefinedCompressionQuality;
1228 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001229 break;
1230 }
cristy947cb4c2011-10-20 18:41:46 +00001231 image_info->quality=StringToUnsignedLong(argv[1]);
1232 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001233 break;
1234 }
anthonyafbaed72011-10-26 12:05:04 +00001235 if (LocaleCompare("quantize",option) == 0)
1236 {
1237 /* no image_info setting! Only set direct in quantize_info */
1238 quantize_info->colorspace=UndefinedColorspace;
1239 if (IfSetOption)
1240 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
1241 MagickColorspaceOptions,MagickFalse,argv[1]);
1242 break;
1243 }
anthony74b1cfc2011-10-06 12:44:16 +00001244 if (LocaleCompare("quiet",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001245 {
1246 static WarningHandler
1247 warning_handler = (WarningHandler) NULL;
anthonyafbaed72011-10-26 12:05:04 +00001248 WarningHandler
1249 tmp = SetWarningHandler((WarningHandler) NULL);
anthony805a2d42011-09-25 08:25:12 +00001250
anthonyafbaed72011-10-26 12:05:04 +00001251 if ( tmp != (WarningHandler) NULL)
1252 warning_handler = tmp; /* remember the old handler */
1253 if (!IfSetOption) /* set the old handler */
1254 warning_handler=SetWarningHandler(warning_handler);
anthony805a2d42011-09-25 08:25:12 +00001255 break;
1256 }
1257 break;
1258 }
1259 case 'r':
1260 {
anthony74b1cfc2011-10-06 12:44:16 +00001261 if (LocaleCompare("red-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001262 {
cristy947cb4c2011-10-20 18:41:46 +00001263 if (*argv[0] == '+')
1264 {
1265 (void) SetImageOption(image_info,option,"0.0");
1266 break;
1267 }
1268 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001269 break;
1270 }
anthonyafbaed72011-10-26 12:05:04 +00001271 if (LocaleCompare("render",option) == 0)
1272 {
1273 /* draw_info only setting */
1274 draw_info->render= IfSetOption ? MagickFalse : MagickTrue;
1275 break;
1276 }
anthony805a2d42011-09-25 08:25:12 +00001277 break;
1278 }
1279 case 's':
1280 {
anthony74b1cfc2011-10-06 12:44:16 +00001281 if (LocaleCompare("sampling-factor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001282 {
anthonyafbaed72011-10-26 12:05:04 +00001283 /* FUTURE: should be converted to jpeg:sampling_factor */
1284 (void) CloneString(&image_info->sampling_factor,
1285 IfSetOption ? argv[1] : (char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001286 break;
1287 }
anthony74b1cfc2011-10-06 12:44:16 +00001288 if (LocaleCompare("scene",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001289 {
anthonyafbaed72011-10-26 12:05:04 +00001290 char
1291 *value = IfSetOption ? argv[1] : "0";
1292
1293 (void) SetImageOption(image_info,option,value);
1294 image_info->scene=StringToUnsignedLong(value);
anthony805a2d42011-09-25 08:25:12 +00001295 break;
1296 }
anthony74b1cfc2011-10-06 12:44:16 +00001297 if (LocaleCompare("seed",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001298 {
anthonyafbaed72011-10-26 12:05:04 +00001299 SeedPseudoRandomGenerator(
1300 IfSetOption ? (size_t) StringToUnsignedLong(argv[1])
1301 : (size_t) time((time_t *) NULL) );
anthony805a2d42011-09-25 08:25:12 +00001302 break;
1303 }
anthony74b1cfc2011-10-06 12:44:16 +00001304 if (LocaleCompare("size",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001305 {
anthonyafbaed72011-10-26 12:05:04 +00001306 /* FUTURE: string in image_info -- convert to Option ???
1307 Look at the special handling for "size" in SetImageOption()
anthony74b1cfc2011-10-06 12:44:16 +00001308 */
anthonyafbaed72011-10-26 12:05:04 +00001309 (void) CloneString(&image_info->size,
1310 IfSetOption ? argv[1] : (char *) NULL);
1311 break;
1312 }
1313 if (LocaleCompare("stretch",option) == 0)
1314 {
1315 draw_info->stretch=UndefinedStretch;
1316 if (IfSetOption)
1317 draw_info->stretch=(StretchType) ParseCommandOption(
1318 MagickStretchOptions,MagickFalse,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001319 break;
1320 }
anthony74b1cfc2011-10-06 12:44:16 +00001321 if (LocaleCompare("stroke",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001322 {
anthonyafbaed72011-10-26 12:05:04 +00001323 /* set stroke color OR stroke-pattern
1324 color is only used by draw_info
1325 but draw_info is only initialsed using the color not the pattern
1326 */
1327 const char
1328 *value = IfSetOption ? argv[1] : "none";
1329
1330 ExceptionInfo
1331 *sans;
1332
1333 (void) SetImageOption(image_info,option,value);
1334
1335 sans=AcquireExceptionInfo();
1336 status=QueryColorCompliance(value,AllCompliance,&draw_info->stroke,
1337 sans);
1338 sans=DestroyExceptionInfo(sans);
1339
1340 if (draw_info->stroke_pattern != (Image *) NULL)
1341 draw_info->stroke_pattern=DestroyImage(draw_info->stroke_pattern);
1342 if (status == MagickFalse)
1343 draw_info->stroke_pattern=GetImageCache(image_info,value,
1344 exception);
anthony805a2d42011-09-25 08:25:12 +00001345 break;
1346 }
anthony74b1cfc2011-10-06 12:44:16 +00001347 if (LocaleCompare("strokewidth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001348 {
anthonyafbaed72011-10-26 12:05:04 +00001349 const char
1350 *value = IfSetOption ? argv[1] : "1.0";
1351 (void) SetImageOption(image_info,option,value);
1352 draw_info->stroke_width=InterpretLocaleValue(value,(char **) NULL);
1353 break;
1354 }
1355 if (LocaleCompare("style",option) == 0)
1356 {
1357 draw_info->style=UndefinedStyle;
1358 if (IfSetOption)
1359 draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
1360 MagickFalse,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001361 break;
1362 }
anthony74b1cfc2011-10-06 12:44:16 +00001363 if (LocaleCompare("synchronize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001364 {
anthonyafbaed72011-10-26 12:05:04 +00001365 image_info->synchronize=IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +00001366 break;
1367 }
1368 break;
1369 }
1370 case 't':
1371 {
anthony74b1cfc2011-10-06 12:44:16 +00001372 if (LocaleCompare("taint",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001373 {
anthonyafbaed72011-10-26 12:05:04 +00001374 (void) SetImageOption(image_info,option,
1375 IfSetOption ? "true" : "false");
anthony805a2d42011-09-25 08:25:12 +00001376 break;
1377 }
anthony74b1cfc2011-10-06 12:44:16 +00001378 if (LocaleCompare("texture",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001379 {
anthonyafbaed72011-10-26 12:05:04 +00001380 /* FUTURE: move image_info string to option splay-tree */
1381 (void) CloneString(&image_info->texture,
1382 IfSetOption ? argv[1] : (char *) NULL);
1383 break;
1384 }
1385 if (LocaleCompare("tile",option) == 0)
1386 {
1387 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
1388 if (IfSetOption)
1389 draw_info->fill_pattern=GetImageCache(image_info,argv[1],exception);
anthony805a2d42011-09-25 08:25:12 +00001390 break;
1391 }
anthony74b1cfc2011-10-06 12:44:16 +00001392 if (LocaleCompare("tile-offset",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001393 {
anthonyafbaed72011-10-26 12:05:04 +00001394 (void) SetImageOption(image_info,option,
1395 IfSetOption ? argv[1] : "0");
anthony805a2d42011-09-25 08:25:12 +00001396 break;
1397 }
anthony74b1cfc2011-10-06 12:44:16 +00001398 if (LocaleCompare("transparent-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001399 {
anthonyafbaed72011-10-26 12:05:04 +00001400 /* FUTURE: both image_info attribute & ImageOption in use!
1401 image_info only used for generating new images.
1402 Note that +transparent-color, means fall-back to image
1403 attribute so ImageOption is deleted, not set to a default.
1404 */
1405 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001406 {
anthonyafbaed72011-10-26 12:05:04 +00001407 (void) SetImageOption(image_info,option,argv[1]);
1408 (void) QueryColorCompliance(argv[1],AllCompliance,
1409 image_info->transparent_color,exception);
anthony805a2d42011-09-25 08:25:12 +00001410 break;
1411 }
anthonyafbaed72011-10-26 12:05:04 +00001412 (void) DeleteImageOption(image_info,option);
1413 (void) QueryColorCompliance("none",AllCompliance,
1414 image_info->transparent_color,exception);
anthony805a2d42011-09-25 08:25:12 +00001415 break;
1416 }
anthony74b1cfc2011-10-06 12:44:16 +00001417 if (LocaleCompare("type",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001418 {
1419 if (*argv[0] == '+')
1420 {
1421 image_info->type=UndefinedType;
anthony74b1cfc2011-10-06 12:44:16 +00001422 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +00001423 break;
1424 }
1425 image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
1426 MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001427 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001428 break;
1429 }
1430 break;
1431 }
1432 case 'u':
1433 {
anthony74b1cfc2011-10-06 12:44:16 +00001434 if (LocaleCompare("undercolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001435 {
1436 if (*argv[0] == '+')
1437 {
anthony74b1cfc2011-10-06 12:44:16 +00001438 (void) DeleteImageOption(image_info,option);
anthony805a2d42011-09-25 08:25:12 +00001439 break;
1440 }
anthony74b1cfc2011-10-06 12:44:16 +00001441 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001442 break;
1443 }
anthony74b1cfc2011-10-06 12:44:16 +00001444 if (LocaleCompare("units",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001445 {
1446 if (*argv[0] == '+')
1447 {
1448 image_info->units=UndefinedResolution;
anthony74b1cfc2011-10-06 12:44:16 +00001449 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +00001450 break;
1451 }
1452 image_info->units=(ResolutionType) ParseCommandOption(
1453 MagickResolutionOptions,MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001454 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001455 break;
1456 }
1457 break;
1458 }
1459 case 'v':
1460 {
anthony74b1cfc2011-10-06 12:44:16 +00001461 if (LocaleCompare("verbose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001462 {
1463 if (*argv[0] == '+')
1464 {
1465 image_info->verbose=MagickFalse;
1466 break;
1467 }
1468 image_info->verbose=MagickTrue;
1469 image_info->ping=MagickFalse;
1470 break;
1471 }
anthony74b1cfc2011-10-06 12:44:16 +00001472 if (LocaleCompare("view",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001473 {
1474 if (*argv[0] == '+')
1475 {
1476 if (image_info->view != (char *) NULL)
1477 image_info->view=DestroyString(image_info->view);
1478 break;
1479 }
1480 (void) CloneString(&image_info->view,argv[1]);
1481 break;
1482 }
anthony74b1cfc2011-10-06 12:44:16 +00001483 if (LocaleCompare("virtual-pixel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001484 {
1485 if (*argv[0] == '+')
1486 {
1487 image_info->virtual_pixel_method=UndefinedVirtualPixelMethod;
anthony74b1cfc2011-10-06 12:44:16 +00001488 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +00001489 break;
1490 }
1491 image_info->virtual_pixel_method=(VirtualPixelMethod)
1492 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001493 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001494 break;
1495 }
1496 break;
1497 }
1498 case 'w':
1499 {
anthony74b1cfc2011-10-06 12:44:16 +00001500 if (LocaleCompare("white-point",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001501 {
1502 if (*argv[0] == '+')
1503 {
anthony74b1cfc2011-10-06 12:44:16 +00001504 (void) SetImageOption(image_info,option,"0.0");
anthony805a2d42011-09-25 08:25:12 +00001505 break;
1506 }
anthony74b1cfc2011-10-06 12:44:16 +00001507 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001508 break;
1509 }
1510 break;
1511 }
1512 default:
1513 break;
1514 }
1515 return(MagickTrue);
1516}
1517
1518/*
1519%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1520% %
1521% %
1522% %
anthony74b1cfc2011-10-06 12:44:16 +00001523+ A p p l y I m a g e O p e r a t o r %
anthony805a2d42011-09-25 08:25:12 +00001524% %
1525% %
1526% %
1527%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1528%
anthony74b1cfc2011-10-06 12:44:16 +00001529% ApplyImageOperator() apply one simple image operation to just the current
1530% image.
anthony805a2d42011-09-25 08:25:12 +00001531%
1532% The image in the list may be modified in three different ways...
1533%
1534% * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1535% * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1536% * replace by a list of images (-separate and -crop only!)
1537%
1538% In each case the result is returned into the list, and the pointer to the
1539% modified image (last image added if replaced by a list of images) is
1540% returned. As the image pointed to may be replaced, the first image in the
1541% list may also change. GetFirstImageInList() should be used by caller if
1542% they wish return the Image pointer to the first image in list.
1543%
anthony74b1cfc2011-10-06 12:44:16 +00001544% The format of the ApplyImageOperator method is:
anthony805a2d42011-09-25 08:25:12 +00001545%
anthony74b1cfc2011-10-06 12:44:16 +00001546% MagickBooleanType ApplyImageOperator(MagickWand *wand,
1547% const int argc,const char **argv)
anthony805a2d42011-09-25 08:25:12 +00001548%
1549% A description of each parameter follows:
1550%
anthony74b1cfc2011-10-06 12:44:16 +00001551% o wand: The CLI wand holding all the settings and pointer to image
anthony805a2d42011-09-25 08:25:12 +00001552%
1553% o argc: Specifies a pointer to an integer describing the number of
1554% elements in the argument vector.
1555%
1556% o argv: Specifies a pointer to a text array containing the command line
1557% arguments.
1558%
anthony805a2d42011-09-25 08:25:12 +00001559% o exception: return any errors or warnings in this structure.
1560%
1561*/
anthony74b1cfc2011-10-06 12:44:16 +00001562MagickExport MagickBooleanType ApplyImageOperator(MagickWand *wand,
1563 const int wand_unused(argc), const char **argv, ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +00001564{
1565 Image *
1566 new_image;
1567
1568 ChannelType
1569 channel;
1570
anthony5f867ae2011-10-09 10:28:34 +00001571 ComposeOperation
1572 compose;
1573
anthony805a2d42011-09-25 08:25:12 +00001574 const char
1575 *format;
1576
1577 DrawInfo
1578 *draw_info;
1579
1580 GeometryInfo
1581 geometry_info;
1582
1583 RectangleInfo
1584 geometry;
1585
1586 MagickStatusType
1587 status;
1588
1589 PixelInfo
1590 fill;
1591
1592 MagickStatusType
1593 flags;
1594
1595 QuantizeInfo
1596 *quantize_info;
1597
1598 assert(image_info != (const ImageInfo *) NULL);
1599 assert(image_info->signature == MagickSignature);
1600 assert(image != (Image **) NULL);
1601 assert((*image)->signature == MagickSignature);
1602 if ((*image)->debug != MagickFalse)
1603 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
anthonya89dd172011-10-04 13:29:35 +00001604 if (argc < 0)
1605 return(MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00001606 draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
1607 quantize_info=AcquireQuantizeInfo(image_info);
1608 SetGeometryInfo(&geometry_info);
1609 GetPixelInfo(*image,&fill);
cristy9d8c8ce2011-10-25 16:13:52 +00001610 fill=(*image)->background_color;
anthony805a2d42011-09-25 08:25:12 +00001611 channel=image_info->channel;
1612 format=GetImageOption(image_info,"format");
1613
1614 new_image = (Image *)NULL;
1615
cristy947cb4c2011-10-20 18:41:46 +00001616 switch (*(argv[0]+1))
anthony805a2d42011-09-25 08:25:12 +00001617 {
1618 case 'a':
1619 {
cristy947cb4c2011-10-20 18:41:46 +00001620 if (LocaleCompare("adaptive-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001621 {
cristy6fccee12011-10-20 18:43:18 +00001622 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001623 flags=ParseGeometry(argv[1],&geometry_info);
1624 if ((flags & SigmaValue) == 0)
1625 geometry_info.sigma=1.0;
1626 if ((flags & XiValue) == 0)
1627 geometry_info.xi=0.0;
1628 new_image=AdaptiveBlurImage(*image,geometry_info.rho,
1629 geometry_info.sigma,geometry_info.xi,exception);
1630 break;
1631 }
cristy947cb4c2011-10-20 18:41:46 +00001632 if (LocaleCompare("adaptive-resize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001633 {
anthony1afdc7a2011-10-05 11:54:28 +00001634 /* FUTURE: this is really a "interpolate-resize" operator
1635 "adaptive-resize" uses a fixed "Mesh" interpolation
anthony805a2d42011-09-25 08:25:12 +00001636 */
cristy6fccee12011-10-20 18:43:18 +00001637 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001638 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
1639 new_image=AdaptiveResizeImage(*image,geometry.width,
anthonya89dd172011-10-04 13:29:35 +00001640 geometry.height,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00001641 break;
1642 }
cristy947cb4c2011-10-20 18:41:46 +00001643 if (LocaleCompare("adaptive-sharpen",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001644 {
1645 /*
1646 Adaptive sharpen image.
1647 */
cristy6fccee12011-10-20 18:43:18 +00001648 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001649 flags=ParseGeometry(argv[1],&geometry_info);
1650 if ((flags & SigmaValue) == 0)
1651 geometry_info.sigma=1.0;
1652 if ((flags & XiValue) == 0)
1653 geometry_info.xi=0.0;
1654 new_image=AdaptiveSharpenImage(*image,geometry_info.rho,
1655 geometry_info.sigma,geometry_info.xi,exception);
1656 break;
1657 }
cristy947cb4c2011-10-20 18:41:46 +00001658 if (LocaleCompare("alpha",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001659 {
1660 AlphaChannelType
1661 alpha_type;
1662
cristy6fccee12011-10-20 18:43:18 +00001663 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001664 alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
1665 MagickFalse,argv[1]);
1666 (void) SetImageAlphaChannel(*image,alpha_type,exception);
1667 break;
1668 }
cristy947cb4c2011-10-20 18:41:46 +00001669 if (LocaleCompare("annotate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001670 {
1671 char
1672 *text,
1673 geometry[MaxTextExtent];
1674
cristy6fccee12011-10-20 18:43:18 +00001675 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001676 SetGeometryInfo(&geometry_info);
1677 flags=ParseGeometry(argv[1],&geometry_info);
1678 if ((flags & SigmaValue) == 0)
1679 geometry_info.sigma=geometry_info.rho;
1680 text=InterpretImageProperties(image_info,*image,argv[2],
1681 exception);
1682 if (text == (char *) NULL)
1683 break;
1684 (void) CloneString(&draw_info->text,text);
1685 text=DestroyString(text);
1686 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1687 geometry_info.xi,geometry_info.psi);
1688 (void) CloneString(&draw_info->geometry,geometry);
1689 draw_info->affine.sx=cos(DegreesToRadians(
1690 fmod(geometry_info.rho,360.0)));
1691 draw_info->affine.rx=sin(DegreesToRadians(
1692 fmod(geometry_info.rho,360.0)));
1693 draw_info->affine.ry=(-sin(DegreesToRadians(
1694 fmod(geometry_info.sigma,360.0))));
1695 draw_info->affine.sy=cos(DegreesToRadians(
1696 fmod(geometry_info.sigma,360.0)));
1697 (void) AnnotateImage(*image,draw_info,exception);
1698 break;
1699 }
cristy947cb4c2011-10-20 18:41:46 +00001700 if (LocaleCompare("auto-gamma",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001701 {
1702 /*
1703 Auto Adjust Gamma of image based on its mean
1704 */
cristy6fccee12011-10-20 18:43:18 +00001705 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001706 (void) AutoGammaImage(*image,exception);
1707 break;
1708 }
cristy947cb4c2011-10-20 18:41:46 +00001709 if (LocaleCompare("auto-level",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001710 {
1711 /*
1712 Perfectly Normalize (max/min stretch) the image
1713 */
cristy6fccee12011-10-20 18:43:18 +00001714 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001715 (void) AutoLevelImage(*image,exception);
1716 break;
1717 }
cristy947cb4c2011-10-20 18:41:46 +00001718 if (LocaleCompare("auto-orient",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001719 {
cristy6fccee12011-10-20 18:43:18 +00001720 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001721 switch ((*image)->orientation)
1722 {
1723 case TopRightOrientation:
1724 {
1725 new_image=FlopImage(*image,exception);
1726 break;
1727 }
1728 case BottomRightOrientation:
1729 {
1730 new_image=RotateImage(*image,180.0,exception);
1731 break;
1732 }
1733 case BottomLeftOrientation:
1734 {
1735 new_image=FlipImage(*image,exception);
1736 break;
1737 }
1738 case LeftTopOrientation:
1739 {
1740 new_image=TransposeImage(*image,exception);
1741 break;
1742 }
1743 case RightTopOrientation:
1744 {
1745 new_image=RotateImage(*image,90.0,exception);
1746 break;
1747 }
1748 case RightBottomOrientation:
1749 {
1750 new_image=TransverseImage(*image,exception);
1751 break;
1752 }
1753 case LeftBottomOrientation:
1754 {
1755 new_image=RotateImage(*image,270.0,exception);
1756 break;
1757 }
1758 default:
1759 break;
1760 }
1761 if (new_image != (Image *) NULL)
1762 new_image->orientation=TopLeftOrientation;
1763 break;
1764 }
1765 break;
1766 }
1767 case 'b':
1768 {
cristy947cb4c2011-10-20 18:41:46 +00001769 if (LocaleCompare("black-threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001770 {
cristy6fccee12011-10-20 18:43:18 +00001771 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001772 (void) BlackThresholdImage(*image,argv[1],exception);
anthony805a2d42011-09-25 08:25:12 +00001773 break;
1774 }
cristy947cb4c2011-10-20 18:41:46 +00001775 if (LocaleCompare("blue-shift",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001776 {
cristy6fccee12011-10-20 18:43:18 +00001777 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001778 geometry_info.rho=1.5;
1779 if (*argv[0] == '-')
1780 flags=ParseGeometry(argv[1],&geometry_info);
1781 new_image=BlueShiftImage(*image,geometry_info.rho,exception);
1782 break;
1783 }
cristy947cb4c2011-10-20 18:41:46 +00001784 if (LocaleCompare("blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001785 {
anthony74b1cfc2011-10-06 12:44:16 +00001786 /* FUTURE: use of "bias" in a blur is non-sensible */
cristy6fccee12011-10-20 18:43:18 +00001787 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001788 flags=ParseGeometry(argv[1],&geometry_info);
1789 if ((flags & SigmaValue) == 0)
1790 geometry_info.sigma=1.0;
1791 if ((flags & XiValue) == 0)
1792 geometry_info.xi=0.0;
1793 new_image=BlurImage(*image,geometry_info.rho,
1794 geometry_info.sigma,geometry_info.xi,exception);
1795 break;
1796 }
cristy947cb4c2011-10-20 18:41:46 +00001797 if (LocaleCompare("border",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001798 {
anthony5f867ae2011-10-09 10:28:34 +00001799 ComposeOperator
1800 compose;
1801
1802 const char*
1803 const char*
1804 value;
1805
1806 value=GetImageOption(image_info,"compose");
1807 if (value != (const char *) NULL)
1808 compose=(CompositeOperator) ParseCommandOption(
1809 MagickComposeOptions,MagickFalse,value);
1810 else
1811 compose=OverCompositeOp; /* use Over not image->compose */
1812
cristy6fccee12011-10-20 18:43:18 +00001813 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001814 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
1815 if ((flags & SigmaValue) == 0)
1816 geometry.height=geometry.width;
anthonya89dd172011-10-04 13:29:35 +00001817 new_image=BorderImage(*image,&geometry,compose,exception);
anthony805a2d42011-09-25 08:25:12 +00001818 break;
1819 }
cristy947cb4c2011-10-20 18:41:46 +00001820 if (LocaleCompare("brightness-contrast",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001821 {
1822 double
1823 brightness,
1824 contrast;
1825
1826 GeometryInfo
1827 geometry_info;
1828
1829 MagickStatusType
1830 flags;
1831
cristy6fccee12011-10-20 18:43:18 +00001832 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001833 flags=ParseGeometry(argv[1],&geometry_info);
1834 brightness=geometry_info.rho;
1835 contrast=0.0;
1836 if ((flags & SigmaValue) != 0)
1837 contrast=geometry_info.sigma;
1838 (void) BrightnessContrastImage(*image,brightness,contrast,
1839 exception);
anthony805a2d42011-09-25 08:25:12 +00001840 break;
1841 }
1842 break;
1843 }
1844 case 'c':
1845 {
cristy947cb4c2011-10-20 18:41:46 +00001846 if (LocaleCompare("cdl",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001847 {
1848 char
1849 *color_correction_collection;
1850
1851 /*
1852 Color correct with a color decision list.
1853 */
cristy6fccee12011-10-20 18:43:18 +00001854 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001855 color_correction_collection=FileToString(argv[1],~0,exception);
1856 if (color_correction_collection == (char *) NULL)
1857 break;
1858 (void) ColorDecisionListImage(*image,color_correction_collection,
1859 exception);
anthony805a2d42011-09-25 08:25:12 +00001860 break;
1861 }
cristy947cb4c2011-10-20 18:41:46 +00001862 if (LocaleCompare("channel",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001863 {
anthony74b1cfc2011-10-06 12:44:16 +00001864 /* The "channel" setting has already been set */
1865 SetPixelChannelMap(*image,image_info->channel);
anthony805a2d42011-09-25 08:25:12 +00001866 break;
1867 }
cristy947cb4c2011-10-20 18:41:46 +00001868 if (LocaleCompare("charcoal",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001869 {
cristy6fccee12011-10-20 18:43:18 +00001870 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001871 flags=ParseGeometry(argv[1],&geometry_info);
1872 if ((flags & SigmaValue) == 0)
1873 geometry_info.sigma=1.0;
1874 if ((flags & XiValue) == 0)
1875 geometry_info.xi=1.0;
1876 new_image=CharcoalImage(*image,geometry_info.rho,
1877 geometry_info.sigma,geometry_info.xi,exception);
1878 break;
1879 }
cristy947cb4c2011-10-20 18:41:46 +00001880 if (LocaleCompare("chop",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001881 {
cristy6fccee12011-10-20 18:43:18 +00001882 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001883 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
1884 new_image=ChopImage(*image,&geometry,exception);
1885 break;
1886 }
cristy947cb4c2011-10-20 18:41:46 +00001887 if (LocaleCompare("clamp",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001888 {
cristy6fccee12011-10-20 18:43:18 +00001889 (void) SyncImageSettings(image_info,*image,exception);
cristy092d71c2011-10-14 18:01:29 +00001890 (void) ClampImage(*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001891 break;
1892 }
cristy947cb4c2011-10-20 18:41:46 +00001893 if (LocaleCompare("clip",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001894 {
cristy6fccee12011-10-20 18:43:18 +00001895 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001896 if (*argv[0] == '+')
1897 {
1898 (void) SetImageClipMask(*image,(Image *) NULL,exception);
1899 break;
1900 }
1901 (void) ClipImage(*image,exception);
1902 break;
1903 }
cristy947cb4c2011-10-20 18:41:46 +00001904 if (LocaleCompare("clip-mask",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001905 {
1906 CacheView
1907 *mask_view;
1908
1909 Image
1910 *mask_image;
1911
1912 register Quantum
1913 *restrict q;
1914
1915 register ssize_t
1916 x;
1917
1918 ssize_t
1919 y;
1920
cristy6fccee12011-10-20 18:43:18 +00001921 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001922 if (*argv[0] == '+')
1923 {
anthony74b1cfc2011-10-06 12:44:16 +00001924 /* Remove the write mask */
anthony805a2d42011-09-25 08:25:12 +00001925 (void) SetImageMask(*image,(Image *) NULL,exception);
1926 break;
1927 }
1928 mask_image=GetImageCache(image_info,argv[1],exception);
1929 if (mask_image == (Image *) NULL)
1930 break;
1931 if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
1932 return(MagickFalse);
anthony74b1cfc2011-10-06 12:44:16 +00001933 /* create a write mask from clip-mask image */
1934 /* FUTURE: use Alpha operations instead */
anthony805a2d42011-09-25 08:25:12 +00001935 mask_view=AcquireCacheView(mask_image);
1936 for (y=0; y < (ssize_t) mask_image->rows; y++)
1937 {
1938 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
1939 exception);
1940 if (q == (Quantum *) NULL)
1941 break;
1942 for (x=0; x < (ssize_t) mask_image->columns; x++)
1943 {
1944 if (mask_image->matte == MagickFalse)
1945 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1946 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1947 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1948 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1949 q+=GetPixelChannels(mask_image);
1950 }
1951 if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
1952 break;
1953 }
anthony74b1cfc2011-10-06 12:44:16 +00001954 /* set the write mask */
anthony805a2d42011-09-25 08:25:12 +00001955 mask_view=DestroyCacheView(mask_view);
1956 mask_image->matte=MagickTrue;
anthonya89dd172011-10-04 13:29:35 +00001957 (void) SetImageClipMask(*image,mask_image,exception);
anthony805a2d42011-09-25 08:25:12 +00001958 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00001959 break;
1960 }
cristy947cb4c2011-10-20 18:41:46 +00001961 if (LocaleCompare("clip-path",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001962 {
cristy6fccee12011-10-20 18:43:18 +00001963 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001964 (void) ClipImagePath(*image,argv[1],*argv[0] == '-' ? MagickTrue :
1965 MagickFalse,exception);
1966 break;
1967 }
cristy947cb4c2011-10-20 18:41:46 +00001968 if (LocaleCompare("colorize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001969 {
cristy6fccee12011-10-20 18:43:18 +00001970 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001971 new_image=ColorizeImage(*image,argv[1],draw_info->fill,
1972 exception);
1973 break;
1974 }
cristy947cb4c2011-10-20 18:41:46 +00001975 if (LocaleCompare("color-matrix",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001976 {
1977 KernelInfo
1978 *kernel;
1979
cristy6fccee12011-10-20 18:43:18 +00001980 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001981 kernel=AcquireKernelInfo(argv[1]);
1982 if (kernel == (KernelInfo *) NULL)
1983 break;
1984 new_image=ColorMatrixImage(*image,kernel,exception);
1985 kernel=DestroyKernelInfo(kernel);
1986 break;
1987 }
cristy947cb4c2011-10-20 18:41:46 +00001988 if (LocaleCompare("colors",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001989 {
anthony74b1cfc2011-10-06 12:44:16 +00001990 /* Reduce the number of colors in the image. */
cristy6fccee12011-10-20 18:43:18 +00001991 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001992 quantize_info->number_colors=StringToUnsignedLong(argv[1]);
1993 if (quantize_info->number_colors == 0)
1994 break;
1995 if (((*image)->storage_class == DirectClass) ||
1996 (*image)->colors > quantize_info->number_colors)
1997 (void) QuantizeImage(quantize_info,*image,exception);
1998 else
1999 (void) CompressImageColormap(*image,exception);
2000 break;
2001 }
cristy947cb4c2011-10-20 18:41:46 +00002002 if (LocaleCompare("colorspace",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002003 {
anthonyd2cdc862011-10-07 14:07:17 +00002004 /* This is a Image Setting, which should already been set */
2005 /* FUTURE: default colorspace should be sRGB!
2006 Unless some type of 'linear colorspace' mode is set.
2007 Note that +colorspace sets "undefined" or no effect on
2008 new images, but forces images already in memory back to RGB!
2009 */
cristy6fccee12011-10-20 18:43:18 +00002010 (void) SyncImageSettings(image_info,*image,exception);
anthonyd2cdc862011-10-07 14:07:17 +00002011 (void) TransformImageColorspace(*image,
anthony6613bf32011-10-15 07:24:44 +00002012 IfSetOption ? image_info->colorspace : RGBColorspace,
2013 exception);
anthony805a2d42011-09-25 08:25:12 +00002014 break;
2015 }
cristy947cb4c2011-10-20 18:41:46 +00002016 if (LocaleCompare("contrast",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002017 {
cristy6fccee12011-10-20 18:43:18 +00002018 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002019 (void) ContrastImage(*image,(*argv[0] == '-') ? MagickTrue :
2020 MagickFalse,exception);
2021 break;
2022 }
cristy947cb4c2011-10-20 18:41:46 +00002023 if (LocaleCompare("contrast-stretch",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002024 {
2025 double
2026 black_point,
2027 white_point;
2028
2029 MagickStatusType
2030 flags;
2031
2032 /*
2033 Contrast stretch image.
2034 */
cristy6fccee12011-10-20 18:43:18 +00002035 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002036 flags=ParseGeometry(argv[1],&geometry_info);
2037 black_point=geometry_info.rho;
2038 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2039 black_point;
2040 if ((flags & PercentValue) != 0)
2041 {
2042 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2043 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2044 }
2045 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2046 white_point;
2047 (void) ContrastStretchImage(*image,black_point,white_point,
2048 exception);
anthony805a2d42011-09-25 08:25:12 +00002049 break;
2050 }
cristy947cb4c2011-10-20 18:41:46 +00002051 if (LocaleCompare("convolve",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002052 {
2053 KernelInfo
2054 *kernel_info;
2055
cristy6fccee12011-10-20 18:43:18 +00002056 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002057 kernel_info=AcquireKernelInfo(argv[1]);
2058 if (kernel_info == (KernelInfo *) NULL)
2059 break;
2060 kernel_info->bias=(*image)->bias;
2061 new_image=ConvolveImage(*image,kernel_info,exception);
2062 kernel_info=DestroyKernelInfo(kernel_info);
2063 break;
2064 }
cristy947cb4c2011-10-20 18:41:46 +00002065 if (LocaleCompare("crop",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002066 {
2067 /*
2068 Crop a image to a smaller size
2069 */
cristy6fccee12011-10-20 18:43:18 +00002070 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002071 new_image=CropImageToTiles(*image,argv[1],exception);
2072 break;
2073 }
cristy947cb4c2011-10-20 18:41:46 +00002074 if (LocaleCompare("cycle",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002075 {
2076 /*
2077 Cycle an image colormap.
2078 */
cristy6fccee12011-10-20 18:43:18 +00002079 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002080 (void) CycleColormapImage(*image,(ssize_t) StringToLong(argv[1]),
2081 exception);
2082 break;
2083 }
2084 break;
2085 }
2086 case 'd':
2087 {
cristy947cb4c2011-10-20 18:41:46 +00002088 if (LocaleCompare("decipher",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002089 {
2090 StringInfo
2091 *passkey;
2092
2093 /*
2094 Decipher pixels.
2095 */
cristy6fccee12011-10-20 18:43:18 +00002096 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002097 passkey=FileToStringInfo(argv[1],~0,exception);
2098 if (passkey != (StringInfo *) NULL)
2099 {
2100 (void) PasskeyDecipherImage(*image,passkey,exception);
2101 passkey=DestroyStringInfo(passkey);
2102 }
2103 break;
2104 }
cristy947cb4c2011-10-20 18:41:46 +00002105 if (LocaleCompare("depth",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002106 {
anthony5f867ae2011-10-09 10:28:34 +00002107 /* the image_info->depth setting has already bee set
2108 * We just need to apply it to all images in current sequence */
cristy6fccee12011-10-20 18:43:18 +00002109 (void) SyncImageSettings(image_info,*image,exception);
anthony5f867ae2011-10-09 10:28:34 +00002110 (void) SetImageDepth(*image,image_info->depth);
anthony805a2d42011-09-25 08:25:12 +00002111 break;
2112 }
cristy947cb4c2011-10-20 18:41:46 +00002113 if (LocaleCompare("deskew",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002114 {
2115 double
2116 threshold;
2117
2118 /*
2119 Straighten the image.
2120 */
cristy6fccee12011-10-20 18:43:18 +00002121 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002122 if (*argv[0] == '+')
2123 threshold=40.0*QuantumRange/100.0;
2124 else
2125 threshold=SiPrefixToDouble(argv[1],QuantumRange);
2126 new_image=DeskewImage(*image,threshold,exception);
2127 break;
2128 }
cristy947cb4c2011-10-20 18:41:46 +00002129 if (LocaleCompare("despeckle",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002130 {
2131 /*
2132 Reduce the speckles within an image.
2133 */
cristy6fccee12011-10-20 18:43:18 +00002134 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002135 new_image=DespeckleImage(*image,exception);
2136 break;
2137 }
cristy947cb4c2011-10-20 18:41:46 +00002138 if (LocaleCompare("display",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002139 {
2140 (void) CloneString(&draw_info->server_name,argv[1]);
2141 break;
2142 }
cristy947cb4c2011-10-20 18:41:46 +00002143 if (LocaleCompare("distort",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002144 {
2145 char
2146 *args,
2147 token[MaxTextExtent];
2148
2149 const char
2150 *p;
2151
2152 DistortImageMethod
2153 method;
2154
2155 double
2156 *arguments;
2157
2158 register ssize_t
2159 x;
2160
2161 size_t
2162 number_arguments;
2163
2164 /*
2165 Distort image.
2166 */
cristy6fccee12011-10-20 18:43:18 +00002167 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002168 method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
2169 MagickFalse,argv[1]);
2170 if ( method == ResizeDistortion )
2171 {
2172 /* Special Case - Argument is actually a resize geometry!
2173 ** Convert that to an appropriate distortion argument array.
2174 */
2175 double
2176 resize_args[2];
2177 (void) ParseRegionGeometry(*image,argv[2],&geometry,
2178 exception);
2179 resize_args[0]=(double)geometry.width;
2180 resize_args[1]=(double)geometry.height;
2181 new_image=DistortImage(*image,method,(size_t)2,
2182 resize_args,MagickTrue,exception);
2183 break;
2184 }
2185 args=InterpretImageProperties(image_info,*image,argv[2],
2186 exception);
2187 if (args == (char *) NULL)
2188 break;
2189 p=(char *) args;
2190 for (x=0; *p != '\0'; x++)
2191 {
2192 GetMagickToken(p,&p,token);
2193 if (*token == ',')
2194 GetMagickToken(p,&p,token);
2195 }
2196 number_arguments=(size_t) x;
2197 arguments=(double *) AcquireQuantumMemory(number_arguments,
2198 sizeof(*arguments));
2199 if (arguments == (double *) NULL)
2200 ThrowWandFatalException(ResourceLimitFatalError,
2201 "MemoryAllocationFailed",(*image)->filename);
2202 (void) ResetMagickMemory(arguments,0,number_arguments*
2203 sizeof(*arguments));
2204 p=(char *) args;
2205 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2206 {
2207 GetMagickToken(p,&p,token);
2208 if (*token == ',')
2209 GetMagickToken(p,&p,token);
2210 arguments[x]=InterpretLocaleValue(token,(char **) NULL);
2211 }
2212 args=DestroyString(args);
2213 new_image=DistortImage(*image,method,number_arguments,arguments,
2214 (*argv[0] == '+') ? MagickTrue : MagickFalse,exception);
2215 arguments=(double *) RelinquishMagickMemory(arguments);
2216 break;
2217 }
cristy947cb4c2011-10-20 18:41:46 +00002218 if (LocaleCompare("draw",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002219 {
cristy6fccee12011-10-20 18:43:18 +00002220 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002221 (void) CloneString(&draw_info->primitive,argv[1]);
2222 (void) DrawImage(*image,draw_info,exception);
2223 break;
2224 }
2225 break;
2226 }
2227 case 'e':
2228 {
cristy947cb4c2011-10-20 18:41:46 +00002229 if (LocaleCompare("edge",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002230 {
cristy6fccee12011-10-20 18:43:18 +00002231 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002232 flags=ParseGeometry(argv[1],&geometry_info);
2233 if ((flags & SigmaValue) == 0)
2234 geometry_info.sigma=1.0;
2235 new_image=EdgeImage(*image,geometry_info.rho,
2236 geometry_info.sigma,exception);
2237 break;
2238 }
cristy947cb4c2011-10-20 18:41:46 +00002239 if (LocaleCompare("emboss",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002240 {
cristy6fccee12011-10-20 18:43:18 +00002241 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002242 flags=ParseGeometry(argv[1],&geometry_info);
2243 if ((flags & SigmaValue) == 0)
2244 geometry_info.sigma=1.0;
2245 new_image=EmbossImage(*image,geometry_info.rho,
2246 geometry_info.sigma,exception);
2247 break;
2248 }
cristy947cb4c2011-10-20 18:41:46 +00002249 if (LocaleCompare("encipher",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002250 {
2251 StringInfo
2252 *passkey;
2253
cristy6fccee12011-10-20 18:43:18 +00002254 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002255 passkey=FileToStringInfo(argv[1],~0,exception);
2256 if (passkey != (StringInfo *) NULL)
2257 {
2258 (void) PasskeyEncipherImage(*image,passkey,exception);
2259 passkey=DestroyStringInfo(passkey);
2260 }
2261 break;
2262 }
cristy947cb4c2011-10-20 18:41:46 +00002263 if (LocaleCompare("enhance",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002264 {
cristy6fccee12011-10-20 18:43:18 +00002265 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002266 new_image=EnhanceImage(*image,exception);
2267 break;
2268 }
cristy947cb4c2011-10-20 18:41:46 +00002269 if (LocaleCompare("equalize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002270 {
cristy6fccee12011-10-20 18:43:18 +00002271 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002272 (void) EqualizeImage(*image,exception);
2273 break;
2274 }
cristy947cb4c2011-10-20 18:41:46 +00002275 if (LocaleCompare("evaluate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002276 {
2277 double
2278 constant;
2279
2280 MagickEvaluateOperator
2281 op;
2282
cristy6fccee12011-10-20 18:43:18 +00002283 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002284 op=(MagickEvaluateOperator) ParseCommandOption(
2285 MagickEvaluateOptions,MagickFalse,argv[1]);
2286 constant=SiPrefixToDouble(argv[2],QuantumRange);
2287 (void) EvaluateImage(*image,op,constant,exception);
2288 break;
2289 }
cristy947cb4c2011-10-20 18:41:46 +00002290 if (LocaleCompare("extent",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002291 {
cristy6fccee12011-10-20 18:43:18 +00002292 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002293 flags=ParseGravityGeometry(*image,argv[1],&geometry,exception);
2294 if (geometry.width == 0)
2295 geometry.width=(*image)->columns;
2296 if (geometry.height == 0)
2297 geometry.height=(*image)->rows;
2298 new_image=ExtentImage(*image,&geometry,exception);
2299 break;
2300 }
2301 break;
2302 }
2303 case 'f':
2304 {
cristy947cb4c2011-10-20 18:41:46 +00002305 if (LocaleCompare("features",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002306 {
anthonyafbaed72011-10-26 12:05:04 +00002307 /* FUTURE: Assign Artifact to all images -- per image setting */
anthony6dc09cd2011-10-12 08:56:49 +00002308 (void) SetImageArtifact(*image,"identify:features",
2309 IfSetOption ? argv[1] : (const char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002310 break;
2311 }
cristy947cb4c2011-10-20 18:41:46 +00002312 if (LocaleCompare("flip",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002313 {
cristy947cb4c2011-10-20 18:41:46 +00002314 /*
2315 Flip image scanlines.
2316 */
cristy6fccee12011-10-20 18:43:18 +00002317 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002318 new_image=FlipImage(*image,exception);
2319 break;
2320 }
cristy947cb4c2011-10-20 18:41:46 +00002321 if (LocaleCompare("flop",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002322 {
cristy947cb4c2011-10-20 18:41:46 +00002323 /*
2324 Flop image scanlines.
2325 */
cristy6fccee12011-10-20 18:43:18 +00002326 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002327 new_image=FlopImage(*image,exception);
2328 break;
2329 }
cristy947cb4c2011-10-20 18:41:46 +00002330 if (LocaleCompare("floodfill",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002331 {
2332 PixelInfo
2333 target;
2334
cristy947cb4c2011-10-20 18:41:46 +00002335 /*
2336 Floodfill image.
2337 */
cristy6fccee12011-10-20 18:43:18 +00002338 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002339 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
cristy269c9412011-10-13 23:41:15 +00002340 (void) QueryColorCompliance(argv[2],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00002341 exception);
anthony805a2d42011-09-25 08:25:12 +00002342 (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
2343 geometry.y,*argv[0] == '-' ? MagickFalse : MagickTrue,exception);
2344 break;
2345 }
cristy947cb4c2011-10-20 18:41:46 +00002346 /* FUTURE: should be from ImageOption "format"
2347 if (LocaleCompare("format",argv[0]+1) == 0)
2348 {
2349 format=argv[1];
2350 break;
2351 }
2352 */
2353 if (LocaleCompare("frame",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002354 {
2355 FrameInfo
2356 frame_info;
2357
cristy947cb4c2011-10-20 18:41:46 +00002358 /*
2359 Surround image with an ornamental border.
2360 */
cristy6fccee12011-10-20 18:43:18 +00002361 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002362 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
2363 frame_info.width=geometry.width;
2364 frame_info.height=geometry.height;
2365 if ((flags & HeightValue) == 0)
2366 frame_info.height=geometry.width;
2367 frame_info.outer_bevel=geometry.x;
2368 frame_info.inner_bevel=geometry.y;
2369 frame_info.x=(ssize_t) frame_info.width;
2370 frame_info.y=(ssize_t) frame_info.height;
2371 frame_info.width=(*image)->columns+2*frame_info.width;
2372 frame_info.height=(*image)->rows+2*frame_info.height;
anthony5f867ae2011-10-09 10:28:34 +00002373 new_image=FrameImage(*image,&frame_info,COMPOSE,exception);
anthony805a2d42011-09-25 08:25:12 +00002374 break;
2375 }
cristy947cb4c2011-10-20 18:41:46 +00002376 if (LocaleCompare("function",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002377 {
2378 char
2379 *arguments,
2380 token[MaxTextExtent];
2381
2382 const char
2383 *p;
2384
2385 double
2386 *parameters;
2387
2388 MagickFunction
2389 function;
2390
2391 register ssize_t
2392 x;
2393
2394 size_t
2395 number_parameters;
2396
cristy947cb4c2011-10-20 18:41:46 +00002397 /*
2398 Function Modify Image Values
2399 */
cristy6fccee12011-10-20 18:43:18 +00002400 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002401 function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
2402 MagickFalse,argv[1]);
2403 arguments=InterpretImageProperties(image_info,*image,argv[2],
2404 exception);
2405 if (arguments == (char *) NULL)
2406 break;
2407 p=(char *) arguments;
2408 for (x=0; *p != '\0'; x++)
2409 {
2410 GetMagickToken(p,&p,token);
2411 if (*token == ',')
2412 GetMagickToken(p,&p,token);
2413 }
2414 number_parameters=(size_t) x;
2415 parameters=(double *) AcquireQuantumMemory(number_parameters,
2416 sizeof(*parameters));
2417 if (parameters == (double *) NULL)
2418 ThrowWandFatalException(ResourceLimitFatalError,
2419 "MemoryAllocationFailed",(*image)->filename);
2420 (void) ResetMagickMemory(parameters,0,number_parameters*
2421 sizeof(*parameters));
2422 p=(char *) arguments;
2423 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
2424 {
2425 GetMagickToken(p,&p,token);
2426 if (*token == ',')
2427 GetMagickToken(p,&p,token);
2428 parameters[x]=InterpretLocaleValue(token,(char **) NULL);
2429 }
2430 arguments=DestroyString(arguments);
2431 (void) FunctionImage(*image,function,number_parameters,parameters,
2432 exception);
2433 parameters=(double *) RelinquishMagickMemory(parameters);
2434 break;
2435 }
2436 break;
2437 }
2438 case 'g':
2439 {
cristy947cb4c2011-10-20 18:41:46 +00002440 if (LocaleCompare("gamma",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002441 {
cristy6fccee12011-10-20 18:43:18 +00002442 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002443 if (*argv[0] == '+')
2444 (*image)->gamma=InterpretLocaleValue(argv[1],(char **) NULL);
2445 else
2446 (void) GammaImage(*image,InterpretLocaleValue(argv[1],
2447 (char **) NULL),exception);
2448 break;
2449 }
cristy947cb4c2011-10-20 18:41:46 +00002450 if ((LocaleCompare("gaussian-blur",argv[0]+1) == 0) ||
2451 (LocaleCompare("gaussian",argv[0]+1) == 0))
anthony805a2d42011-09-25 08:25:12 +00002452 {
cristy6fccee12011-10-20 18:43:18 +00002453 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002454 flags=ParseGeometry(argv[1],&geometry_info);
2455 if ((flags & SigmaValue) == 0)
2456 geometry_info.sigma=1.0;
2457 if ((flags & XiValue) == 0)
2458 geometry_info.xi=0.0;
2459 new_image=GaussianBlurImage(*image,geometry_info.rho,
2460 geometry_info.sigma,geometry_info.xi,exception);
2461 break;
2462 }
cristy947cb4c2011-10-20 18:41:46 +00002463 if (LocaleCompare("geometry",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002464 {
2465 /*
anthony6613bf32011-10-15 07:24:44 +00002466 Record Image offset for composition,
2467 Resize last image. -- FUTURE depreciate this aspect
anthony805a2d42011-09-25 08:25:12 +00002468 */
cristy6fccee12011-10-20 18:43:18 +00002469 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002470 if (*argv[0] == '+')
2471 {
2472 if ((*image)->geometry != (char *) NULL)
2473 (*image)->geometry=DestroyString((*image)->geometry);
2474 break;
2475 }
2476 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2477 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2478 (void) CloneString(&(*image)->geometry,argv[1]);
2479 else
2480 new_image=ResizeImage(*image,geometry.width,geometry.height,
2481 (*image)->filter,(*image)->blur,exception);
2482 break;
2483 }
anthony805a2d42011-09-25 08:25:12 +00002484 break;
2485 }
2486 case 'h':
2487 {
cristy947cb4c2011-10-20 18:41:46 +00002488 if (LocaleCompare("highlight-color",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002489 {
cristy947cb4c2011-10-20 18:41:46 +00002490 (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00002491 break;
2492 }
2493 break;
2494 }
2495 case 'i':
2496 {
cristy947cb4c2011-10-20 18:41:46 +00002497 if (LocaleCompare("identify",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002498 {
2499 char
2500 *text;
2501
cristy6fccee12011-10-20 18:43:18 +00002502 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002503 if (format == (char *) NULL)
2504 {
2505 (void) IdentifyImage(*image,stdout,image_info->verbose,
2506 exception);
2507 break;
2508 }
2509 text=InterpretImageProperties(image_info,*image,format,
2510 exception);
2511 if (text == (char *) NULL)
2512 break;
2513 (void) fputs(text,stdout);
2514 (void) fputc('\n',stdout);
2515 text=DestroyString(text);
2516 break;
2517 }
cristy947cb4c2011-10-20 18:41:46 +00002518 if (LocaleCompare("implode",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002519 {
cristy947cb4c2011-10-20 18:41:46 +00002520 /*
2521 Implode image.
2522 */
cristy6fccee12011-10-20 18:43:18 +00002523 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002524 (void) ParseGeometry(argv[1],&geometry_info);
anthonya89dd172011-10-04 13:29:35 +00002525 new_image=ImplodeImage(*image,geometry_info.rho,
2526 interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00002527 break;
2528 }
cristy947cb4c2011-10-20 18:41:46 +00002529 if (LocaleCompare("interline-spacing",argv[0]+1) == 0)
2530 {
2531 if (*argv[0] == '+')
2532 (void) ParseGeometry("0",&geometry_info);
2533 else
2534 (void) ParseGeometry(argv[1],&geometry_info);
2535 draw_info->interline_spacing=geometry_info.rho;
2536 break;
2537 }
2538 if (LocaleCompare("interpolate",argv[0]+1) == 0)
2539 {
2540 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
2541 MagickInterpolateOptions,MagickFalse,argv[1]);
2542 break;
2543 }
2544 if (LocaleCompare("interword-spacing",argv[0]+1) == 0)
2545 {
2546 if (*argv[0] == '+')
2547 (void) ParseGeometry("0",&geometry_info);
2548 else
2549 (void) ParseGeometry(argv[1],&geometry_info);
2550 draw_info->interword_spacing=geometry_info.rho;
2551 break;
2552 }
2553 break;
2554 }
2555 case 'k':
2556 {
2557 if (LocaleCompare("kerning",argv[0]+1) == 0)
2558 {
2559 if (*argv[0] == '+')
2560 (void) ParseGeometry("0",&geometry_info);
2561 else
2562 (void) ParseGeometry(argv[1],&geometry_info);
2563 draw_info->kerning=geometry_info.rho;
2564 break;
2565 }
anthony805a2d42011-09-25 08:25:12 +00002566 break;
2567 }
2568 case 'l':
2569 {
cristy947cb4c2011-10-20 18:41:46 +00002570 if (LocaleCompare("lat",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002571 {
2572 /*
2573 Local adaptive threshold image.
2574 */
cristy6fccee12011-10-20 18:43:18 +00002575 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002576 flags=ParseGeometry(argv[1],&geometry_info);
2577 if ((flags & PercentValue) != 0)
2578 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2579 new_image=AdaptiveThresholdImage(*image,(size_t)
2580 geometry_info.rho,(size_t) geometry_info.sigma,(double)
2581 geometry_info.xi,exception);
2582 break;
2583 }
cristy947cb4c2011-10-20 18:41:46 +00002584 if (LocaleCompare("level",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002585 {
2586 MagickRealType
2587 black_point,
2588 gamma,
2589 white_point;
2590
2591 MagickStatusType
2592 flags;
2593
cristy947cb4c2011-10-20 18:41:46 +00002594 /*
2595 Parse levels.
2596 */
cristy6fccee12011-10-20 18:43:18 +00002597 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002598 flags=ParseGeometry(argv[1],&geometry_info);
2599 black_point=geometry_info.rho;
2600 white_point=(MagickRealType) QuantumRange;
2601 if ((flags & SigmaValue) != 0)
2602 white_point=geometry_info.sigma;
2603 gamma=1.0;
2604 if ((flags & XiValue) != 0)
2605 gamma=geometry_info.xi;
2606 if ((flags & PercentValue) != 0)
2607 {
2608 black_point*=(MagickRealType) (QuantumRange/100.0);
2609 white_point*=(MagickRealType) (QuantumRange/100.0);
2610 }
2611 if ((flags & SigmaValue) == 0)
2612 white_point=(MagickRealType) QuantumRange-black_point;
2613 if ((*argv[0] == '+') || ((flags & AspectValue) != 0))
2614 (void) LevelizeImage(*image,black_point,white_point,gamma,
2615 exception);
2616 else
2617 (void) LevelImage(*image,black_point,white_point,gamma,
2618 exception);
anthony805a2d42011-09-25 08:25:12 +00002619 break;
2620 }
cristy947cb4c2011-10-20 18:41:46 +00002621 if (LocaleCompare("level-colors",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002622 {
2623 char
2624 token[MaxTextExtent];
2625
2626 const char
2627 *p;
2628
2629 PixelInfo
2630 black_point,
2631 white_point;
2632
2633 p=(const char *) argv[1];
2634 GetMagickToken(p,&p,token); /* get black point color */
2635 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002636 (void) QueryColorCompliance(token,AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002637 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002638 else
cristy269c9412011-10-13 23:41:15 +00002639 (void) QueryColorCompliance("#000000",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002640 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002641 if (isalpha((int) token[0]) || (token[0] == '#'))
2642 GetMagickToken(p,&p,token);
2643 if (*token == '\0')
2644 white_point=black_point; /* set everything to that color */
2645 else
2646 {
2647 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2648 GetMagickToken(p,&p,token); /* Get white point color. */
2649 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002650 (void) QueryColorCompliance(token,AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002651 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002652 else
cristy269c9412011-10-13 23:41:15 +00002653 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002654 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002655 }
2656 (void) LevelImageColors(*image,&black_point,&white_point,
2657 *argv[0] == '+' ? MagickTrue : MagickFalse,exception);
2658 break;
2659 }
cristy947cb4c2011-10-20 18:41:46 +00002660 if (LocaleCompare("linear-stretch",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002661 {
2662 double
2663 black_point,
2664 white_point;
2665
2666 MagickStatusType
2667 flags;
2668
cristy6fccee12011-10-20 18:43:18 +00002669 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002670 flags=ParseGeometry(argv[1],&geometry_info);
2671 black_point=geometry_info.rho;
2672 white_point=(MagickRealType) (*image)->columns*(*image)->rows;
2673 if ((flags & SigmaValue) != 0)
2674 white_point=geometry_info.sigma;
2675 if ((flags & PercentValue) != 0)
2676 {
2677 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2678 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2679 }
2680 if ((flags & SigmaValue) == 0)
2681 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2682 black_point;
2683 (void) LinearStretchImage(*image,black_point,white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002684 break;
2685 }
cristy947cb4c2011-10-20 18:41:46 +00002686 if (LocaleCompare("linewidth",argv[0]+1) == 0)
2687 {
2688 draw_info->stroke_width=InterpretLocaleValue(argv[1],
2689 (char **) NULL);
2690 break;
2691 }
2692 if (LocaleCompare("liquid-rescale",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002693 {
2694 /*
2695 Liquid rescale image.
2696 */
cristy6fccee12011-10-20 18:43:18 +00002697 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002698 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2699 if ((flags & XValue) == 0)
2700 geometry.x=1;
2701 if ((flags & YValue) == 0)
2702 geometry.y=0;
2703 new_image=LiquidRescaleImage(*image,geometry.width,
2704 geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
2705 break;
2706 }
cristy947cb4c2011-10-20 18:41:46 +00002707 if (LocaleCompare("lowlight-color",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002708 {
cristy947cb4c2011-10-20 18:41:46 +00002709 (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00002710 break;
2711 }
2712 break;
2713 }
2714 case 'm':
2715 {
cristy947cb4c2011-10-20 18:41:46 +00002716 if (LocaleCompare("map",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002717 {
2718 Image
2719 *remap_image;
2720
cristy947cb4c2011-10-20 18:41:46 +00002721 /*
2722 Transform image colors to match this set of colors.
2723 */
cristy6fccee12011-10-20 18:43:18 +00002724 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002725 if (*argv[0] == '+')
2726 break;
2727 remap_image=GetImageCache(image_info,argv[1],exception);
2728 if (remap_image == (Image *) NULL)
2729 break;
2730 (void) RemapImage(quantize_info,*image,remap_image,exception);
2731 remap_image=DestroyImage(remap_image);
2732 break;
2733 }
cristy947cb4c2011-10-20 18:41:46 +00002734 if (LocaleCompare("mask",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002735 {
2736 Image
2737 *mask;
2738
cristy6fccee12011-10-20 18:43:18 +00002739 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002740 if (*argv[0] == '+')
2741 {
cristy947cb4c2011-10-20 18:41:46 +00002742 /*
2743 Remove a mask.
2744 */
anthony805a2d42011-09-25 08:25:12 +00002745 (void) SetImageMask(*image,(Image *) NULL,exception);
2746 break;
2747 }
cristy947cb4c2011-10-20 18:41:46 +00002748 /*
2749 Set the image mask.
2750 */
anthony805a2d42011-09-25 08:25:12 +00002751 mask=GetImageCache(image_info,argv[1],exception);
2752 if (mask == (Image *) NULL)
2753 break;
2754 (void) SetImageMask(*image,mask,exception);
2755 mask=DestroyImage(mask);
2756 break;
2757 }
cristy947cb4c2011-10-20 18:41:46 +00002758 if (LocaleCompare("matte",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002759 {
cristy947cb4c2011-10-20 18:41:46 +00002760 (void) SetImageAlphaChannel(*image,(*argv[0] == '-') ?
2761 SetAlphaChannel : DeactivateAlphaChannel,exception);
anthony805a2d42011-09-25 08:25:12 +00002762 break;
2763 }
cristy947cb4c2011-10-20 18:41:46 +00002764 if (LocaleCompare("median",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002765 {
cristy947cb4c2011-10-20 18:41:46 +00002766 /*
2767 Median filter image.
2768 */
cristy6fccee12011-10-20 18:43:18 +00002769 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002770 flags=ParseGeometry(argv[1],&geometry_info);
2771 if ((flags & SigmaValue) == 0)
2772 geometry_info.sigma=geometry_info.rho;
2773 new_image=StatisticImage(*image,MedianStatistic,(size_t)
2774 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2775 break;
2776 }
cristy947cb4c2011-10-20 18:41:46 +00002777 if (LocaleCompare("mode",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002778 {
2779 /*
cristy947cb4c2011-10-20 18:41:46 +00002780 Mode image.
anthony805a2d42011-09-25 08:25:12 +00002781 */
cristy6fccee12011-10-20 18:43:18 +00002782 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002783 flags=ParseGeometry(argv[1],&geometry_info);
2784 if ((flags & SigmaValue) == 0)
2785 geometry_info.sigma=geometry_info.rho;
2786 new_image=StatisticImage(*image,ModeStatistic,(size_t)
2787 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2788 break;
2789 }
cristy947cb4c2011-10-20 18:41:46 +00002790 if (LocaleCompare("modulate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002791 {
cristy6fccee12011-10-20 18:43:18 +00002792 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002793 (void) ModulateImage(*image,argv[1],exception);
2794 break;
2795 }
cristy947cb4c2011-10-20 18:41:46 +00002796 if (LocaleCompare("monitor",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002797 {
anthonyafbaed72011-10-26 12:05:04 +00002798 /* FUTURE: Why is this a per-image setting? */
anthony805a2d42011-09-25 08:25:12 +00002799 if (*argv[0] == '+')
2800 {
2801 (void) SetImageProgressMonitor(*image,
2802 (MagickProgressMonitor) NULL,(void *) NULL);
2803 break;
2804 }
2805 (void) SetImageProgressMonitor(*image,MonitorProgress,
2806 (void *) NULL);
2807 break;
2808 }
cristy947cb4c2011-10-20 18:41:46 +00002809 if (LocaleCompare("monochrome",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002810 {
cristy6fccee12011-10-20 18:43:18 +00002811 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002812 (void) SetImageType(*image,BilevelType,exception);
2813 break;
2814 }
cristy947cb4c2011-10-20 18:41:46 +00002815 if (LocaleCompare("morphology",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002816 {
2817 char
2818 token[MaxTextExtent];
2819
2820 const char
2821 *p;
2822
2823 KernelInfo
2824 *kernel;
2825
2826 MorphologyMethod
2827 method;
2828
2829 ssize_t
2830 iterations;
2831
cristy6fccee12011-10-20 18:43:18 +00002832 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002833 p=argv[1];
2834 GetMagickToken(p,&p,token);
2835 method=(MorphologyMethod) ParseCommandOption(
2836 MagickMorphologyOptions,MagickFalse,token);
2837 iterations=1L;
2838 GetMagickToken(p,&p,token);
2839 if ((*p == ':') || (*p == ','))
2840 GetMagickToken(p,&p,token);
2841 if ((*p != '\0'))
2842 iterations=(ssize_t) StringToLong(p);
2843 kernel=AcquireKernelInfo(argv[2]);
2844 if (kernel == (KernelInfo *) NULL)
2845 {
2846 (void) ThrowMagickException(exception,GetMagickModule(),
2847 OptionError,"UnabletoParseKernel","morphology");
2848 status=MagickFalse;
2849 break;
2850 }
2851 new_image=MorphologyImage(*image,method,iterations,kernel,
2852 exception);
2853 kernel=DestroyKernelInfo(kernel);
2854 break;
2855 }
cristy947cb4c2011-10-20 18:41:46 +00002856 if (LocaleCompare("motion-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002857 {
cristy947cb4c2011-10-20 18:41:46 +00002858 /*
2859 Motion blur image.
2860 */
cristy6fccee12011-10-20 18:43:18 +00002861 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002862 flags=ParseGeometry(argv[1],&geometry_info);
2863 if ((flags & SigmaValue) == 0)
2864 geometry_info.sigma=1.0;
2865 new_image=MotionBlurImage(*image,geometry_info.rho,
2866 geometry_info.sigma,geometry_info.xi,geometry_info.psi,
2867 exception);
2868 break;
2869 }
2870 break;
2871 }
2872 case 'n':
2873 {
cristy947cb4c2011-10-20 18:41:46 +00002874 if (LocaleCompare("negate",argv[0]+1) == 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 (void) NegateImage(*image,*argv[0] == '+' ? MagickTrue :
2878 MagickFalse,exception);
2879 break;
2880 }
cristy947cb4c2011-10-20 18:41:46 +00002881 if (LocaleCompare("noise",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002882 {
cristy6fccee12011-10-20 18:43:18 +00002883 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002884 if (*argv[0] == '-')
2885 {
2886 flags=ParseGeometry(argv[1],&geometry_info);
2887 if ((flags & SigmaValue) == 0)
2888 geometry_info.sigma=geometry_info.rho;
2889 new_image=StatisticImage(*image,NonpeakStatistic,(size_t)
2890 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2891 }
2892 else
2893 {
2894 NoiseType
2895 noise;
2896
2897 noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
2898 MagickFalse,argv[1]);
anthony5f867ae2011-10-09 10:28:34 +00002899 new_image=AddNoiseImage(*image,noise,exception);
anthony805a2d42011-09-25 08:25:12 +00002900 }
2901 break;
2902 }
cristy947cb4c2011-10-20 18:41:46 +00002903 if (LocaleCompare("normalize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002904 {
cristy6fccee12011-10-20 18:43:18 +00002905 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002906 (void) NormalizeImage(*image,exception);
2907 break;
2908 }
2909 break;
2910 }
2911 case 'o':
2912 {
cristy947cb4c2011-10-20 18:41:46 +00002913 if (LocaleCompare("opaque",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002914 {
2915 PixelInfo
2916 target;
2917
cristy6fccee12011-10-20 18:43:18 +00002918 (void) SyncImageSettings(image_info,*image,exception);
cristy269c9412011-10-13 23:41:15 +00002919 (void) QueryColorCompliance(argv[1],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00002920 exception);
anthony805a2d42011-09-25 08:25:12 +00002921 (void) OpaquePaintImage(*image,&target,&fill,*argv[0] == '-' ?
2922 MagickFalse : MagickTrue,exception);
2923 break;
2924 }
cristy947cb4c2011-10-20 18:41:46 +00002925 if (LocaleCompare("ordered-dither",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002926 {
cristy6fccee12011-10-20 18:43:18 +00002927 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002928 (void) OrderedPosterizeImage(*image,argv[1],exception);
2929 break;
2930 }
2931 break;
2932 }
2933 case 'p':
2934 {
cristy947cb4c2011-10-20 18:41:46 +00002935 if (LocaleCompare("paint",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002936 {
cristy6fccee12011-10-20 18:43:18 +00002937 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002938 (void) ParseGeometry(argv[1],&geometry_info);
2939 new_image=OilPaintImage(*image,geometry_info.rho,
2940 geometry_info.sigma,exception);
2941 break;
2942 }
cristy947cb4c2011-10-20 18:41:46 +00002943 if (LocaleCompare("pen",argv[0]+1) == 0)
2944 {
2945 if (*argv[0] == '+')
2946 {
2947 (void) QueryColorCompliance("none",AllCompliance,&draw_info->fill,
2948 exception);
2949 break;
2950 }
2951 (void) QueryColorCompliance(argv[1],AllCompliance,&draw_info->fill,
2952 exception);
2953 break;
2954 }
2955 if (LocaleCompare("pointsize",argv[0]+1) == 0)
2956 {
2957 if (*argv[0] == '+')
2958 (void) ParseGeometry("12",&geometry_info);
2959 else
2960 (void) ParseGeometry(argv[1],&geometry_info);
2961 draw_info->pointsize=geometry_info.rho;
2962 break;
2963 }
2964 if (LocaleCompare("polaroid",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002965 {
2966 double
2967 angle;
2968
2969 RandomInfo
2970 *random_info;
2971
cristy947cb4c2011-10-20 18:41:46 +00002972 /*
2973 Simulate a Polaroid picture.
2974 */
cristy6fccee12011-10-20 18:43:18 +00002975 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002976 random_info=AcquireRandomInfo();
2977 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2978 random_info=DestroyRandomInfo(random_info);
2979 if (*argv[0] == '-')
2980 {
2981 SetGeometryInfo(&geometry_info);
2982 flags=ParseGeometry(argv[1],&geometry_info);
2983 angle=geometry_info.rho;
2984 }
2985 new_image=PolaroidImage(*image,draw_info,angle,
2986 interpolate_method,exception);
2987 break;
2988 }
cristy947cb4c2011-10-20 18:41:46 +00002989 if (LocaleCompare("posterize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002990 {
cristy947cb4c2011-10-20 18:41:46 +00002991 /*
2992 Posterize image.
2993 */
cristy6fccee12011-10-20 18:43:18 +00002994 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002995 (void) PosterizeImage(*image,StringToUnsignedLong(argv[1]),
2996 quantize_info->dither,exception);
2997 break;
2998 }
cristy947cb4c2011-10-20 18:41:46 +00002999 if (LocaleCompare("preview",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003000 {
3001 PreviewType
cristy947cb4c2011-10-20 18:41:46 +00003002 preview_type;
anthony170fce92011-10-20 11:50:23 +00003003
cristy947cb4c2011-10-20 18:41:46 +00003004 /*
3005 Preview image.
3006 */
cristy6fccee12011-10-20 18:43:18 +00003007 (void) SyncImageSettings(image_info,*image,exception);
cristy947cb4c2011-10-20 18:41:46 +00003008 if (*argv[0] == '+')
3009 preview_type=UndefinedPreview;
3010 else
anthony805a2d42011-09-25 08:25:12 +00003011 preview_type=(PreviewType) ParseCommandOption(
3012 MagickPreviewOptions,MagickFalse,argv[1]);
3013 new_image=PreviewImage(*image,preview_type,exception);
3014 break;
3015 }
cristy947cb4c2011-10-20 18:41:46 +00003016 if (LocaleCompare("profile",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003017 {
3018 const char
3019 *name;
3020
3021 const StringInfo
3022 *profile;
3023
3024 Image
3025 *profile_image;
3026
3027 ImageInfo
3028 *profile_info;
3029
cristy6fccee12011-10-20 18:43:18 +00003030 (void) SyncImageSettings(image_info,*image,exception);
cristy947cb4c2011-10-20 18:41:46 +00003031 if (*argv[0] == '+')
anthony805a2d42011-09-25 08:25:12 +00003032 {
cristy947cb4c2011-10-20 18:41:46 +00003033 /*
3034 Remove a profile from the image.
3035 */
anthony805a2d42011-09-25 08:25:12 +00003036 (void) ProfileImage(*image,argv[1],(const unsigned char *)
cristy092d71c2011-10-14 18:01:29 +00003037 NULL,0,exception);
anthony805a2d42011-09-25 08:25:12 +00003038 break;
3039 }
cristy947cb4c2011-10-20 18:41:46 +00003040 /*
3041 Associate a profile with the image.
3042 */
anthony805a2d42011-09-25 08:25:12 +00003043 profile_info=CloneImageInfo(image_info);
3044 profile=GetImageProfile(*image,"iptc");
3045 if (profile != (StringInfo *) NULL)
3046 profile_info->profile=(void *) CloneStringInfo(profile);
3047 profile_image=GetImageCache(profile_info,argv[1],exception);
3048 profile_info=DestroyImageInfo(profile_info);
3049 if (profile_image == (Image *) NULL)
3050 {
3051 StringInfo
3052 *profile;
3053
3054 profile_info=CloneImageInfo(image_info);
3055 (void) CopyMagickString(profile_info->filename,argv[1],
3056 MaxTextExtent);
3057 profile=FileToStringInfo(profile_info->filename,~0UL,exception);
3058 if (profile != (StringInfo *) NULL)
3059 {
3060 (void) ProfileImage(*image,profile_info->magick,
3061 GetStringInfoDatum(profile),(size_t)
cristy092d71c2011-10-14 18:01:29 +00003062 GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003063 profile=DestroyStringInfo(profile);
3064 }
3065 profile_info=DestroyImageInfo(profile_info);
3066 break;
3067 }
3068 ResetImageProfileIterator(profile_image);
3069 name=GetNextImageProfile(profile_image);
3070 while (name != (const char *) NULL)
3071 {
3072 profile=GetImageProfile(profile_image,name);
3073 if (profile != (StringInfo *) NULL)
3074 (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
cristy092d71c2011-10-14 18:01:29 +00003075 (size_t) GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003076 name=GetNextImageProfile(profile_image);
3077 }
3078 profile_image=DestroyImage(profile_image);
3079 break;
3080 }
3081 break;
3082 }
cristy947cb4c2011-10-20 18:41:46 +00003083 case 'q':
3084 {
3085 if (LocaleCompare("quantize",argv[0]+1) == 0)
3086 {
3087 if (*argv[0] == '+')
3088 {
3089 quantize_info->colorspace=UndefinedColorspace;
3090 break;
3091 }
3092 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
3093 MagickColorspaceOptions,MagickFalse,argv[1]);
3094 break;
3095 }
3096 break;
3097 }
anthony805a2d42011-09-25 08:25:12 +00003098 case 'r':
3099 {
cristy947cb4c2011-10-20 18:41:46 +00003100 if (LocaleCompare("radial-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003101 {
cristy6fccee12011-10-20 18:43:18 +00003102 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003103 flags=ParseGeometry(argv[1],&geometry_info);
3104 new_image=RadialBlurImage(*image,geometry_info.rho,
3105 geometry_info.sigma,exception);
3106 break;
3107 }
cristy947cb4c2011-10-20 18:41:46 +00003108 if (LocaleCompare("raise",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003109 {
anthony805a2d42011-09-25 08:25:12 +00003110 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3111 if ((flags & SigmaValue) == 0)
3112 geometry.height=geometry.width;
3113 (void) RaiseImage(*image,&geometry,*argv[0] == '-' ? MagickTrue :
3114 MagickFalse,exception);
3115 break;
3116 }
cristy947cb4c2011-10-20 18:41:46 +00003117 if (LocaleCompare("random-threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003118 {
cristy6fccee12011-10-20 18:43:18 +00003119 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003120 (void) RandomThresholdImage(*image,argv[1],exception);
3121 break;
3122 }
cristy947cb4c2011-10-20 18:41:46 +00003123 if (LocaleCompare("recolor",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003124 {
3125 KernelInfo
3126 *kernel;
3127
cristy6fccee12011-10-20 18:43:18 +00003128 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003129 kernel=AcquireKernelInfo(argv[1]);
3130 if (kernel == (KernelInfo *) NULL)
3131 break;
3132 new_image=ColorMatrixImage(*image,kernel,exception);
3133 kernel=DestroyKernelInfo(kernel);
3134 break;
3135 }
cristy947cb4c2011-10-20 18:41:46 +00003136 if (LocaleCompare("remap",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003137 {
3138 Image
3139 *remap_image;
3140
cristy6fccee12011-10-20 18:43:18 +00003141 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003142 if (*argv[0] == '+')
3143 break;
3144 remap_image=GetImageCache(image_info,argv[1],exception);
3145 if (remap_image == (Image *) NULL)
3146 break;
3147 (void) RemapImage(quantize_info,*image,remap_image,exception);
3148 remap_image=DestroyImage(remap_image);
3149 break;
3150 }
cristy947cb4c2011-10-20 18:41:46 +00003151 if (LocaleCompare("repage",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003152 {
3153 if (*argv[0] == '+')
3154 {
3155 (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
3156 break;
3157 }
3158 (void) ResetImagePage(*image,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00003159 break;
3160 }
cristy947cb4c2011-10-20 18:41:46 +00003161 if (LocaleCompare("resample",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003162 {
anthonyafbaed72011-10-26 12:05:04 +00003163 /* FUTURE: remove blur - no longer used */
cristy6fccee12011-10-20 18:43:18 +00003164 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003165 flags=ParseGeometry(argv[1],&geometry_info);
3166 if ((flags & SigmaValue) == 0)
3167 geometry_info.sigma=geometry_info.rho;
3168 new_image=ResampleImage(*image,geometry_info.rho,
3169 geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
3170 break;
3171 }
cristy947cb4c2011-10-20 18:41:46 +00003172 if (LocaleCompare("resize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003173 {
anthonyafbaed72011-10-26 12:05:04 +00003174 /* FUTURE: remove blur argument - no longer used */
cristy6fccee12011-10-20 18:43:18 +00003175 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003176 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3177 new_image=ResizeImage(*image,geometry.width,geometry.height,
3178 (*image)->filter,(*image)->blur,exception);
3179 break;
3180 }
cristy947cb4c2011-10-20 18:41:46 +00003181 if (LocaleCompare("roll",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003182 {
cristy6fccee12011-10-20 18:43:18 +00003183 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003184 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
3185 new_image=RollImage(*image,geometry.x,geometry.y,exception);
3186 break;
3187 }
cristy947cb4c2011-10-20 18:41:46 +00003188 if (LocaleCompare("rotate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003189 {
anthonyafbaed72011-10-26 12:05:04 +00003190 /* special case rotation flags */
cristy6fccee12011-10-20 18:43:18 +00003191 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003192 if (strchr(argv[1],'>') != (char *) NULL)
3193 if ((*image)->columns <= (*image)->rows)
3194 break;
3195 if (strchr(argv[1],'<') != (char *) NULL)
3196 if ((*image)->columns >= (*image)->rows)
3197 break;
anthonyafbaed72011-10-26 12:05:04 +00003198
3199 (void) ParseGeometry(argv[1],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003200 new_image=RotateImage(*image,geometry_info.rho,exception);
3201 break;
3202 }
3203 break;
3204 }
3205 case 's':
3206 {
cristy947cb4c2011-10-20 18:41:46 +00003207 if (LocaleCompare("sample",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003208 {
cristy6fccee12011-10-20 18:43:18 +00003209 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003210 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3211 new_image=SampleImage(*image,geometry.width,geometry.height,
3212 exception);
3213 break;
3214 }
cristy947cb4c2011-10-20 18:41:46 +00003215 if (LocaleCompare("scale",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003216 {
cristy6fccee12011-10-20 18:43:18 +00003217 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003218 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3219 new_image=ScaleImage(*image,geometry.width,geometry.height,
3220 exception);
3221 break;
3222 }
cristy947cb4c2011-10-20 18:41:46 +00003223 if (LocaleCompare("selective-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003224 {
cristy6fccee12011-10-20 18:43:18 +00003225 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003226 flags=ParseGeometry(argv[1],&geometry_info);
3227 if ((flags & PercentValue) != 0)
3228 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3229 new_image=SelectiveBlurImage(*image,geometry_info.rho,
3230 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3231 break;
3232 }
cristy947cb4c2011-10-20 18:41:46 +00003233 if (LocaleCompare("separate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003234 {
3235 /*
3236 Break channels into separate images.
3237 WARNING: This can generate multiple images!
3238 */
cristy6fccee12011-10-20 18:43:18 +00003239 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003240 new_image=SeparateImages(*image,exception);
3241 break;
3242 }
cristy947cb4c2011-10-20 18:41:46 +00003243 if (LocaleCompare("sepia-tone",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003244 {
3245 double
3246 threshold;
3247
cristy6fccee12011-10-20 18:43:18 +00003248 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003249 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3250 new_image=SepiaToneImage(*image,threshold,exception);
3251 break;
3252 }
cristy947cb4c2011-10-20 18:41:46 +00003253 if (LocaleCompare("segment",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003254 {
cristy6fccee12011-10-20 18:43:18 +00003255 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003256 flags=ParseGeometry(argv[1],&geometry_info);
3257 if ((flags & SigmaValue) == 0)
3258 geometry_info.sigma=1.0;
3259 (void) SegmentImage(*image,(*image)->colorspace,
3260 image_info->verbose,geometry_info.rho,geometry_info.sigma,
3261 exception);
3262 break;
3263 }
cristy947cb4c2011-10-20 18:41:46 +00003264 if (LocaleCompare("set",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003265 {
3266 char
3267 *value;
3268
anthony805a2d42011-09-25 08:25:12 +00003269 if (*argv[0] == '+')
3270 {
3271 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3272 (void) DeleteImageRegistry(argv[1]+9);
3273 else
3274 if (LocaleNCompare(argv[1],"argv[0]:",7) == 0)
3275 {
3276 (void) DeleteImageOption(image_info,argv[1]+7);
3277 (void) DeleteImageArtifact(*image,argv[1]+7);
3278 }
3279 else
3280 (void) DeleteImageProperty(*image,argv[1]);
3281 break;
3282 }
3283 value=InterpretImageProperties(image_info,*image,argv[2],
3284 exception);
3285 if (value == (char *) NULL)
3286 break;
3287 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3288 (void) SetImageRegistry(StringRegistryType,argv[1]+9,value,
3289 exception);
3290 else
anthonya89dd172011-10-04 13:29:35 +00003291 if (LocaleNCompare(argv[1],"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003292 {
3293 (void) SetImageOption(image_info,argv[1]+7,value);
anthony805a2d42011-09-25 08:25:12 +00003294 (void) SetImageArtifact(*image,argv[1]+7,value);
3295 }
3296 else
cristyd15e6592011-10-15 00:13:06 +00003297 (void) SetImageProperty(*image,argv[1],value,exception);
anthony805a2d42011-09-25 08:25:12 +00003298 value=DestroyString(value);
3299 break;
3300 }
cristy947cb4c2011-10-20 18:41:46 +00003301 if (LocaleCompare("shade",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003302 {
cristy6fccee12011-10-20 18:43:18 +00003303 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003304 flags=ParseGeometry(argv[1],&geometry_info);
3305 if ((flags & SigmaValue) == 0)
3306 geometry_info.sigma=1.0;
3307 new_image=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue :
3308 MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
3309 break;
3310 }
cristy947cb4c2011-10-20 18:41:46 +00003311 if (LocaleCompare("shadow",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003312 {
cristy6fccee12011-10-20 18:43:18 +00003313 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003314 flags=ParseGeometry(argv[1],&geometry_info);
3315 if ((flags & SigmaValue) == 0)
3316 geometry_info.sigma=1.0;
3317 if ((flags & XiValue) == 0)
3318 geometry_info.xi=4.0;
3319 if ((flags & PsiValue) == 0)
3320 geometry_info.psi=4.0;
3321 new_image=ShadowImage(*image,geometry_info.rho,
3322 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3323 ceil(geometry_info.psi-0.5),exception);
3324 break;
3325 }
cristy947cb4c2011-10-20 18:41:46 +00003326 if (LocaleCompare("sharpen",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003327 {
cristy6fccee12011-10-20 18:43:18 +00003328 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003329 flags=ParseGeometry(argv[1],&geometry_info);
3330 if ((flags & SigmaValue) == 0)
3331 geometry_info.sigma=1.0;
3332 if ((flags & XiValue) == 0)
3333 geometry_info.xi=0.0;
3334 new_image=SharpenImage(*image,geometry_info.rho,
3335 geometry_info.sigma,geometry_info.xi,exception);
3336 break;
3337 }
cristy947cb4c2011-10-20 18:41:46 +00003338 if (LocaleCompare("shave",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003339 {
cristy6fccee12011-10-20 18:43:18 +00003340 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003341 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3342 new_image=ShaveImage(*image,&geometry,exception);
3343 break;
3344 }
cristy947cb4c2011-10-20 18:41:46 +00003345 if (LocaleCompare("shear",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003346 {
cristy6fccee12011-10-20 18:43:18 +00003347 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003348 flags=ParseGeometry(argv[1],&geometry_info);
3349 if ((flags & SigmaValue) == 0)
3350 geometry_info.sigma=geometry_info.rho;
3351 new_image=ShearImage(*image,geometry_info.rho,
3352 geometry_info.sigma,exception);
3353 break;
3354 }
cristy947cb4c2011-10-20 18:41:46 +00003355 if (LocaleCompare("sigmoidal-contrast",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003356 {
cristy6fccee12011-10-20 18:43:18 +00003357 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003358 flags=ParseGeometry(argv[1],&geometry_info);
3359 if ((flags & SigmaValue) == 0)
3360 geometry_info.sigma=(double) QuantumRange/2.0;
3361 if ((flags & PercentValue) != 0)
3362 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3363 100.0;
3364 (void) SigmoidalContrastImage(*image,(*argv[0] == '-') ?
3365 MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
3366 exception);
3367 break;
3368 }
cristy947cb4c2011-10-20 18:41:46 +00003369 if (LocaleCompare("sketch",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003370 {
cristy6fccee12011-10-20 18:43:18 +00003371 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003372 flags=ParseGeometry(argv[1],&geometry_info);
3373 if ((flags & SigmaValue) == 0)
3374 geometry_info.sigma=1.0;
3375 new_image=SketchImage(*image,geometry_info.rho,
3376 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3377 break;
3378 }
cristy947cb4c2011-10-20 18:41:46 +00003379 if (LocaleCompare("solarize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003380 {
3381 double
3382 threshold;
3383
cristy6fccee12011-10-20 18:43:18 +00003384 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003385 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3386 (void) SolarizeImage(*image,threshold,exception);
3387 break;
3388 }
cristy947cb4c2011-10-20 18:41:46 +00003389 if (LocaleCompare("sparse-color",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003390 {
3391 SparseColorMethod
3392 method;
3393
3394 char
3395 *arguments;
3396
cristy6fccee12011-10-20 18:43:18 +00003397 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003398 method=(SparseColorMethod) ParseCommandOption(
3399 MagickSparseColorOptions,MagickFalse,argv[1]);
3400 arguments=InterpretImageProperties(image_info,*image,argv[2],
3401 exception);
3402 if (arguments == (char *) NULL)
3403 break;
3404 new_image=SparseColorOption(*image,method,arguments,
3405 argv[0][0] == '+' ? MagickTrue : MagickFalse,exception);
3406 arguments=DestroyString(arguments);
3407 break;
3408 }
cristy947cb4c2011-10-20 18:41:46 +00003409 if (LocaleCompare("splice",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003410 {
cristy6fccee12011-10-20 18:43:18 +00003411 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003412 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
3413 new_image=SpliceImage(*image,&geometry,exception);
3414 break;
3415 }
cristy947cb4c2011-10-20 18:41:46 +00003416 if (LocaleCompare("spread",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003417 {
cristy6fccee12011-10-20 18:43:18 +00003418 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003419 (void) ParseGeometry(argv[1],&geometry_info);
3420 new_image=SpreadImage(*image,geometry_info.rho,
3421 interpolate_method,exception);
3422 break;
3423 }
cristy947cb4c2011-10-20 18:41:46 +00003424 if (LocaleCompare("statistic",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003425 {
3426 StatisticType
3427 type;
3428
cristy6fccee12011-10-20 18:43:18 +00003429 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003430 type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
3431 MagickFalse,argv[1]);
3432 (void) ParseGeometry(argv[2],&geometry_info);
3433 new_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
3434 (size_t) geometry_info.sigma,exception);
3435 break;
3436 }
cristy947cb4c2011-10-20 18:41:46 +00003437 if (LocaleCompare("strip",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003438 {
cristy6fccee12011-10-20 18:43:18 +00003439 (void) SyncImageSettings(image_info,*image,exception);
anthony6613bf32011-10-15 07:24:44 +00003440 (void) StripImage(*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003441 break;
3442 }
cristy947cb4c2011-10-20 18:41:46 +00003443 if (LocaleCompare("swirl",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003444 {
cristy6fccee12011-10-20 18:43:18 +00003445 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003446 (void) ParseGeometry(argv[1],&geometry_info);
3447 new_image=SwirlImage(*image,geometry_info.rho,
3448 interpolate_method,exception);
3449 break;
3450 }
3451 break;
3452 }
3453 case 't':
3454 {
cristy947cb4c2011-10-20 18:41:46 +00003455 if (LocaleCompare("threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003456 {
3457 double
3458 threshold;
3459
cristy6fccee12011-10-20 18:43:18 +00003460 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003461 if (*argv[0] == '+')
3462 threshold=(double) QuantumRange/2;
3463 else
3464 threshold=SiPrefixToDouble(argv[1],QuantumRange);
anthony6613bf32011-10-15 07:24:44 +00003465 (void) BilevelImage(*image,threshold,exception);
anthony805a2d42011-09-25 08:25:12 +00003466 break;
3467 }
cristy947cb4c2011-10-20 18:41:46 +00003468 if (LocaleCompare("thumbnail",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003469 {
3470 /*
3471 Thumbnail image.
3472 */
cristy6fccee12011-10-20 18:43:18 +00003473 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003474 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3475 new_image=ThumbnailImage(*image,geometry.width,geometry.height,
3476 exception);
3477 break;
3478 }
cristy947cb4c2011-10-20 18:41:46 +00003479 if (LocaleCompare("tint",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003480 {
cristy6fccee12011-10-20 18:43:18 +00003481 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003482 new_image=TintImage(*image,argv[1],&fill,exception);
3483 break;
3484 }
cristy947cb4c2011-10-20 18:41:46 +00003485 if (LocaleCompare("transform",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003486 {
cristy6fccee12011-10-20 18:43:18 +00003487 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003488 new_image=AffineTransformImage(*image,&draw_info->affine,
3489 exception);
3490 break;
3491 }
cristy947cb4c2011-10-20 18:41:46 +00003492 if (LocaleCompare("transparent",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003493 {
3494 PixelInfo
3495 target;
3496
cristy6fccee12011-10-20 18:43:18 +00003497 (void) SyncImageSettings(image_info,*image,exception);
cristy269c9412011-10-13 23:41:15 +00003498 (void) QueryColorCompliance(argv[1],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00003499 exception);
anthony805a2d42011-09-25 08:25:12 +00003500 (void) TransparentPaintImage(*image,&target,(Quantum)
3501 TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue,
cristy82d7af52011-10-16 16:26:41 +00003502 exception);
anthony805a2d42011-09-25 08:25:12 +00003503 break;
3504 }
cristy947cb4c2011-10-20 18:41:46 +00003505 if (LocaleCompare("transpose",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003506 {
cristy6fccee12011-10-20 18:43:18 +00003507 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003508 new_image=TransposeImage(*image,exception);
3509 break;
3510 }
cristy947cb4c2011-10-20 18:41:46 +00003511 if (LocaleCompare("transverse",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003512 {
cristy6fccee12011-10-20 18:43:18 +00003513 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003514 new_image=TransverseImage(*image,exception);
3515 break;
3516 }
cristy947cb4c2011-10-20 18:41:46 +00003517 if (LocaleCompare("treedepth",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003518 {
3519 quantize_info->tree_depth=StringToUnsignedLong(argv[1]);
3520 break;
3521 }
cristy947cb4c2011-10-20 18:41:46 +00003522 if (LocaleCompare("trim",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003523 {
cristy6fccee12011-10-20 18:43:18 +00003524 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003525 new_image=TrimImage(*image,exception);
3526 break;
3527 }
cristy947cb4c2011-10-20 18:41:46 +00003528 if (LocaleCompare("type",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003529 {
3530 ImageType
3531 type;
3532
cristy6fccee12011-10-20 18:43:18 +00003533 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003534 if (*argv[0] == '+')
3535 type=UndefinedType;
3536 else
3537 type=(ImageType) ParseCommandOption(MagickTypeOptions,MagickFalse,
3538 argv[1]);
3539 (*image)->type=UndefinedType;
3540 (void) SetImageType(*image,type,exception);
3541 break;
3542 }
3543 break;
3544 }
3545 case 'u':
3546 {
cristy947cb4c2011-10-20 18:41:46 +00003547 if (LocaleCompare("undercolor",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003548 {
anthony1afdc7a2011-10-05 11:54:28 +00003549 (void) QueryColorCompliance(argv[1],AllCompliance,&draw_info->undercolor,
anthony805a2d42011-09-25 08:25:12 +00003550 exception);
3551 break;
3552 }
cristy947cb4c2011-10-20 18:41:46 +00003553 if (LocaleCompare("unique",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003554 {
3555 if (*argv[0] == '+')
3556 {
3557 (void) DeleteImageArtifact(*image,"identify:unique-colors");
3558 break;
3559 }
3560 (void) SetImageArtifact(*image,"identify:unique-colors","true");
3561 (void) SetImageArtifact(*image,"verbose","true");
3562 break;
3563 }
cristy947cb4c2011-10-20 18:41:46 +00003564 if (LocaleCompare("unique-colors",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003565 {
3566 /*
3567 Unique image colors.
3568 */
cristy6fccee12011-10-20 18:43:18 +00003569 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003570 new_image=UniqueImageColors(*image,exception);
3571 break;
3572 }
cristy947cb4c2011-10-20 18:41:46 +00003573 if (LocaleCompare("unsharp",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003574 {
3575 /*
3576 Unsharp mask image.
3577 */
cristy6fccee12011-10-20 18:43:18 +00003578 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003579 flags=ParseGeometry(argv[1],&geometry_info);
3580 if ((flags & SigmaValue) == 0)
3581 geometry_info.sigma=1.0;
3582 if ((flags & XiValue) == 0)
3583 geometry_info.xi=1.0;
3584 if ((flags & PsiValue) == 0)
3585 geometry_info.psi=0.05;
3586 new_image=UnsharpMaskImage(*image,geometry_info.rho,
3587 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3588 break;
3589 }
3590 break;
3591 }
3592 case 'v':
3593 {
cristy947cb4c2011-10-20 18:41:46 +00003594 if (LocaleCompare("verbose",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003595 {
cristy947cb4c2011-10-20 18:41:46 +00003596 (void) SetImageArtifact(*image,argv[0]+1,
anthony805a2d42011-09-25 08:25:12 +00003597 *argv[0] == '+' ? "false" : "true");
3598 break;
3599 }
cristy947cb4c2011-10-20 18:41:46 +00003600 if (LocaleCompare("vignette",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003601 {
3602 /*
3603 Vignette image.
3604 */
cristy6fccee12011-10-20 18:43:18 +00003605 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003606 flags=ParseGeometry(argv[1],&geometry_info);
3607 if ((flags & SigmaValue) == 0)
3608 geometry_info.sigma=1.0;
3609 if ((flags & XiValue) == 0)
3610 geometry_info.xi=0.1*(*image)->columns;
3611 if ((flags & PsiValue) == 0)
3612 geometry_info.psi=0.1*(*image)->rows;
3613 new_image=VignetteImage(*image,geometry_info.rho,
3614 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3615 ceil(geometry_info.psi-0.5),exception);
3616 break;
3617 }
cristy947cb4c2011-10-20 18:41:46 +00003618 if (LocaleCompare("virtual-pixel",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003619 {
3620 if (*argv[0] == '+')
3621 {
3622 (void) SetImageVirtualPixelMethod(*image,
3623 UndefinedVirtualPixelMethod);
3624 break;
3625 }
3626 (void) SetImageVirtualPixelMethod(*image,(VirtualPixelMethod)
3627 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
3628 argv[1]));
3629 break;
3630 }
3631 break;
3632 }
3633 case 'w':
3634 {
cristy947cb4c2011-10-20 18:41:46 +00003635 if (LocaleCompare("wave",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003636 {
3637 /*
3638 Wave image.
3639 */
cristy6fccee12011-10-20 18:43:18 +00003640 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003641 flags=ParseGeometry(argv[1],&geometry_info);
3642 if ((flags & SigmaValue) == 0)
3643 geometry_info.sigma=1.0;
3644 new_image=WaveImage(*image,geometry_info.rho,
anthonya89dd172011-10-04 13:29:35 +00003645 geometry_info.sigma,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003646 break;
3647 }
cristy947cb4c2011-10-20 18:41:46 +00003648 if (LocaleCompare("weight",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003649 {
3650 draw_info->weight=StringToUnsignedLong(argv[1]);
3651 if (LocaleCompare(argv[1],"all") == 0)
3652 draw_info->weight=0;
3653 if (LocaleCompare(argv[1],"bold") == 0)
3654 draw_info->weight=700;
3655 if (LocaleCompare(argv[1],"bolder") == 0)
3656 if (draw_info->weight <= 800)
3657 draw_info->weight+=100;
3658 if (LocaleCompare(argv[1],"lighter") == 0)
3659 if (draw_info->weight >= 100)
3660 draw_info->weight-=100;
3661 if (LocaleCompare(argv[1],"normal") == 0)
3662 draw_info->weight=400;
3663 break;
3664 }
cristy947cb4c2011-10-20 18:41:46 +00003665 if (LocaleCompare("white-threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003666 {
cristy947cb4c2011-10-20 18:41:46 +00003667 /*
3668 White threshold image.
3669 */
cristy6fccee12011-10-20 18:43:18 +00003670 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003671 (void) WhiteThresholdImage(*image,argv[1],exception);
anthony805a2d42011-09-25 08:25:12 +00003672 break;
3673 }
3674 break;
3675 }
3676 default:
3677 break;
3678 }
3679 /*
3680 Replace current image with any image that was generated
3681 */
3682 if (new_image != (Image *) NULL)
3683 ReplaceImageInListReturnLast(image,new_image);
3684
3685 /*
3686 Free resources.
3687 */
3688 quantize_info=DestroyQuantizeInfo(quantize_info);
3689 draw_info=DestroyDrawInfo(draw_info);
cristy82d7af52011-10-16 16:26:41 +00003690 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthonya89dd172011-10-04 13:29:35 +00003691 return(status == 0 ? MagickFalse : MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003692}
3693
3694/*
3695%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3696% %
3697% %
3698% %
3699+ S e q u e n c e O p e r a t i o n I m a g e s %
3700% %
3701% %
3702% %
3703%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3704%
3705% SequenceOperationImages() applies a single operation that apply to the
3706% entire image list (e.g. -append, -layers, -coalesce, etc.).
3707%
3708% The format of the MogrifyImage method is:
3709%
3710% MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3711% const int argc, const char **argv,Image **images,
3712% ExceptionInfo *exception)
3713%
3714% A description of each parameter follows:
3715%
3716% o image_info: the image info..
3717%
3718% o argc: Specifies a pointer to an integer describing the number of
3719% elements in the argument vector.
3720%
3721% o argv: Specifies a pointer to a text array containing the command line
3722% arguments.
3723%
3724% o images: pointer to pointer of the first image in image list.
3725%
3726% o exception: return any errors or warnings in this structure.
3727%
3728*/
3729WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3730 const int argc,const char **argv,Image **images,ExceptionInfo *exception)
3731{
3732
3733 MagickStatusType
3734 status;
3735
3736 QuantizeInfo
3737 *quantize_info;
3738
3739 assert(image_info != (ImageInfo *) NULL);
3740 assert(image_info->signature == MagickSignature);
3741 assert(images != (Image **) NULL);
3742 assert((*images)->previous == (Image *) NULL);
3743 assert((*images)->signature == MagickSignature);
3744 if ((*images)->debug != MagickFalse)
3745 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3746 (*images)->filename);
anthonya89dd172011-10-04 13:29:35 +00003747 if ((argc <= 0) || (*argv == (char *) NULL))
3748 return(MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003749 status=MagickTrue;
3750
3751 switch (*(argv[0]+1))
3752 {
3753 case 'a':
3754 {
3755 if (LocaleCompare("affinity",argv[0]+1) == 0)
3756 {
cristy6fccee12011-10-20 18:43:18 +00003757 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003758 if (*argv[0] == '+')
3759 {
3760 (void) RemapImages(quantize_info,*images,(Image *) NULL,
3761 exception);
3762 break;
3763 }
3764 break;
3765 }
3766 if (LocaleCompare("append",argv[0]+1) == 0)
3767 {
3768 Image
3769 *append_image;
3770
cristy6fccee12011-10-20 18:43:18 +00003771 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003772 append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue :
3773 MagickFalse,exception);
3774 if (append_image == (Image *) NULL)
3775 {
3776 status=MagickFalse;
3777 break;
3778 }
3779 *images=DestroyImageList(*images);
3780 *images=append_image;
3781 break;
3782 }
3783 if (LocaleCompare("average",argv[0]+1) == 0)
3784 {
3785 Image
3786 *average_image;
3787
3788 /*
3789 Average an image sequence (deprecated).
3790 */
cristy6fccee12011-10-20 18:43:18 +00003791 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003792 average_image=EvaluateImages(*images,MeanEvaluateOperator,
3793 exception);
3794 if (average_image == (Image *) NULL)
3795 {
3796 status=MagickFalse;
3797 break;
3798 }
3799 *images=DestroyImageList(*images);
3800 *images=average_image;
3801 break;
3802 }
3803 break;
3804 }
3805 case 'c':
3806 {
3807 if (LocaleCompare("channel",argv[0]+1) == 0)
3808 {
3809 ChannelType
3810 channel;
3811
3812 if (*argv[0] == '+')
3813 {
3814 channel=DefaultChannels;
3815 break;
3816 }
3817 channel=(ChannelType) ParseChannelOption(argv[1]);
3818 SetPixelChannelMap(*images,channel);
3819 break;
3820 }
3821 if (LocaleCompare("clut",argv[0]+1) == 0)
3822 {
3823 Image
3824 *clut_image,
3825 *image;
3826
cristy6fccee12011-10-20 18:43:18 +00003827 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003828 image=RemoveFirstImageFromList(images);
3829 clut_image=RemoveFirstImageFromList(images);
3830 if (clut_image == (Image *) NULL)
3831 {
3832 status=MagickFalse;
3833 break;
3834 }
anthonya89dd172011-10-04 13:29:35 +00003835 (void) ClutImage(image,clut_image,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003836 clut_image=DestroyImage(clut_image);
3837 *images=DestroyImageList(*images);
3838 *images=image;
3839 break;
3840 }
3841 if (LocaleCompare("coalesce",argv[0]+1) == 0)
3842 {
3843 Image
3844 *coalesce_image;
3845
cristy6fccee12011-10-20 18:43:18 +00003846 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003847 coalesce_image=CoalesceImages(*images,exception);
3848 if (coalesce_image == (Image *) NULL)
3849 {
3850 status=MagickFalse;
3851 break;
3852 }
3853 *images=DestroyImageList(*images);
3854 *images=coalesce_image;
3855 break;
3856 }
3857 if (LocaleCompare("combine",argv[0]+1) == 0)
3858 {
3859 Image
3860 *combine_image;
3861
cristy6fccee12011-10-20 18:43:18 +00003862 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003863 combine_image=CombineImages(*images,exception);
3864 if (combine_image == (Image *) NULL)
3865 {
3866 status=MagickFalse;
3867 break;
3868 }
3869 *images=DestroyImageList(*images);
3870 *images=combine_image;
3871 break;
3872 }
3873 if (LocaleCompare("composite",argv[0]+1) == 0)
3874 {
3875 Image
3876 *mask_image,
3877 *composite_image,
3878 *image;
3879
3880 RectangleInfo
3881 geometry;
3882
anthony5f867ae2011-10-09 10:28:34 +00003883 ComposeOperator
3884 compose;
3885
3886 const char*
3887 value;
3888
3889 value=GetImageOption(image_info,"compose");
3890 if (value != (const char *) NULL)
3891 compose=(CompositeOperator) ParseCommandOption(
3892 MagickComposeOptions,MagickFalse,value);
3893 else
3894 compose=OverCompositeOp; /* use Over not image->compose */
3895
3896 const char*
3897 value=GetImageOption(image_info,"compose");
3898
3899 if (value != (const char *) NULL)
3900 compose=(CompositeOperator) ParseCommandOption(
3901 MagickComposeOptions,MagickFalse,value);
3902 else
3903 compose=OverCompositeOp; /* use Over not image->compose */
3904
3905
cristy6fccee12011-10-20 18:43:18 +00003906 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003907 image=RemoveFirstImageFromList(images);
3908 composite_image=RemoveFirstImageFromList(images);
3909 if (composite_image == (Image *) NULL)
3910 {
3911 status=MagickFalse;
3912 break;
3913 }
3914 (void) TransformImage(&composite_image,(char *) NULL,
anthony6613bf32011-10-15 07:24:44 +00003915 composite_image->geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003916 SetGeometry(composite_image,&geometry);
3917 (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
3918 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
3919 &geometry);
3920 mask_image=RemoveFirstImageFromList(images);
3921 if (mask_image != (Image *) NULL)
3922 {
anthony5f867ae2011-10-09 10:28:34 +00003923 if ((compose == DisplaceCompositeOp) ||
3924 (compose == DistortCompositeOp))
anthony805a2d42011-09-25 08:25:12 +00003925 {
3926 /*
3927 Merge Y displacement into X displacement image.
3928 */
3929 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
anthony6613bf32011-10-15 07:24:44 +00003930 mask_image,0,0,exception);
anthony805a2d42011-09-25 08:25:12 +00003931 mask_image=DestroyImage(mask_image);
3932 }
3933 else
3934 {
3935 /*
3936 Set a blending mask for the composition.
3937 Posible error, what if image->mask already set.
3938 */
3939 image->mask=mask_image;
3940 (void) NegateImage(image->mask,MagickFalse,exception);
3941 }
3942 }
anthony5f867ae2011-10-09 10:28:34 +00003943 (void) CompositeImage(image,compose,composite_image,
anthony6613bf32011-10-15 07:24:44 +00003944 geometry.x,geometry.y,exception);
anthony805a2d42011-09-25 08:25:12 +00003945 if (mask_image != (Image *) NULL)
3946 mask_image=image->mask=DestroyImage(image->mask);
3947 composite_image=DestroyImage(composite_image);
anthony805a2d42011-09-25 08:25:12 +00003948 *images=DestroyImageList(*images);
3949 *images=image;
3950 break;
3951 }
3952 break;
3953 }
3954 case 'd':
3955 {
3956 if (LocaleCompare("deconstruct",argv[0]+1) == 0)
3957 {
3958 Image
3959 *deconstruct_image;
3960
cristy6fccee12011-10-20 18:43:18 +00003961 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003962 deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
3963 exception);
3964 if (deconstruct_image == (Image *) NULL)
3965 {
3966 status=MagickFalse;
3967 break;
3968 }
3969 *images=DestroyImageList(*images);
3970 *images=deconstruct_image;
3971 break;
3972 }
3973 if (LocaleCompare("delete",argv[0]+1) == 0)
3974 {
3975 if (*argv[0] == '+')
3976 DeleteImages(images,"-1",exception);
3977 else
3978 DeleteImages(images,argv[1],exception);
3979 break;
3980 }
3981 if (LocaleCompare("dither",argv[0]+1) == 0)
3982 {
3983 if (*argv[0] == '+')
3984 {
3985 quantize_info->dither=MagickFalse;
3986 break;
3987 }
3988 quantize_info->dither=MagickTrue;
3989 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
3990 MagickDitherOptions,MagickFalse,argv[1]);
3991 break;
3992 }
3993 if (LocaleCompare("duplicate",argv[0]+1) == 0)
3994 {
3995 Image
3996 *duplicate_images;
3997
3998 if (*argv[0] == '+')
3999 duplicate_images=DuplicateImages(*images,1,"-1",exception);
4000 else
4001 {
4002 const char
4003 *p;
4004
4005 size_t
4006 number_duplicates;
4007
4008 number_duplicates=(size_t) StringToLong(argv[1]);
4009 p=strchr(argv[1],',');
4010 if (p == (const char *) NULL)
4011 duplicate_images=DuplicateImages(*images,number_duplicates,
4012 "-1",exception);
4013 else
4014 duplicate_images=DuplicateImages(*images,number_duplicates,p,
4015 exception);
4016 }
4017 AppendImageToList(images, duplicate_images);
cristy6fccee12011-10-20 18:43:18 +00004018 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004019 break;
4020 }
4021 break;
4022 }
4023 case 'e':
4024 {
4025 if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0)
4026 {
4027 Image
4028 *evaluate_image;
4029
4030 MagickEvaluateOperator
4031 op;
4032
4033 (void) SyncImageSettings(image_info,*images);
4034 op=(MagickEvaluateOperator) ParseCommandOption(
4035 MagickEvaluateOptions,MagickFalse,argv[1]);
4036 evaluate_image=EvaluateImages(*images,op,exception);
4037 if (evaluate_image == (Image *) NULL)
4038 {
4039 status=MagickFalse;
4040 break;
4041 }
4042 *images=DestroyImageList(*images);
4043 *images=evaluate_image;
4044 break;
4045 }
4046 break;
4047 }
4048 case 'f':
4049 {
4050 if (LocaleCompare("fft",argv[0]+1) == 0)
4051 {
4052 Image
4053 *fourier_image;
4054
4055 /*
4056 Implements the discrete Fourier transform (DFT).
4057 */
4058 (void) SyncImageSettings(image_info,*images);
4059 fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ?
4060 MagickTrue : MagickFalse,exception);
4061 if (fourier_image == (Image *) NULL)
4062 break;
4063 *images=DestroyImage(*images);
4064 *images=fourier_image;
4065 break;
4066 }
4067 if (LocaleCompare("flatten",argv[0]+1) == 0)
4068 {
4069 Image
4070 *flatten_image;
4071
cristy6fccee12011-10-20 18:43:18 +00004072 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004073 flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
4074 if (flatten_image == (Image *) NULL)
4075 break;
4076 *images=DestroyImageList(*images);
4077 *images=flatten_image;
4078 break;
4079 }
4080 if (LocaleCompare("fx",argv[0]+1) == 0)
4081 {
4082 Image
4083 *fx_image;
4084
cristy6fccee12011-10-20 18:43:18 +00004085 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004086 fx_image=FxImage(*images,argv[1],exception);
4087 if (fx_image == (Image *) NULL)
4088 {
4089 status=MagickFalse;
4090 break;
4091 }
4092 *images=DestroyImageList(*images);
4093 *images=fx_image;
4094 break;
4095 }
4096 break;
4097 }
4098 case 'h':
4099 {
4100 if (LocaleCompare("hald-clut",argv[0]+1) == 0)
4101 {
4102 Image
4103 *hald_image,
4104 *image;
4105
cristy6fccee12011-10-20 18:43:18 +00004106 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004107 image=RemoveFirstImageFromList(images);
4108 hald_image=RemoveFirstImageFromList(images);
4109 if (hald_image == (Image *) NULL)
4110 {
4111 status=MagickFalse;
4112 break;
4113 }
4114 (void) HaldClutImage(image,hald_image,exception);
4115 hald_image=DestroyImage(hald_image);
4116 if (*images != (Image *) NULL)
4117 *images=DestroyImageList(*images);
4118 *images=image;
4119 break;
4120 }
4121 break;
4122 }
4123 case 'i':
4124 {
4125 if (LocaleCompare("ift",argv[0]+1) == 0)
4126 {
4127 Image
4128 *fourier_image,
4129 *magnitude_image,
4130 *phase_image;
4131
4132 /*
4133 Implements the inverse fourier discrete Fourier transform (DFT).
4134 */
cristy6fccee12011-10-20 18:43:18 +00004135 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004136 magnitude_image=RemoveFirstImageFromList(images);
4137 phase_image=RemoveFirstImageFromList(images);
4138 if (phase_image == (Image *) NULL)
4139 {
4140 status=MagickFalse;
4141 break;
4142 }
4143 fourier_image=InverseFourierTransformImage(magnitude_image,
4144 phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception);
4145 if (fourier_image == (Image *) NULL)
4146 break;
4147 if (*images != (Image *) NULL)
4148 *images=DestroyImage(*images);
4149 *images=fourier_image;
4150 break;
4151 }
4152 if (LocaleCompare("insert",argv[0]+1) == 0)
4153 {
4154 Image
4155 *p,
4156 *q;
4157
4158 index=0;
4159 if (*argv[0] != '+')
4160 index=(ssize_t) StringToLong(argv[1]);
4161 p=RemoveLastImageFromList(images);
4162 if (p == (Image *) NULL)
4163 {
4164 (void) ThrowMagickException(exception,GetMagickModule(),
4165 OptionError,"NoSuchImage","`%s'",argv[1]);
4166 status=MagickFalse;
4167 break;
4168 }
4169 q=p;
4170 if (index == 0)
4171 PrependImageToList(images,q);
4172 else
4173 if (index == (ssize_t) GetImageListLength(*images))
4174 AppendImageToList(images,q);
4175 else
4176 {
4177 q=GetImageFromList(*images,index-1);
4178 if (q == (Image *) NULL)
4179 {
4180 (void) ThrowMagickException(exception,GetMagickModule(),
4181 OptionError,"NoSuchImage","`%s'",argv[1]);
4182 status=MagickFalse;
4183 break;
4184 }
4185 InsertImageInList(&q,p);
4186 }
4187 *images=GetFirstImageInList(q);
4188 break;
4189 }
4190 if (LocaleCompare("interpolate",argv[0]+1) == 0)
4191 {
4192 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
4193 MagickInterpolateOptions,MagickFalse,argv[1]);
4194 break;
4195 }
4196 break;
4197 }
4198 case 'l':
4199 {
4200 if (LocaleCompare("layers",argv[0]+1) == 0)
4201 {
4202 Image
4203 *layers;
4204
4205 ImageLayerMethod
4206 method;
4207
cristy6fccee12011-10-20 18:43:18 +00004208 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004209 layers=(Image *) NULL;
4210 method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
4211 MagickFalse,argv[1]);
4212 switch (method)
4213 {
4214 case CoalesceLayer:
4215 {
4216 layers=CoalesceImages(*images,exception);
4217 break;
4218 }
4219 case CompareAnyLayer:
4220 case CompareClearLayer:
4221 case CompareOverlayLayer:
4222 default:
4223 {
4224 layers=CompareImagesLayers(*images,method,exception);
4225 break;
4226 }
4227 case MergeLayer:
4228 case FlattenLayer:
4229 case MosaicLayer:
4230 case TrimBoundsLayer:
4231 {
4232 layers=MergeImageLayers(*images,method,exception);
4233 break;
4234 }
4235 case DisposeLayer:
4236 {
4237 layers=DisposeImages(*images,exception);
4238 break;
4239 }
4240 case OptimizeImageLayer:
4241 {
4242 layers=OptimizeImageLayers(*images,exception);
4243 break;
4244 }
4245 case OptimizePlusLayer:
4246 {
4247 layers=OptimizePlusImageLayers(*images,exception);
4248 break;
4249 }
4250 case OptimizeTransLayer:
4251 {
4252 OptimizeImageTransparency(*images,exception);
4253 break;
4254 }
4255 case RemoveDupsLayer:
4256 {
4257 RemoveDuplicateLayers(images,exception);
4258 break;
4259 }
4260 case RemoveZeroLayer:
4261 {
4262 RemoveZeroDelayLayers(images,exception);
4263 break;
4264 }
4265 case OptimizeLayer:
4266 {
4267 /*
4268 General Purpose, GIF Animation Optimizer.
4269 */
4270 layers=CoalesceImages(*images,exception);
4271 if (layers == (Image *) NULL)
4272 {
4273 status=MagickFalse;
4274 break;
4275 }
4276 *images=DestroyImageList(*images);
4277 *images=layers;
4278 layers=OptimizeImageLayers(*images,exception);
4279 if (layers == (Image *) NULL)
4280 {
4281 status=MagickFalse;
4282 break;
4283 }
4284 *images=DestroyImageList(*images);
4285 *images=layers;
4286 layers=(Image *) NULL;
4287 OptimizeImageTransparency(*images,exception);
4288 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4289 exception);
4290 break;
4291 }
4292 case CompositeLayer:
4293 {
anthony805a2d42011-09-25 08:25:12 +00004294 Image
4295 *source;
4296
4297 RectangleInfo
4298 geometry;
4299
anthony5f867ae2011-10-09 10:28:34 +00004300 ComposeOperator
4301 compose;
4302
4303 const char*
4304 value;
4305
4306 value=GetImageOption(image_info,"compose");
4307 if (value != (const char *) NULL)
4308 compose=(CompositeOperator) ParseCommandOption(
4309 MagickComposeOptions,MagickFalse,value);
4310 else
4311 compose=OverCompositeOp; /* use Over not image->compose */
4312
anthony805a2d42011-09-25 08:25:12 +00004313 /*
4314 Split image sequence at the first 'NULL:' image.
4315 */
4316 source=(*images);
4317 while (source != (Image *) NULL)
4318 {
4319 source=GetNextImageInList(source);
4320 if ((source != (Image *) NULL) &&
4321 (LocaleCompare(source->magick,"NULL") == 0))
4322 break;
4323 }
4324 if (source != (Image *) NULL)
4325 {
4326 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4327 (GetNextImageInList(source) == (Image *) NULL))
4328 source=(Image *) NULL;
4329 else
4330 {
4331 /*
4332 Separate the two lists, junk the null: image.
4333 */
4334 source=SplitImageList(source->previous);
4335 DeleteImageFromList(&source);
4336 }
4337 }
4338 if (source == (Image *) NULL)
4339 {
4340 (void) ThrowMagickException(exception,GetMagickModule(),
4341 OptionError,"MissingNullSeparator","layers Composite");
4342 status=MagickFalse;
4343 break;
4344 }
4345 /*
4346 Adjust offset with gravity and virtual canvas.
4347 */
4348 SetGeometry(*images,&geometry);
4349 (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
4350 geometry.width=source->page.width != 0 ?
4351 source->page.width : source->columns;
4352 geometry.height=source->page.height != 0 ?
4353 source->page.height : source->rows;
4354 GravityAdjustGeometry((*images)->page.width != 0 ?
4355 (*images)->page.width : (*images)->columns,
4356 (*images)->page.height != 0 ? (*images)->page.height :
4357 (*images)->rows,(*images)->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004358
4359 /*
4360 Compose the two image sequences together
4361 */
anthony805a2d42011-09-25 08:25:12 +00004362 CompositeLayers(*images,compose,source,geometry.x,geometry.y,
4363 exception);
4364 source=DestroyImageList(source);
4365 break;
4366 }
4367 }
4368 if (layers == (Image *) NULL)
4369 break;
anthony805a2d42011-09-25 08:25:12 +00004370 *images=DestroyImageList(*images);
4371 *images=layers;
4372 break;
4373 }
4374 break;
4375 }
4376 case 'm':
4377 {
4378 if (LocaleCompare("map",argv[0]+1) == 0)
4379 {
cristy6fccee12011-10-20 18:43:18 +00004380 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004381 if (*argv[0] == '+')
4382 {
4383 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4384 exception);
4385 break;
4386 }
4387 break;
4388 }
4389 if (LocaleCompare("maximum",argv[0]+1) == 0)
4390 {
4391 Image
4392 *maximum_image;
4393
4394 /*
4395 Maximum image sequence (deprecated).
4396 */
cristy6fccee12011-10-20 18:43:18 +00004397 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004398 maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
4399 if (maximum_image == (Image *) NULL)
4400 {
4401 status=MagickFalse;
4402 break;
4403 }
4404 *images=DestroyImageList(*images);
4405 *images=maximum_image;
4406 break;
4407 }
4408 if (LocaleCompare("minimum",argv[0]+1) == 0)
4409 {
4410 Image
4411 *minimum_image;
4412
4413 /*
4414 Minimum image sequence (deprecated).
4415 */
cristy6fccee12011-10-20 18:43:18 +00004416 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004417 minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
4418 if (minimum_image == (Image *) NULL)
4419 {
4420 status=MagickFalse;
4421 break;
4422 }
4423 *images=DestroyImageList(*images);
4424 *images=minimum_image;
4425 break;
4426 }
4427 if (LocaleCompare("morph",argv[0]+1) == 0)
4428 {
4429 Image
4430 *morph_image;
4431
cristy6fccee12011-10-20 18:43:18 +00004432 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004433 morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]),
4434 exception);
4435 if (morph_image == (Image *) NULL)
4436 {
4437 status=MagickFalse;
4438 break;
4439 }
4440 *images=DestroyImageList(*images);
4441 *images=morph_image;
4442 break;
4443 }
4444 if (LocaleCompare("mosaic",argv[0]+1) == 0)
4445 {
4446 Image
4447 *mosaic_image;
4448
cristy6fccee12011-10-20 18:43:18 +00004449 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004450 mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
4451 if (mosaic_image == (Image *) NULL)
4452 {
4453 status=MagickFalse;
4454 break;
4455 }
4456 *images=DestroyImageList(*images);
4457 *images=mosaic_image;
4458 break;
4459 }
4460 break;
4461 }
4462 case 'p':
4463 {
4464 if (LocaleCompare("print",argv[0]+1) == 0)
4465 {
4466 char
4467 *string;
4468
cristy6fccee12011-10-20 18:43:18 +00004469 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004470 string=InterpretImageProperties(image_info,*images,argv[1],
4471 exception);
4472 if (string == (char *) NULL)
4473 break;
4474 (void) FormatLocaleFile(stdout,"%s",string);
4475 string=DestroyString(string);
4476 }
4477 if (LocaleCompare("process",argv[0]+1) == 0)
4478 {
4479 char
4480 **arguments;
4481
4482 int
4483 j,
4484 number_arguments;
4485
cristy6fccee12011-10-20 18:43:18 +00004486 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004487 arguments=StringToArgv(argv[1],&number_arguments);
4488 if (arguments == (char **) NULL)
4489 break;
4490 if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
4491 {
4492 char
4493 breaker,
4494 quote,
4495 *token;
4496
4497 const char
4498 *arguments;
4499
4500 int
4501 next,
4502 status;
4503
4504 size_t
4505 length;
4506
4507 TokenInfo
4508 *token_info;
4509
4510 /*
4511 Support old style syntax, filter="-option arg".
4512 */
4513 length=strlen(argv[1]);
4514 token=(char *) NULL;
4515 if (~length >= (MaxTextExtent-1))
4516 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4517 sizeof(*token));
4518 if (token == (char *) NULL)
4519 break;
4520 next=0;
4521 arguments=argv[1];
4522 token_info=AcquireTokenInfo();
4523 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4524 "\"",'\0',&breaker,&next,&quote);
4525 token_info=DestroyTokenInfo(token_info);
4526 if (status == 0)
4527 {
4528 const char
4529 *argv;
4530
4531 argv=(&(arguments[next]));
4532 (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
4533 exception);
4534 }
4535 token=DestroyString(token);
4536 break;
4537 }
4538 (void) SubstituteString(&arguments[1],"-","");
4539 (void) InvokeDynamicImageFilter(arguments[1],&(*images),
4540 number_arguments-2,(const char **) arguments+2,exception);
4541 for (j=0; j < number_arguments; j++)
4542 arguments[j]=DestroyString(arguments[j]);
4543 arguments=(char **) RelinquishMagickMemory(arguments);
4544 break;
4545 }
4546 break;
4547 }
4548 case 'r':
4549 {
4550 if (LocaleCompare("reverse",argv[0]+1) == 0)
4551 {
4552 ReverseImageList(images);
anthony805a2d42011-09-25 08:25:12 +00004553 break;
4554 }
4555 break;
4556 }
4557 case 's':
4558 {
4559 if (LocaleCompare("smush",argv[0]+1) == 0)
4560 {
4561 Image
4562 *smush_image;
4563
4564 ssize_t
4565 offset;
4566
cristy6fccee12011-10-20 18:43:18 +00004567 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004568 offset=(ssize_t) StringToLong(argv[1]);
4569 smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue :
4570 MagickFalse,offset,exception);
4571 if (smush_image == (Image *) NULL)
4572 {
4573 status=MagickFalse;
4574 break;
4575 }
4576 *images=DestroyImageList(*images);
4577 *images=smush_image;
4578 break;
4579 }
4580 if (LocaleCompare("swap",argv[0]+1) == 0)
4581 {
4582 Image
4583 *p,
4584 *q,
4585 *swap;
4586
4587 ssize_t
4588 swap_index;
4589
4590 index=(-1);
4591 swap_index=(-2);
4592 if (*argv[0] != '+')
4593 {
4594 GeometryInfo
4595 geometry_info;
4596
4597 MagickStatusType
4598 flags;
4599
4600 swap_index=(-1);
4601 flags=ParseGeometry(argv[1],&geometry_info);
4602 index=(ssize_t) geometry_info.rho;
4603 if ((flags & SigmaValue) != 0)
4604 swap_index=(ssize_t) geometry_info.sigma;
4605 }
4606 p=GetImageFromList(*images,index);
4607 q=GetImageFromList(*images,swap_index);
4608 if ((p == (Image *) NULL) || (q == (Image *) NULL))
4609 {
4610 (void) ThrowMagickException(exception,GetMagickModule(),
4611 OptionError,"NoSuchImage","`%s'",(*images)->filename);
4612 status=MagickFalse;
4613 break;
4614 }
4615 if (p == q)
4616 break;
4617 swap=CloneImage(p,0,0,MagickTrue,exception);
4618 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
4619 ReplaceImageInList(&q,swap);
4620 *images=GetFirstImageInList(q);
4621 break;
4622 }
4623 break;
4624 }
4625 case 'w':
4626 {
4627 if (LocaleCompare("write",argv[0]+1) == 0)
4628 {
4629 char
4630 key[MaxTextExtent];
4631
4632 Image
4633 *write_images;
4634
4635 ImageInfo
4636 *write_info;
4637
cristy6fccee12011-10-20 18:43:18 +00004638 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004639 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]);
4640 (void) DeleteImageRegistry(key);
4641 write_images=(*images);
4642 if (*argv[0] == '+')
4643 write_images=CloneImageList(*images,exception);
4644 write_info=CloneImageInfo(image_info);
4645 status&=WriteImages(write_info,write_images,argv[1],exception);
4646 write_info=DestroyImageInfo(write_info);
4647 if (*argv[0] == '+')
4648 write_images=DestroyImageList(write_images);
4649 break;
4650 }
4651 break;
4652 }
4653 default:
4654 break;
4655 }
4656 quantize_info=DestroyQuantizeInfo(quantize_info);
4657
cristy82d7af52011-10-16 16:26:41 +00004658 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthony805a2d42011-09-25 08:25:12 +00004659 return(status != 0 ? MagickTrue : MagickFalse);
4660}
cristy0a0ca4f2011-09-28 01:15:28 +00004661#endif