blob: 19d2c4a1ef8180cadaf96b25c08ef8c2df2ba0cf [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 {
anthonyab3a50c2011-10-27 11:48:57 +00001419 (void) SetImageOption(image_info,option,
1420 IfSetOption ? argv[1] : (char) NULL);
1421 image_info->type=UndefinedType;
1422 if (IfSetOption)
1423 image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
1424 MagickFalse,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001425 break;
1426 }
1427 break;
1428 }
1429 case 'u':
1430 {
anthony74b1cfc2011-10-06 12:44:16 +00001431 if (LocaleCompare("undercolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001432 {
anthonyab3a50c2011-10-27 11:48:57 +00001433 (void) SetImageOption(image_info,option,
1434 IfSetOption ? argv[1] : (char) NULL);
1435 (void) QueryColorCompliance(argv[1],AllCompliance,
1436 draw_info->undercolor,exception);
anthony805a2d42011-09-25 08:25:12 +00001437 break;
1438 }
anthony74b1cfc2011-10-06 12:44:16 +00001439 if (LocaleCompare("units",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001440 {
anthonyab3a50c2011-10-27 11:48:57 +00001441 /* Set in images via SyncImageSettings() */
1442 /* Should this effect draw_info X and Y resolution? */
1443 /* FUTURE: this probably should be part of the density setting */
1444 (void) SetImageOption(image_info,option,
1445 IfSetOption ? argv[1] : (char) NULL);
1446 image_info->units=UndefinedResolution;
1447 if (IfSetOption)
1448 image_info->units=(ResolutionType) ParseCommandOption(
1449 MagickResolutionOptions,MagickFalse,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001450 break;
1451 }
1452 break;
1453 }
1454 case 'v':
1455 {
anthony74b1cfc2011-10-06 12:44:16 +00001456 if (LocaleCompare("verbose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001457 {
anthonyab3a50c2011-10-27 11:48:57 +00001458 /* FUTURE: Also an image artifact, set in Simple Operators.
1459 But artifact is only used in verbose output.
1460 */
1461 image_info->verbose= IfSetOption ? MagickTrue : MagickFalse;
1462 image_info->ping=MagickFalse; /* verbose can't be a ping */
anthony805a2d42011-09-25 08:25:12 +00001463 break;
1464 }
anthony74b1cfc2011-10-06 12:44:16 +00001465 if (LocaleCompare("view",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001466 {
anthonyab3a50c2011-10-27 11:48:57 +00001467 /* FUTURE: Convert from image_info to Option
1468 Only used by coder FPX
1469 */
1470 (void) CloneString(&image_info->view,
1471 IfSetOption ? argv[1] : (char) NULL);
anthony805a2d42011-09-25 08:25:12 +00001472 break;
1473 }
anthony74b1cfc2011-10-06 12:44:16 +00001474 if (LocaleCompare("virtual-pixel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001475 {
anthonyab3a50c2011-10-27 11:48:57 +00001476 /* Also used as a 'image' option deep in image structure */
1477 const char
1478 *value = IfSetOption ? argv[1] : "undefined";
1479
1480 (void) SetImageOption(image_info,option,value);
anthony805a2d42011-09-25 08:25:12 +00001481 image_info->virtual_pixel_method=(VirtualPixelMethod)
anthonyab3a50c2011-10-27 11:48:57 +00001482 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,value);
anthony805a2d42011-09-25 08:25:12 +00001483 break;
1484 }
1485 break;
1486 }
1487 case 'w':
1488 {
anthonyab3a50c2011-10-27 11:48:57 +00001489 if (LocaleCompare("weight",argv[0]+1) == 0)
1490 {
1491 /* FUTURE: relative weights not sensical due to first assignment!
1492 Also just what is actually using font 'weight' ???
1493 */
1494 draw_info->weight=StringToUnsignedLong(argv[1]);
1495 if (LocaleCompare(argv[1],"all") == 0)
1496 draw_info->weight=0;
1497 if (LocaleCompare(argv[1],"bold") == 0)
1498 draw_info->weight=700;
1499 if (LocaleCompare(argv[1],"bolder") == 0)
1500 if (draw_info->weight <= 800)
1501 draw_info->weight+=100;
1502 if (LocaleCompare(argv[1],"lighter") == 0)
1503 if (draw_info->weight >= 100)
1504 draw_info->weight-=100;
1505 if (LocaleCompare(argv[1],"normal") == 0)
1506 draw_info->weight=400;
1507 break;
1508 }
anthony74b1cfc2011-10-06 12:44:16 +00001509 if (LocaleCompare("white-point",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001510 {
1511 if (*argv[0] == '+')
1512 {
anthony74b1cfc2011-10-06 12:44:16 +00001513 (void) SetImageOption(image_info,option,"0.0");
anthony805a2d42011-09-25 08:25:12 +00001514 break;
1515 }
anthony74b1cfc2011-10-06 12:44:16 +00001516 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001517 break;
1518 }
1519 break;
1520 }
1521 default:
1522 break;
1523 }
1524 return(MagickTrue);
1525}
1526
1527/*
1528%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1529% %
1530% %
1531% %
anthony74b1cfc2011-10-06 12:44:16 +00001532+ A p p l y I m a g e O p e r a t o r %
anthony805a2d42011-09-25 08:25:12 +00001533% %
1534% %
1535% %
1536%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1537%
anthony74b1cfc2011-10-06 12:44:16 +00001538% ApplyImageOperator() apply one simple image operation to just the current
1539% image.
anthony805a2d42011-09-25 08:25:12 +00001540%
1541% The image in the list may be modified in three different ways...
1542%
1543% * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1544% * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1545% * replace by a list of images (-separate and -crop only!)
1546%
1547% In each case the result is returned into the list, and the pointer to the
1548% modified image (last image added if replaced by a list of images) is
1549% returned. As the image pointed to may be replaced, the first image in the
1550% list may also change. GetFirstImageInList() should be used by caller if
1551% they wish return the Image pointer to the first image in list.
1552%
anthony74b1cfc2011-10-06 12:44:16 +00001553% The format of the ApplyImageOperator method is:
anthony805a2d42011-09-25 08:25:12 +00001554%
anthony74b1cfc2011-10-06 12:44:16 +00001555% MagickBooleanType ApplyImageOperator(MagickWand *wand,
1556% const int argc,const char **argv)
anthony805a2d42011-09-25 08:25:12 +00001557%
1558% A description of each parameter follows:
1559%
anthony74b1cfc2011-10-06 12:44:16 +00001560% o wand: The CLI wand holding all the settings and pointer to image
anthony805a2d42011-09-25 08:25:12 +00001561%
1562% o argc: Specifies a pointer to an integer describing the number of
1563% elements in the argument vector.
1564%
1565% o argv: Specifies a pointer to a text array containing the command line
1566% arguments.
1567%
anthony805a2d42011-09-25 08:25:12 +00001568% o exception: return any errors or warnings in this structure.
1569%
1570*/
anthony74b1cfc2011-10-06 12:44:16 +00001571MagickExport MagickBooleanType ApplyImageOperator(MagickWand *wand,
1572 const int wand_unused(argc), const char **argv, ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +00001573{
1574 Image *
1575 new_image;
1576
1577 ChannelType
1578 channel;
1579
anthony5f867ae2011-10-09 10:28:34 +00001580 ComposeOperation
1581 compose;
1582
anthony805a2d42011-09-25 08:25:12 +00001583 const char
1584 *format;
1585
1586 DrawInfo
1587 *draw_info;
1588
1589 GeometryInfo
1590 geometry_info;
1591
1592 RectangleInfo
1593 geometry;
1594
1595 MagickStatusType
1596 status;
1597
1598 PixelInfo
1599 fill;
1600
1601 MagickStatusType
1602 flags;
1603
1604 QuantizeInfo
1605 *quantize_info;
1606
1607 assert(image_info != (const ImageInfo *) NULL);
1608 assert(image_info->signature == MagickSignature);
1609 assert(image != (Image **) NULL);
1610 assert((*image)->signature == MagickSignature);
1611 if ((*image)->debug != MagickFalse)
1612 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
anthonya89dd172011-10-04 13:29:35 +00001613 if (argc < 0)
1614 return(MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00001615 draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
1616 quantize_info=AcquireQuantizeInfo(image_info);
1617 SetGeometryInfo(&geometry_info);
1618 GetPixelInfo(*image,&fill);
cristy9d8c8ce2011-10-25 16:13:52 +00001619 fill=(*image)->background_color;
anthony805a2d42011-09-25 08:25:12 +00001620 channel=image_info->channel;
1621 format=GetImageOption(image_info,"format");
1622
1623 new_image = (Image *)NULL;
1624
cristy947cb4c2011-10-20 18:41:46 +00001625 switch (*(argv[0]+1))
anthony805a2d42011-09-25 08:25:12 +00001626 {
1627 case 'a':
1628 {
cristy947cb4c2011-10-20 18:41:46 +00001629 if (LocaleCompare("adaptive-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001630 {
cristy6fccee12011-10-20 18:43:18 +00001631 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001632 flags=ParseGeometry(argv[1],&geometry_info);
1633 if ((flags & SigmaValue) == 0)
1634 geometry_info.sigma=1.0;
1635 if ((flags & XiValue) == 0)
1636 geometry_info.xi=0.0;
1637 new_image=AdaptiveBlurImage(*image,geometry_info.rho,
1638 geometry_info.sigma,geometry_info.xi,exception);
1639 break;
1640 }
cristy947cb4c2011-10-20 18:41:46 +00001641 if (LocaleCompare("adaptive-resize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001642 {
anthony1afdc7a2011-10-05 11:54:28 +00001643 /* FUTURE: this is really a "interpolate-resize" operator
1644 "adaptive-resize" uses a fixed "Mesh" interpolation
anthony805a2d42011-09-25 08:25:12 +00001645 */
cristy6fccee12011-10-20 18:43:18 +00001646 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001647 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
1648 new_image=AdaptiveResizeImage(*image,geometry.width,
anthonya89dd172011-10-04 13:29:35 +00001649 geometry.height,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00001650 break;
1651 }
cristy947cb4c2011-10-20 18:41:46 +00001652 if (LocaleCompare("adaptive-sharpen",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001653 {
1654 /*
1655 Adaptive sharpen image.
1656 */
cristy6fccee12011-10-20 18:43:18 +00001657 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001658 flags=ParseGeometry(argv[1],&geometry_info);
1659 if ((flags & SigmaValue) == 0)
1660 geometry_info.sigma=1.0;
1661 if ((flags & XiValue) == 0)
1662 geometry_info.xi=0.0;
1663 new_image=AdaptiveSharpenImage(*image,geometry_info.rho,
1664 geometry_info.sigma,geometry_info.xi,exception);
1665 break;
1666 }
cristy947cb4c2011-10-20 18:41:46 +00001667 if (LocaleCompare("alpha",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001668 {
1669 AlphaChannelType
1670 alpha_type;
1671
cristy6fccee12011-10-20 18:43:18 +00001672 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001673 alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
1674 MagickFalse,argv[1]);
1675 (void) SetImageAlphaChannel(*image,alpha_type,exception);
1676 break;
1677 }
cristy947cb4c2011-10-20 18:41:46 +00001678 if (LocaleCompare("annotate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001679 {
1680 char
1681 *text,
1682 geometry[MaxTextExtent];
1683
cristy6fccee12011-10-20 18:43:18 +00001684 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001685 SetGeometryInfo(&geometry_info);
1686 flags=ParseGeometry(argv[1],&geometry_info);
1687 if ((flags & SigmaValue) == 0)
1688 geometry_info.sigma=geometry_info.rho;
1689 text=InterpretImageProperties(image_info,*image,argv[2],
1690 exception);
1691 if (text == (char *) NULL)
1692 break;
1693 (void) CloneString(&draw_info->text,text);
1694 text=DestroyString(text);
1695 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1696 geometry_info.xi,geometry_info.psi);
1697 (void) CloneString(&draw_info->geometry,geometry);
1698 draw_info->affine.sx=cos(DegreesToRadians(
1699 fmod(geometry_info.rho,360.0)));
1700 draw_info->affine.rx=sin(DegreesToRadians(
1701 fmod(geometry_info.rho,360.0)));
1702 draw_info->affine.ry=(-sin(DegreesToRadians(
1703 fmod(geometry_info.sigma,360.0))));
1704 draw_info->affine.sy=cos(DegreesToRadians(
1705 fmod(geometry_info.sigma,360.0)));
1706 (void) AnnotateImage(*image,draw_info,exception);
1707 break;
1708 }
cristy947cb4c2011-10-20 18:41:46 +00001709 if (LocaleCompare("auto-gamma",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001710 {
1711 /*
1712 Auto Adjust Gamma of image based on its mean
1713 */
cristy6fccee12011-10-20 18:43:18 +00001714 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001715 (void) AutoGammaImage(*image,exception);
1716 break;
1717 }
cristy947cb4c2011-10-20 18:41:46 +00001718 if (LocaleCompare("auto-level",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001719 {
1720 /*
1721 Perfectly Normalize (max/min stretch) the image
1722 */
cristy6fccee12011-10-20 18:43:18 +00001723 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001724 (void) AutoLevelImage(*image,exception);
1725 break;
1726 }
cristy947cb4c2011-10-20 18:41:46 +00001727 if (LocaleCompare("auto-orient",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001728 {
cristy6fccee12011-10-20 18:43:18 +00001729 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001730 switch ((*image)->orientation)
1731 {
1732 case TopRightOrientation:
1733 {
1734 new_image=FlopImage(*image,exception);
1735 break;
1736 }
1737 case BottomRightOrientation:
1738 {
1739 new_image=RotateImage(*image,180.0,exception);
1740 break;
1741 }
1742 case BottomLeftOrientation:
1743 {
1744 new_image=FlipImage(*image,exception);
1745 break;
1746 }
1747 case LeftTopOrientation:
1748 {
1749 new_image=TransposeImage(*image,exception);
1750 break;
1751 }
1752 case RightTopOrientation:
1753 {
1754 new_image=RotateImage(*image,90.0,exception);
1755 break;
1756 }
1757 case RightBottomOrientation:
1758 {
1759 new_image=TransverseImage(*image,exception);
1760 break;
1761 }
1762 case LeftBottomOrientation:
1763 {
1764 new_image=RotateImage(*image,270.0,exception);
1765 break;
1766 }
1767 default:
1768 break;
1769 }
1770 if (new_image != (Image *) NULL)
1771 new_image->orientation=TopLeftOrientation;
1772 break;
1773 }
1774 break;
1775 }
1776 case 'b':
1777 {
cristy947cb4c2011-10-20 18:41:46 +00001778 if (LocaleCompare("black-threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001779 {
cristy6fccee12011-10-20 18:43:18 +00001780 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001781 (void) BlackThresholdImage(*image,argv[1],exception);
anthony805a2d42011-09-25 08:25:12 +00001782 break;
1783 }
cristy947cb4c2011-10-20 18:41:46 +00001784 if (LocaleCompare("blue-shift",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001785 {
cristy6fccee12011-10-20 18:43:18 +00001786 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001787 geometry_info.rho=1.5;
1788 if (*argv[0] == '-')
1789 flags=ParseGeometry(argv[1],&geometry_info);
1790 new_image=BlueShiftImage(*image,geometry_info.rho,exception);
1791 break;
1792 }
cristy947cb4c2011-10-20 18:41:46 +00001793 if (LocaleCompare("blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001794 {
anthony74b1cfc2011-10-06 12:44:16 +00001795 /* FUTURE: use of "bias" in a blur is non-sensible */
cristy6fccee12011-10-20 18:43:18 +00001796 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001797 flags=ParseGeometry(argv[1],&geometry_info);
1798 if ((flags & SigmaValue) == 0)
1799 geometry_info.sigma=1.0;
1800 if ((flags & XiValue) == 0)
1801 geometry_info.xi=0.0;
1802 new_image=BlurImage(*image,geometry_info.rho,
1803 geometry_info.sigma,geometry_info.xi,exception);
1804 break;
1805 }
cristy947cb4c2011-10-20 18:41:46 +00001806 if (LocaleCompare("border",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001807 {
anthony5f867ae2011-10-09 10:28:34 +00001808 ComposeOperator
1809 compose;
1810
1811 const char*
1812 const char*
1813 value;
1814
1815 value=GetImageOption(image_info,"compose");
1816 if (value != (const char *) NULL)
1817 compose=(CompositeOperator) ParseCommandOption(
1818 MagickComposeOptions,MagickFalse,value);
1819 else
1820 compose=OverCompositeOp; /* use Over not image->compose */
1821
cristy6fccee12011-10-20 18:43:18 +00001822 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001823 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
1824 if ((flags & SigmaValue) == 0)
1825 geometry.height=geometry.width;
anthonya89dd172011-10-04 13:29:35 +00001826 new_image=BorderImage(*image,&geometry,compose,exception);
anthony805a2d42011-09-25 08:25:12 +00001827 break;
1828 }
cristy947cb4c2011-10-20 18:41:46 +00001829 if (LocaleCompare("brightness-contrast",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001830 {
1831 double
1832 brightness,
1833 contrast;
1834
1835 GeometryInfo
1836 geometry_info;
1837
1838 MagickStatusType
1839 flags;
1840
cristy6fccee12011-10-20 18:43:18 +00001841 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001842 flags=ParseGeometry(argv[1],&geometry_info);
1843 brightness=geometry_info.rho;
1844 contrast=0.0;
1845 if ((flags & SigmaValue) != 0)
1846 contrast=geometry_info.sigma;
1847 (void) BrightnessContrastImage(*image,brightness,contrast,
1848 exception);
anthony805a2d42011-09-25 08:25:12 +00001849 break;
1850 }
1851 break;
1852 }
1853 case 'c':
1854 {
cristy947cb4c2011-10-20 18:41:46 +00001855 if (LocaleCompare("cdl",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001856 {
1857 char
1858 *color_correction_collection;
1859
1860 /*
1861 Color correct with a color decision list.
1862 */
cristy6fccee12011-10-20 18:43:18 +00001863 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001864 color_correction_collection=FileToString(argv[1],~0,exception);
1865 if (color_correction_collection == (char *) NULL)
1866 break;
1867 (void) ColorDecisionListImage(*image,color_correction_collection,
1868 exception);
anthony805a2d42011-09-25 08:25:12 +00001869 break;
1870 }
cristy947cb4c2011-10-20 18:41:46 +00001871 if (LocaleCompare("channel",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001872 {
anthony74b1cfc2011-10-06 12:44:16 +00001873 /* The "channel" setting has already been set */
1874 SetPixelChannelMap(*image,image_info->channel);
anthony805a2d42011-09-25 08:25:12 +00001875 break;
1876 }
cristy947cb4c2011-10-20 18:41:46 +00001877 if (LocaleCompare("charcoal",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001878 {
cristy6fccee12011-10-20 18:43:18 +00001879 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001880 flags=ParseGeometry(argv[1],&geometry_info);
1881 if ((flags & SigmaValue) == 0)
1882 geometry_info.sigma=1.0;
1883 if ((flags & XiValue) == 0)
1884 geometry_info.xi=1.0;
1885 new_image=CharcoalImage(*image,geometry_info.rho,
1886 geometry_info.sigma,geometry_info.xi,exception);
1887 break;
1888 }
cristy947cb4c2011-10-20 18:41:46 +00001889 if (LocaleCompare("chop",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001890 {
cristy6fccee12011-10-20 18:43:18 +00001891 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001892 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
1893 new_image=ChopImage(*image,&geometry,exception);
1894 break;
1895 }
cristy947cb4c2011-10-20 18:41:46 +00001896 if (LocaleCompare("clamp",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001897 {
cristy6fccee12011-10-20 18:43:18 +00001898 (void) SyncImageSettings(image_info,*image,exception);
cristy092d71c2011-10-14 18:01:29 +00001899 (void) ClampImage(*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001900 break;
1901 }
cristy947cb4c2011-10-20 18:41:46 +00001902 if (LocaleCompare("clip",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001903 {
cristy6fccee12011-10-20 18:43:18 +00001904 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001905 if (*argv[0] == '+')
1906 {
1907 (void) SetImageClipMask(*image,(Image *) NULL,exception);
1908 break;
1909 }
1910 (void) ClipImage(*image,exception);
1911 break;
1912 }
cristy947cb4c2011-10-20 18:41:46 +00001913 if (LocaleCompare("clip-mask",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001914 {
1915 CacheView
1916 *mask_view;
1917
1918 Image
1919 *mask_image;
1920
1921 register Quantum
1922 *restrict q;
1923
1924 register ssize_t
1925 x;
1926
1927 ssize_t
1928 y;
1929
cristy6fccee12011-10-20 18:43:18 +00001930 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001931 if (*argv[0] == '+')
1932 {
anthony74b1cfc2011-10-06 12:44:16 +00001933 /* Remove the write mask */
anthony805a2d42011-09-25 08:25:12 +00001934 (void) SetImageMask(*image,(Image *) NULL,exception);
1935 break;
1936 }
1937 mask_image=GetImageCache(image_info,argv[1],exception);
1938 if (mask_image == (Image *) NULL)
1939 break;
1940 if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
1941 return(MagickFalse);
anthony74b1cfc2011-10-06 12:44:16 +00001942 /* create a write mask from clip-mask image */
1943 /* FUTURE: use Alpha operations instead */
anthony805a2d42011-09-25 08:25:12 +00001944 mask_view=AcquireCacheView(mask_image);
1945 for (y=0; y < (ssize_t) mask_image->rows; y++)
1946 {
1947 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
1948 exception);
1949 if (q == (Quantum *) NULL)
1950 break;
1951 for (x=0; x < (ssize_t) mask_image->columns; x++)
1952 {
1953 if (mask_image->matte == MagickFalse)
1954 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1955 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1956 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1957 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1958 q+=GetPixelChannels(mask_image);
1959 }
1960 if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
1961 break;
1962 }
anthony74b1cfc2011-10-06 12:44:16 +00001963 /* set the write mask */
anthony805a2d42011-09-25 08:25:12 +00001964 mask_view=DestroyCacheView(mask_view);
1965 mask_image->matte=MagickTrue;
anthonya89dd172011-10-04 13:29:35 +00001966 (void) SetImageClipMask(*image,mask_image,exception);
anthony805a2d42011-09-25 08:25:12 +00001967 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00001968 break;
1969 }
cristy947cb4c2011-10-20 18:41:46 +00001970 if (LocaleCompare("clip-path",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001971 {
cristy6fccee12011-10-20 18:43:18 +00001972 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001973 (void) ClipImagePath(*image,argv[1],*argv[0] == '-' ? MagickTrue :
1974 MagickFalse,exception);
1975 break;
1976 }
cristy947cb4c2011-10-20 18:41:46 +00001977 if (LocaleCompare("colorize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001978 {
cristy6fccee12011-10-20 18:43:18 +00001979 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001980 new_image=ColorizeImage(*image,argv[1],draw_info->fill,
1981 exception);
1982 break;
1983 }
cristy947cb4c2011-10-20 18:41:46 +00001984 if (LocaleCompare("color-matrix",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001985 {
1986 KernelInfo
1987 *kernel;
1988
cristy6fccee12011-10-20 18:43:18 +00001989 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001990 kernel=AcquireKernelInfo(argv[1]);
1991 if (kernel == (KernelInfo *) NULL)
1992 break;
1993 new_image=ColorMatrixImage(*image,kernel,exception);
1994 kernel=DestroyKernelInfo(kernel);
1995 break;
1996 }
cristy947cb4c2011-10-20 18:41:46 +00001997 if (LocaleCompare("colors",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001998 {
anthony74b1cfc2011-10-06 12:44:16 +00001999 /* Reduce the number of colors in the image. */
cristy6fccee12011-10-20 18:43:18 +00002000 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002001 quantize_info->number_colors=StringToUnsignedLong(argv[1]);
2002 if (quantize_info->number_colors == 0)
2003 break;
2004 if (((*image)->storage_class == DirectClass) ||
2005 (*image)->colors > quantize_info->number_colors)
2006 (void) QuantizeImage(quantize_info,*image,exception);
2007 else
2008 (void) CompressImageColormap(*image,exception);
2009 break;
2010 }
cristy947cb4c2011-10-20 18:41:46 +00002011 if (LocaleCompare("colorspace",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002012 {
anthonyd2cdc862011-10-07 14:07:17 +00002013 /* This is a Image Setting, which should already been set */
2014 /* FUTURE: default colorspace should be sRGB!
2015 Unless some type of 'linear colorspace' mode is set.
2016 Note that +colorspace sets "undefined" or no effect on
2017 new images, but forces images already in memory back to RGB!
2018 */
cristy6fccee12011-10-20 18:43:18 +00002019 (void) SyncImageSettings(image_info,*image,exception);
anthonyd2cdc862011-10-07 14:07:17 +00002020 (void) TransformImageColorspace(*image,
anthony6613bf32011-10-15 07:24:44 +00002021 IfSetOption ? image_info->colorspace : RGBColorspace,
2022 exception);
anthony805a2d42011-09-25 08:25:12 +00002023 break;
2024 }
cristy947cb4c2011-10-20 18:41:46 +00002025 if (LocaleCompare("contrast",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002026 {
cristy6fccee12011-10-20 18:43:18 +00002027 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002028 (void) ContrastImage(*image,(*argv[0] == '-') ? MagickTrue :
2029 MagickFalse,exception);
2030 break;
2031 }
cristy947cb4c2011-10-20 18:41:46 +00002032 if (LocaleCompare("contrast-stretch",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002033 {
2034 double
2035 black_point,
2036 white_point;
2037
2038 MagickStatusType
2039 flags;
2040
2041 /*
2042 Contrast stretch image.
2043 */
cristy6fccee12011-10-20 18:43:18 +00002044 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002045 flags=ParseGeometry(argv[1],&geometry_info);
2046 black_point=geometry_info.rho;
2047 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2048 black_point;
2049 if ((flags & PercentValue) != 0)
2050 {
2051 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2052 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2053 }
2054 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2055 white_point;
2056 (void) ContrastStretchImage(*image,black_point,white_point,
2057 exception);
anthony805a2d42011-09-25 08:25:12 +00002058 break;
2059 }
cristy947cb4c2011-10-20 18:41:46 +00002060 if (LocaleCompare("convolve",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002061 {
2062 KernelInfo
2063 *kernel_info;
2064
cristy6fccee12011-10-20 18:43:18 +00002065 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002066 kernel_info=AcquireKernelInfo(argv[1]);
2067 if (kernel_info == (KernelInfo *) NULL)
2068 break;
2069 kernel_info->bias=(*image)->bias;
2070 new_image=ConvolveImage(*image,kernel_info,exception);
2071 kernel_info=DestroyKernelInfo(kernel_info);
2072 break;
2073 }
cristy947cb4c2011-10-20 18:41:46 +00002074 if (LocaleCompare("crop",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002075 {
2076 /*
2077 Crop a image to a smaller size
2078 */
cristy6fccee12011-10-20 18:43:18 +00002079 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002080 new_image=CropImageToTiles(*image,argv[1],exception);
2081 break;
2082 }
cristy947cb4c2011-10-20 18:41:46 +00002083 if (LocaleCompare("cycle",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002084 {
2085 /*
2086 Cycle an image colormap.
2087 */
cristy6fccee12011-10-20 18:43:18 +00002088 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002089 (void) CycleColormapImage(*image,(ssize_t) StringToLong(argv[1]),
2090 exception);
2091 break;
2092 }
2093 break;
2094 }
2095 case 'd':
2096 {
cristy947cb4c2011-10-20 18:41:46 +00002097 if (LocaleCompare("decipher",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002098 {
2099 StringInfo
2100 *passkey;
2101
2102 /*
2103 Decipher pixels.
2104 */
cristy6fccee12011-10-20 18:43:18 +00002105 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002106 passkey=FileToStringInfo(argv[1],~0,exception);
2107 if (passkey != (StringInfo *) NULL)
2108 {
2109 (void) PasskeyDecipherImage(*image,passkey,exception);
2110 passkey=DestroyStringInfo(passkey);
2111 }
2112 break;
2113 }
cristy947cb4c2011-10-20 18:41:46 +00002114 if (LocaleCompare("depth",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002115 {
anthony5f867ae2011-10-09 10:28:34 +00002116 /* the image_info->depth setting has already bee set
2117 * We just need to apply it to all images in current sequence */
cristy6fccee12011-10-20 18:43:18 +00002118 (void) SyncImageSettings(image_info,*image,exception);
anthony5f867ae2011-10-09 10:28:34 +00002119 (void) SetImageDepth(*image,image_info->depth);
anthony805a2d42011-09-25 08:25:12 +00002120 break;
2121 }
cristy947cb4c2011-10-20 18:41:46 +00002122 if (LocaleCompare("deskew",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002123 {
2124 double
2125 threshold;
2126
2127 /*
2128 Straighten the image.
2129 */
cristy6fccee12011-10-20 18:43:18 +00002130 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002131 if (*argv[0] == '+')
2132 threshold=40.0*QuantumRange/100.0;
2133 else
2134 threshold=SiPrefixToDouble(argv[1],QuantumRange);
2135 new_image=DeskewImage(*image,threshold,exception);
2136 break;
2137 }
cristy947cb4c2011-10-20 18:41:46 +00002138 if (LocaleCompare("despeckle",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002139 {
2140 /*
2141 Reduce the speckles within an image.
2142 */
cristy6fccee12011-10-20 18:43:18 +00002143 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002144 new_image=DespeckleImage(*image,exception);
2145 break;
2146 }
cristy947cb4c2011-10-20 18:41:46 +00002147 if (LocaleCompare("display",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002148 {
2149 (void) CloneString(&draw_info->server_name,argv[1]);
2150 break;
2151 }
cristy947cb4c2011-10-20 18:41:46 +00002152 if (LocaleCompare("distort",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002153 {
2154 char
2155 *args,
2156 token[MaxTextExtent];
2157
2158 const char
2159 *p;
2160
2161 DistortImageMethod
2162 method;
2163
2164 double
2165 *arguments;
2166
2167 register ssize_t
2168 x;
2169
2170 size_t
2171 number_arguments;
2172
2173 /*
2174 Distort image.
2175 */
cristy6fccee12011-10-20 18:43:18 +00002176 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002177 method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
2178 MagickFalse,argv[1]);
2179 if ( method == ResizeDistortion )
2180 {
2181 /* Special Case - Argument is actually a resize geometry!
2182 ** Convert that to an appropriate distortion argument array.
2183 */
2184 double
2185 resize_args[2];
2186 (void) ParseRegionGeometry(*image,argv[2],&geometry,
2187 exception);
2188 resize_args[0]=(double)geometry.width;
2189 resize_args[1]=(double)geometry.height;
2190 new_image=DistortImage(*image,method,(size_t)2,
2191 resize_args,MagickTrue,exception);
2192 break;
2193 }
2194 args=InterpretImageProperties(image_info,*image,argv[2],
2195 exception);
2196 if (args == (char *) NULL)
2197 break;
2198 p=(char *) args;
2199 for (x=0; *p != '\0'; x++)
2200 {
2201 GetMagickToken(p,&p,token);
2202 if (*token == ',')
2203 GetMagickToken(p,&p,token);
2204 }
2205 number_arguments=(size_t) x;
2206 arguments=(double *) AcquireQuantumMemory(number_arguments,
2207 sizeof(*arguments));
2208 if (arguments == (double *) NULL)
2209 ThrowWandFatalException(ResourceLimitFatalError,
2210 "MemoryAllocationFailed",(*image)->filename);
2211 (void) ResetMagickMemory(arguments,0,number_arguments*
2212 sizeof(*arguments));
2213 p=(char *) args;
2214 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2215 {
2216 GetMagickToken(p,&p,token);
2217 if (*token == ',')
2218 GetMagickToken(p,&p,token);
2219 arguments[x]=InterpretLocaleValue(token,(char **) NULL);
2220 }
2221 args=DestroyString(args);
2222 new_image=DistortImage(*image,method,number_arguments,arguments,
2223 (*argv[0] == '+') ? MagickTrue : MagickFalse,exception);
2224 arguments=(double *) RelinquishMagickMemory(arguments);
2225 break;
2226 }
cristy947cb4c2011-10-20 18:41:46 +00002227 if (LocaleCompare("draw",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002228 {
cristy6fccee12011-10-20 18:43:18 +00002229 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002230 (void) CloneString(&draw_info->primitive,argv[1]);
2231 (void) DrawImage(*image,draw_info,exception);
2232 break;
2233 }
2234 break;
2235 }
2236 case 'e':
2237 {
cristy947cb4c2011-10-20 18:41:46 +00002238 if (LocaleCompare("edge",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002239 {
cristy6fccee12011-10-20 18:43:18 +00002240 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002241 flags=ParseGeometry(argv[1],&geometry_info);
2242 if ((flags & SigmaValue) == 0)
2243 geometry_info.sigma=1.0;
2244 new_image=EdgeImage(*image,geometry_info.rho,
2245 geometry_info.sigma,exception);
2246 break;
2247 }
cristy947cb4c2011-10-20 18:41:46 +00002248 if (LocaleCompare("emboss",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002249 {
cristy6fccee12011-10-20 18:43:18 +00002250 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002251 flags=ParseGeometry(argv[1],&geometry_info);
2252 if ((flags & SigmaValue) == 0)
2253 geometry_info.sigma=1.0;
2254 new_image=EmbossImage(*image,geometry_info.rho,
2255 geometry_info.sigma,exception);
2256 break;
2257 }
cristy947cb4c2011-10-20 18:41:46 +00002258 if (LocaleCompare("encipher",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002259 {
2260 StringInfo
2261 *passkey;
2262
cristy6fccee12011-10-20 18:43:18 +00002263 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002264 passkey=FileToStringInfo(argv[1],~0,exception);
2265 if (passkey != (StringInfo *) NULL)
2266 {
2267 (void) PasskeyEncipherImage(*image,passkey,exception);
2268 passkey=DestroyStringInfo(passkey);
2269 }
2270 break;
2271 }
cristy947cb4c2011-10-20 18:41:46 +00002272 if (LocaleCompare("enhance",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002273 {
cristy6fccee12011-10-20 18:43:18 +00002274 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002275 new_image=EnhanceImage(*image,exception);
2276 break;
2277 }
cristy947cb4c2011-10-20 18:41:46 +00002278 if (LocaleCompare("equalize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002279 {
cristy6fccee12011-10-20 18:43:18 +00002280 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002281 (void) EqualizeImage(*image,exception);
2282 break;
2283 }
cristy947cb4c2011-10-20 18:41:46 +00002284 if (LocaleCompare("evaluate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002285 {
2286 double
2287 constant;
2288
2289 MagickEvaluateOperator
2290 op;
2291
cristy6fccee12011-10-20 18:43:18 +00002292 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002293 op=(MagickEvaluateOperator) ParseCommandOption(
2294 MagickEvaluateOptions,MagickFalse,argv[1]);
2295 constant=SiPrefixToDouble(argv[2],QuantumRange);
2296 (void) EvaluateImage(*image,op,constant,exception);
2297 break;
2298 }
cristy947cb4c2011-10-20 18:41:46 +00002299 if (LocaleCompare("extent",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002300 {
cristy6fccee12011-10-20 18:43:18 +00002301 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002302 flags=ParseGravityGeometry(*image,argv[1],&geometry,exception);
2303 if (geometry.width == 0)
2304 geometry.width=(*image)->columns;
2305 if (geometry.height == 0)
2306 geometry.height=(*image)->rows;
2307 new_image=ExtentImage(*image,&geometry,exception);
2308 break;
2309 }
2310 break;
2311 }
2312 case 'f':
2313 {
cristy947cb4c2011-10-20 18:41:46 +00002314 if (LocaleCompare("features",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002315 {
anthonyafbaed72011-10-26 12:05:04 +00002316 /* FUTURE: Assign Artifact to all images -- per image setting */
anthony6dc09cd2011-10-12 08:56:49 +00002317 (void) SetImageArtifact(*image,"identify:features",
2318 IfSetOption ? argv[1] : (const char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002319 break;
2320 }
cristy947cb4c2011-10-20 18:41:46 +00002321 if (LocaleCompare("flip",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002322 {
cristy947cb4c2011-10-20 18:41:46 +00002323 /*
2324 Flip 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=FlipImage(*image,exception);
2328 break;
2329 }
cristy947cb4c2011-10-20 18:41:46 +00002330 if (LocaleCompare("flop",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002331 {
cristy947cb4c2011-10-20 18:41:46 +00002332 /*
2333 Flop image scanlines.
2334 */
cristy6fccee12011-10-20 18:43:18 +00002335 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002336 new_image=FlopImage(*image,exception);
2337 break;
2338 }
cristy947cb4c2011-10-20 18:41:46 +00002339 if (LocaleCompare("floodfill",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002340 {
2341 PixelInfo
2342 target;
2343
cristy947cb4c2011-10-20 18:41:46 +00002344 /*
2345 Floodfill image.
2346 */
cristy6fccee12011-10-20 18:43:18 +00002347 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002348 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
cristy269c9412011-10-13 23:41:15 +00002349 (void) QueryColorCompliance(argv[2],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00002350 exception);
anthony805a2d42011-09-25 08:25:12 +00002351 (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
2352 geometry.y,*argv[0] == '-' ? MagickFalse : MagickTrue,exception);
2353 break;
2354 }
cristy947cb4c2011-10-20 18:41:46 +00002355 /* FUTURE: should be from ImageOption "format"
2356 if (LocaleCompare("format",argv[0]+1) == 0)
2357 {
2358 format=argv[1];
2359 break;
2360 }
2361 */
2362 if (LocaleCompare("frame",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002363 {
2364 FrameInfo
2365 frame_info;
2366
cristy947cb4c2011-10-20 18:41:46 +00002367 /*
2368 Surround image with an ornamental border.
2369 */
cristy6fccee12011-10-20 18:43:18 +00002370 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002371 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
2372 frame_info.width=geometry.width;
2373 frame_info.height=geometry.height;
2374 if ((flags & HeightValue) == 0)
2375 frame_info.height=geometry.width;
2376 frame_info.outer_bevel=geometry.x;
2377 frame_info.inner_bevel=geometry.y;
2378 frame_info.x=(ssize_t) frame_info.width;
2379 frame_info.y=(ssize_t) frame_info.height;
2380 frame_info.width=(*image)->columns+2*frame_info.width;
2381 frame_info.height=(*image)->rows+2*frame_info.height;
anthony5f867ae2011-10-09 10:28:34 +00002382 new_image=FrameImage(*image,&frame_info,COMPOSE,exception);
anthony805a2d42011-09-25 08:25:12 +00002383 break;
2384 }
cristy947cb4c2011-10-20 18:41:46 +00002385 if (LocaleCompare("function",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002386 {
2387 char
2388 *arguments,
2389 token[MaxTextExtent];
2390
2391 const char
2392 *p;
2393
2394 double
2395 *parameters;
2396
2397 MagickFunction
2398 function;
2399
2400 register ssize_t
2401 x;
2402
2403 size_t
2404 number_parameters;
2405
cristy947cb4c2011-10-20 18:41:46 +00002406 /*
2407 Function Modify Image Values
2408 */
cristy6fccee12011-10-20 18:43:18 +00002409 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002410 function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
2411 MagickFalse,argv[1]);
2412 arguments=InterpretImageProperties(image_info,*image,argv[2],
2413 exception);
2414 if (arguments == (char *) NULL)
2415 break;
2416 p=(char *) arguments;
2417 for (x=0; *p != '\0'; x++)
2418 {
2419 GetMagickToken(p,&p,token);
2420 if (*token == ',')
2421 GetMagickToken(p,&p,token);
2422 }
2423 number_parameters=(size_t) x;
2424 parameters=(double *) AcquireQuantumMemory(number_parameters,
2425 sizeof(*parameters));
2426 if (parameters == (double *) NULL)
2427 ThrowWandFatalException(ResourceLimitFatalError,
2428 "MemoryAllocationFailed",(*image)->filename);
2429 (void) ResetMagickMemory(parameters,0,number_parameters*
2430 sizeof(*parameters));
2431 p=(char *) arguments;
2432 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
2433 {
2434 GetMagickToken(p,&p,token);
2435 if (*token == ',')
2436 GetMagickToken(p,&p,token);
2437 parameters[x]=InterpretLocaleValue(token,(char **) NULL);
2438 }
2439 arguments=DestroyString(arguments);
2440 (void) FunctionImage(*image,function,number_parameters,parameters,
2441 exception);
2442 parameters=(double *) RelinquishMagickMemory(parameters);
2443 break;
2444 }
2445 break;
2446 }
2447 case 'g':
2448 {
cristy947cb4c2011-10-20 18:41:46 +00002449 if (LocaleCompare("gamma",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002450 {
cristy6fccee12011-10-20 18:43:18 +00002451 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002452 if (*argv[0] == '+')
2453 (*image)->gamma=InterpretLocaleValue(argv[1],(char **) NULL);
2454 else
2455 (void) GammaImage(*image,InterpretLocaleValue(argv[1],
2456 (char **) NULL),exception);
2457 break;
2458 }
cristy947cb4c2011-10-20 18:41:46 +00002459 if ((LocaleCompare("gaussian-blur",argv[0]+1) == 0) ||
2460 (LocaleCompare("gaussian",argv[0]+1) == 0))
anthony805a2d42011-09-25 08:25:12 +00002461 {
cristy6fccee12011-10-20 18:43:18 +00002462 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002463 flags=ParseGeometry(argv[1],&geometry_info);
2464 if ((flags & SigmaValue) == 0)
2465 geometry_info.sigma=1.0;
2466 if ((flags & XiValue) == 0)
2467 geometry_info.xi=0.0;
2468 new_image=GaussianBlurImage(*image,geometry_info.rho,
2469 geometry_info.sigma,geometry_info.xi,exception);
2470 break;
2471 }
cristy947cb4c2011-10-20 18:41:46 +00002472 if (LocaleCompare("geometry",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002473 {
2474 /*
anthony6613bf32011-10-15 07:24:44 +00002475 Record Image offset for composition,
2476 Resize last image. -- FUTURE depreciate this aspect
anthony805a2d42011-09-25 08:25:12 +00002477 */
cristy6fccee12011-10-20 18:43:18 +00002478 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002479 if (*argv[0] == '+')
2480 {
2481 if ((*image)->geometry != (char *) NULL)
2482 (*image)->geometry=DestroyString((*image)->geometry);
2483 break;
2484 }
2485 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2486 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2487 (void) CloneString(&(*image)->geometry,argv[1]);
2488 else
2489 new_image=ResizeImage(*image,geometry.width,geometry.height,
2490 (*image)->filter,(*image)->blur,exception);
2491 break;
2492 }
anthony805a2d42011-09-25 08:25:12 +00002493 break;
2494 }
2495 case 'h':
2496 {
cristy947cb4c2011-10-20 18:41:46 +00002497 if (LocaleCompare("highlight-color",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002498 {
cristy947cb4c2011-10-20 18:41:46 +00002499 (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00002500 break;
2501 }
2502 break;
2503 }
2504 case 'i':
2505 {
cristy947cb4c2011-10-20 18:41:46 +00002506 if (LocaleCompare("identify",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002507 {
2508 char
2509 *text;
2510
cristy6fccee12011-10-20 18:43:18 +00002511 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002512 if (format == (char *) NULL)
2513 {
2514 (void) IdentifyImage(*image,stdout,image_info->verbose,
2515 exception);
2516 break;
2517 }
2518 text=InterpretImageProperties(image_info,*image,format,
2519 exception);
2520 if (text == (char *) NULL)
2521 break;
2522 (void) fputs(text,stdout);
2523 (void) fputc('\n',stdout);
2524 text=DestroyString(text);
2525 break;
2526 }
cristy947cb4c2011-10-20 18:41:46 +00002527 if (LocaleCompare("implode",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002528 {
cristy947cb4c2011-10-20 18:41:46 +00002529 /*
2530 Implode image.
2531 */
cristy6fccee12011-10-20 18:43:18 +00002532 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002533 (void) ParseGeometry(argv[1],&geometry_info);
anthonya89dd172011-10-04 13:29:35 +00002534 new_image=ImplodeImage(*image,geometry_info.rho,
2535 interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00002536 break;
2537 }
cristy947cb4c2011-10-20 18:41:46 +00002538 if (LocaleCompare("interline-spacing",argv[0]+1) == 0)
2539 {
2540 if (*argv[0] == '+')
2541 (void) ParseGeometry("0",&geometry_info);
2542 else
2543 (void) ParseGeometry(argv[1],&geometry_info);
2544 draw_info->interline_spacing=geometry_info.rho;
2545 break;
2546 }
2547 if (LocaleCompare("interpolate",argv[0]+1) == 0)
2548 {
2549 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
2550 MagickInterpolateOptions,MagickFalse,argv[1]);
2551 break;
2552 }
2553 if (LocaleCompare("interword-spacing",argv[0]+1) == 0)
2554 {
2555 if (*argv[0] == '+')
2556 (void) ParseGeometry("0",&geometry_info);
2557 else
2558 (void) ParseGeometry(argv[1],&geometry_info);
2559 draw_info->interword_spacing=geometry_info.rho;
2560 break;
2561 }
2562 break;
2563 }
2564 case 'k':
2565 {
2566 if (LocaleCompare("kerning",argv[0]+1) == 0)
2567 {
2568 if (*argv[0] == '+')
2569 (void) ParseGeometry("0",&geometry_info);
2570 else
2571 (void) ParseGeometry(argv[1],&geometry_info);
2572 draw_info->kerning=geometry_info.rho;
2573 break;
2574 }
anthony805a2d42011-09-25 08:25:12 +00002575 break;
2576 }
2577 case 'l':
2578 {
cristy947cb4c2011-10-20 18:41:46 +00002579 if (LocaleCompare("lat",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002580 {
2581 /*
2582 Local adaptive threshold image.
2583 */
cristy6fccee12011-10-20 18:43:18 +00002584 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002585 flags=ParseGeometry(argv[1],&geometry_info);
2586 if ((flags & PercentValue) != 0)
2587 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2588 new_image=AdaptiveThresholdImage(*image,(size_t)
2589 geometry_info.rho,(size_t) geometry_info.sigma,(double)
2590 geometry_info.xi,exception);
2591 break;
2592 }
cristy947cb4c2011-10-20 18:41:46 +00002593 if (LocaleCompare("level",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002594 {
2595 MagickRealType
2596 black_point,
2597 gamma,
2598 white_point;
2599
2600 MagickStatusType
2601 flags;
2602
cristy947cb4c2011-10-20 18:41:46 +00002603 /*
2604 Parse levels.
2605 */
cristy6fccee12011-10-20 18:43:18 +00002606 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002607 flags=ParseGeometry(argv[1],&geometry_info);
2608 black_point=geometry_info.rho;
2609 white_point=(MagickRealType) QuantumRange;
2610 if ((flags & SigmaValue) != 0)
2611 white_point=geometry_info.sigma;
2612 gamma=1.0;
2613 if ((flags & XiValue) != 0)
2614 gamma=geometry_info.xi;
2615 if ((flags & PercentValue) != 0)
2616 {
2617 black_point*=(MagickRealType) (QuantumRange/100.0);
2618 white_point*=(MagickRealType) (QuantumRange/100.0);
2619 }
2620 if ((flags & SigmaValue) == 0)
2621 white_point=(MagickRealType) QuantumRange-black_point;
2622 if ((*argv[0] == '+') || ((flags & AspectValue) != 0))
2623 (void) LevelizeImage(*image,black_point,white_point,gamma,
2624 exception);
2625 else
2626 (void) LevelImage(*image,black_point,white_point,gamma,
2627 exception);
anthony805a2d42011-09-25 08:25:12 +00002628 break;
2629 }
cristy947cb4c2011-10-20 18:41:46 +00002630 if (LocaleCompare("level-colors",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002631 {
2632 char
2633 token[MaxTextExtent];
2634
2635 const char
2636 *p;
2637
2638 PixelInfo
2639 black_point,
2640 white_point;
2641
2642 p=(const char *) argv[1];
2643 GetMagickToken(p,&p,token); /* get black point color */
2644 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002645 (void) QueryColorCompliance(token,AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002646 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002647 else
cristy269c9412011-10-13 23:41:15 +00002648 (void) QueryColorCompliance("#000000",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002649 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002650 if (isalpha((int) token[0]) || (token[0] == '#'))
2651 GetMagickToken(p,&p,token);
2652 if (*token == '\0')
2653 white_point=black_point; /* set everything to that color */
2654 else
2655 {
2656 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2657 GetMagickToken(p,&p,token); /* Get white point color. */
2658 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002659 (void) QueryColorCompliance(token,AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002660 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002661 else
cristy269c9412011-10-13 23:41:15 +00002662 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002663 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002664 }
2665 (void) LevelImageColors(*image,&black_point,&white_point,
2666 *argv[0] == '+' ? MagickTrue : MagickFalse,exception);
2667 break;
2668 }
cristy947cb4c2011-10-20 18:41:46 +00002669 if (LocaleCompare("linear-stretch",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002670 {
2671 double
2672 black_point,
2673 white_point;
2674
2675 MagickStatusType
2676 flags;
2677
cristy6fccee12011-10-20 18:43:18 +00002678 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002679 flags=ParseGeometry(argv[1],&geometry_info);
2680 black_point=geometry_info.rho;
2681 white_point=(MagickRealType) (*image)->columns*(*image)->rows;
2682 if ((flags & SigmaValue) != 0)
2683 white_point=geometry_info.sigma;
2684 if ((flags & PercentValue) != 0)
2685 {
2686 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2687 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2688 }
2689 if ((flags & SigmaValue) == 0)
2690 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2691 black_point;
2692 (void) LinearStretchImage(*image,black_point,white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002693 break;
2694 }
cristy947cb4c2011-10-20 18:41:46 +00002695 if (LocaleCompare("linewidth",argv[0]+1) == 0)
2696 {
2697 draw_info->stroke_width=InterpretLocaleValue(argv[1],
2698 (char **) NULL);
2699 break;
2700 }
2701 if (LocaleCompare("liquid-rescale",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002702 {
2703 /*
2704 Liquid rescale image.
2705 */
cristy6fccee12011-10-20 18:43:18 +00002706 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002707 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2708 if ((flags & XValue) == 0)
2709 geometry.x=1;
2710 if ((flags & YValue) == 0)
2711 geometry.y=0;
2712 new_image=LiquidRescaleImage(*image,geometry.width,
2713 geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
2714 break;
2715 }
cristy947cb4c2011-10-20 18:41:46 +00002716 if (LocaleCompare("lowlight-color",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002717 {
cristy947cb4c2011-10-20 18:41:46 +00002718 (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00002719 break;
2720 }
2721 break;
2722 }
2723 case 'm':
2724 {
cristy947cb4c2011-10-20 18:41:46 +00002725 if (LocaleCompare("map",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002726 {
2727 Image
2728 *remap_image;
2729
cristy947cb4c2011-10-20 18:41:46 +00002730 /*
2731 Transform image colors to match this set of colors.
2732 */
cristy6fccee12011-10-20 18:43:18 +00002733 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002734 if (*argv[0] == '+')
2735 break;
2736 remap_image=GetImageCache(image_info,argv[1],exception);
2737 if (remap_image == (Image *) NULL)
2738 break;
2739 (void) RemapImage(quantize_info,*image,remap_image,exception);
2740 remap_image=DestroyImage(remap_image);
2741 break;
2742 }
cristy947cb4c2011-10-20 18:41:46 +00002743 if (LocaleCompare("mask",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002744 {
2745 Image
2746 *mask;
2747
cristy6fccee12011-10-20 18:43:18 +00002748 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002749 if (*argv[0] == '+')
2750 {
cristy947cb4c2011-10-20 18:41:46 +00002751 /*
2752 Remove a mask.
2753 */
anthony805a2d42011-09-25 08:25:12 +00002754 (void) SetImageMask(*image,(Image *) NULL,exception);
2755 break;
2756 }
cristy947cb4c2011-10-20 18:41:46 +00002757 /*
2758 Set the image mask.
2759 */
anthony805a2d42011-09-25 08:25:12 +00002760 mask=GetImageCache(image_info,argv[1],exception);
2761 if (mask == (Image *) NULL)
2762 break;
2763 (void) SetImageMask(*image,mask,exception);
2764 mask=DestroyImage(mask);
2765 break;
2766 }
cristy947cb4c2011-10-20 18:41:46 +00002767 if (LocaleCompare("matte",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002768 {
cristy947cb4c2011-10-20 18:41:46 +00002769 (void) SetImageAlphaChannel(*image,(*argv[0] == '-') ?
2770 SetAlphaChannel : DeactivateAlphaChannel,exception);
anthony805a2d42011-09-25 08:25:12 +00002771 break;
2772 }
cristy947cb4c2011-10-20 18:41:46 +00002773 if (LocaleCompare("median",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002774 {
cristy947cb4c2011-10-20 18:41:46 +00002775 /*
2776 Median filter image.
2777 */
cristy6fccee12011-10-20 18:43:18 +00002778 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002779 flags=ParseGeometry(argv[1],&geometry_info);
2780 if ((flags & SigmaValue) == 0)
2781 geometry_info.sigma=geometry_info.rho;
2782 new_image=StatisticImage(*image,MedianStatistic,(size_t)
2783 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2784 break;
2785 }
cristy947cb4c2011-10-20 18:41:46 +00002786 if (LocaleCompare("mode",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002787 {
2788 /*
cristy947cb4c2011-10-20 18:41:46 +00002789 Mode image.
anthony805a2d42011-09-25 08:25:12 +00002790 */
cristy6fccee12011-10-20 18:43:18 +00002791 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002792 flags=ParseGeometry(argv[1],&geometry_info);
2793 if ((flags & SigmaValue) == 0)
2794 geometry_info.sigma=geometry_info.rho;
2795 new_image=StatisticImage(*image,ModeStatistic,(size_t)
2796 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2797 break;
2798 }
cristy947cb4c2011-10-20 18:41:46 +00002799 if (LocaleCompare("modulate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002800 {
cristy6fccee12011-10-20 18:43:18 +00002801 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002802 (void) ModulateImage(*image,argv[1],exception);
2803 break;
2804 }
cristy947cb4c2011-10-20 18:41:46 +00002805 if (LocaleCompare("monitor",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002806 {
anthonyafbaed72011-10-26 12:05:04 +00002807 /* FUTURE: Why is this a per-image setting? */
anthony805a2d42011-09-25 08:25:12 +00002808 if (*argv[0] == '+')
2809 {
2810 (void) SetImageProgressMonitor(*image,
2811 (MagickProgressMonitor) NULL,(void *) NULL);
2812 break;
2813 }
2814 (void) SetImageProgressMonitor(*image,MonitorProgress,
2815 (void *) NULL);
2816 break;
2817 }
cristy947cb4c2011-10-20 18:41:46 +00002818 if (LocaleCompare("monochrome",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002819 {
cristy6fccee12011-10-20 18:43:18 +00002820 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002821 (void) SetImageType(*image,BilevelType,exception);
2822 break;
2823 }
cristy947cb4c2011-10-20 18:41:46 +00002824 if (LocaleCompare("morphology",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002825 {
2826 char
2827 token[MaxTextExtent];
2828
2829 const char
2830 *p;
2831
2832 KernelInfo
2833 *kernel;
2834
2835 MorphologyMethod
2836 method;
2837
2838 ssize_t
2839 iterations;
2840
cristy6fccee12011-10-20 18:43:18 +00002841 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002842 p=argv[1];
2843 GetMagickToken(p,&p,token);
2844 method=(MorphologyMethod) ParseCommandOption(
2845 MagickMorphologyOptions,MagickFalse,token);
2846 iterations=1L;
2847 GetMagickToken(p,&p,token);
2848 if ((*p == ':') || (*p == ','))
2849 GetMagickToken(p,&p,token);
2850 if ((*p != '\0'))
2851 iterations=(ssize_t) StringToLong(p);
2852 kernel=AcquireKernelInfo(argv[2]);
2853 if (kernel == (KernelInfo *) NULL)
2854 {
2855 (void) ThrowMagickException(exception,GetMagickModule(),
2856 OptionError,"UnabletoParseKernel","morphology");
2857 status=MagickFalse;
2858 break;
2859 }
2860 new_image=MorphologyImage(*image,method,iterations,kernel,
2861 exception);
2862 kernel=DestroyKernelInfo(kernel);
2863 break;
2864 }
cristy947cb4c2011-10-20 18:41:46 +00002865 if (LocaleCompare("motion-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002866 {
cristy947cb4c2011-10-20 18:41:46 +00002867 /*
2868 Motion blur image.
2869 */
cristy6fccee12011-10-20 18:43:18 +00002870 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002871 flags=ParseGeometry(argv[1],&geometry_info);
2872 if ((flags & SigmaValue) == 0)
2873 geometry_info.sigma=1.0;
2874 new_image=MotionBlurImage(*image,geometry_info.rho,
2875 geometry_info.sigma,geometry_info.xi,geometry_info.psi,
2876 exception);
2877 break;
2878 }
2879 break;
2880 }
2881 case 'n':
2882 {
cristy947cb4c2011-10-20 18:41:46 +00002883 if (LocaleCompare("negate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002884 {
cristy6fccee12011-10-20 18:43:18 +00002885 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002886 (void) NegateImage(*image,*argv[0] == '+' ? MagickTrue :
2887 MagickFalse,exception);
2888 break;
2889 }
cristy947cb4c2011-10-20 18:41:46 +00002890 if (LocaleCompare("noise",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002891 {
cristy6fccee12011-10-20 18:43:18 +00002892 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002893 if (*argv[0] == '-')
2894 {
2895 flags=ParseGeometry(argv[1],&geometry_info);
2896 if ((flags & SigmaValue) == 0)
2897 geometry_info.sigma=geometry_info.rho;
2898 new_image=StatisticImage(*image,NonpeakStatistic,(size_t)
2899 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2900 }
2901 else
2902 {
2903 NoiseType
2904 noise;
2905
2906 noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
2907 MagickFalse,argv[1]);
anthony5f867ae2011-10-09 10:28:34 +00002908 new_image=AddNoiseImage(*image,noise,exception);
anthony805a2d42011-09-25 08:25:12 +00002909 }
2910 break;
2911 }
cristy947cb4c2011-10-20 18:41:46 +00002912 if (LocaleCompare("normalize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002913 {
cristy6fccee12011-10-20 18:43:18 +00002914 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002915 (void) NormalizeImage(*image,exception);
2916 break;
2917 }
2918 break;
2919 }
2920 case 'o':
2921 {
cristy947cb4c2011-10-20 18:41:46 +00002922 if (LocaleCompare("opaque",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002923 {
2924 PixelInfo
2925 target;
2926
cristy6fccee12011-10-20 18:43:18 +00002927 (void) SyncImageSettings(image_info,*image,exception);
cristy269c9412011-10-13 23:41:15 +00002928 (void) QueryColorCompliance(argv[1],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00002929 exception);
anthony805a2d42011-09-25 08:25:12 +00002930 (void) OpaquePaintImage(*image,&target,&fill,*argv[0] == '-' ?
2931 MagickFalse : MagickTrue,exception);
2932 break;
2933 }
cristy947cb4c2011-10-20 18:41:46 +00002934 if (LocaleCompare("ordered-dither",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002935 {
cristy6fccee12011-10-20 18:43:18 +00002936 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002937 (void) OrderedPosterizeImage(*image,argv[1],exception);
2938 break;
2939 }
2940 break;
2941 }
2942 case 'p':
2943 {
cristy947cb4c2011-10-20 18:41:46 +00002944 if (LocaleCompare("paint",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002945 {
cristy6fccee12011-10-20 18:43:18 +00002946 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002947 (void) ParseGeometry(argv[1],&geometry_info);
2948 new_image=OilPaintImage(*image,geometry_info.rho,
2949 geometry_info.sigma,exception);
2950 break;
2951 }
cristy947cb4c2011-10-20 18:41:46 +00002952 if (LocaleCompare("pen",argv[0]+1) == 0)
2953 {
2954 if (*argv[0] == '+')
2955 {
2956 (void) QueryColorCompliance("none",AllCompliance,&draw_info->fill,
2957 exception);
2958 break;
2959 }
2960 (void) QueryColorCompliance(argv[1],AllCompliance,&draw_info->fill,
2961 exception);
2962 break;
2963 }
2964 if (LocaleCompare("pointsize",argv[0]+1) == 0)
2965 {
2966 if (*argv[0] == '+')
2967 (void) ParseGeometry("12",&geometry_info);
2968 else
2969 (void) ParseGeometry(argv[1],&geometry_info);
2970 draw_info->pointsize=geometry_info.rho;
2971 break;
2972 }
2973 if (LocaleCompare("polaroid",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002974 {
2975 double
2976 angle;
2977
2978 RandomInfo
2979 *random_info;
2980
cristy947cb4c2011-10-20 18:41:46 +00002981 /*
2982 Simulate a Polaroid picture.
2983 */
cristy6fccee12011-10-20 18:43:18 +00002984 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00002985 random_info=AcquireRandomInfo();
2986 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2987 random_info=DestroyRandomInfo(random_info);
2988 if (*argv[0] == '-')
2989 {
2990 SetGeometryInfo(&geometry_info);
2991 flags=ParseGeometry(argv[1],&geometry_info);
2992 angle=geometry_info.rho;
2993 }
2994 new_image=PolaroidImage(*image,draw_info,angle,
2995 interpolate_method,exception);
2996 break;
2997 }
cristy947cb4c2011-10-20 18:41:46 +00002998 if (LocaleCompare("posterize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002999 {
cristy947cb4c2011-10-20 18:41:46 +00003000 /*
3001 Posterize image.
3002 */
cristy6fccee12011-10-20 18:43:18 +00003003 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003004 (void) PosterizeImage(*image,StringToUnsignedLong(argv[1]),
3005 quantize_info->dither,exception);
3006 break;
3007 }
cristy947cb4c2011-10-20 18:41:46 +00003008 if (LocaleCompare("preview",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003009 {
3010 PreviewType
cristy947cb4c2011-10-20 18:41:46 +00003011 preview_type;
anthony170fce92011-10-20 11:50:23 +00003012
cristy947cb4c2011-10-20 18:41:46 +00003013 /*
3014 Preview image.
3015 */
cristy6fccee12011-10-20 18:43:18 +00003016 (void) SyncImageSettings(image_info,*image,exception);
cristy947cb4c2011-10-20 18:41:46 +00003017 if (*argv[0] == '+')
3018 preview_type=UndefinedPreview;
3019 else
anthony805a2d42011-09-25 08:25:12 +00003020 preview_type=(PreviewType) ParseCommandOption(
3021 MagickPreviewOptions,MagickFalse,argv[1]);
3022 new_image=PreviewImage(*image,preview_type,exception);
3023 break;
3024 }
cristy947cb4c2011-10-20 18:41:46 +00003025 if (LocaleCompare("profile",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003026 {
3027 const char
3028 *name;
3029
3030 const StringInfo
3031 *profile;
3032
3033 Image
3034 *profile_image;
3035
3036 ImageInfo
3037 *profile_info;
3038
cristy6fccee12011-10-20 18:43:18 +00003039 (void) SyncImageSettings(image_info,*image,exception);
cristy947cb4c2011-10-20 18:41:46 +00003040 if (*argv[0] == '+')
anthony805a2d42011-09-25 08:25:12 +00003041 {
cristy947cb4c2011-10-20 18:41:46 +00003042 /*
3043 Remove a profile from the image.
3044 */
anthony805a2d42011-09-25 08:25:12 +00003045 (void) ProfileImage(*image,argv[1],(const unsigned char *)
cristy092d71c2011-10-14 18:01:29 +00003046 NULL,0,exception);
anthony805a2d42011-09-25 08:25:12 +00003047 break;
3048 }
cristy947cb4c2011-10-20 18:41:46 +00003049 /*
3050 Associate a profile with the image.
3051 */
anthony805a2d42011-09-25 08:25:12 +00003052 profile_info=CloneImageInfo(image_info);
3053 profile=GetImageProfile(*image,"iptc");
3054 if (profile != (StringInfo *) NULL)
3055 profile_info->profile=(void *) CloneStringInfo(profile);
3056 profile_image=GetImageCache(profile_info,argv[1],exception);
3057 profile_info=DestroyImageInfo(profile_info);
3058 if (profile_image == (Image *) NULL)
3059 {
3060 StringInfo
3061 *profile;
3062
3063 profile_info=CloneImageInfo(image_info);
3064 (void) CopyMagickString(profile_info->filename,argv[1],
3065 MaxTextExtent);
3066 profile=FileToStringInfo(profile_info->filename,~0UL,exception);
3067 if (profile != (StringInfo *) NULL)
3068 {
3069 (void) ProfileImage(*image,profile_info->magick,
3070 GetStringInfoDatum(profile),(size_t)
cristy092d71c2011-10-14 18:01:29 +00003071 GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003072 profile=DestroyStringInfo(profile);
3073 }
3074 profile_info=DestroyImageInfo(profile_info);
3075 break;
3076 }
3077 ResetImageProfileIterator(profile_image);
3078 name=GetNextImageProfile(profile_image);
3079 while (name != (const char *) NULL)
3080 {
3081 profile=GetImageProfile(profile_image,name);
3082 if (profile != (StringInfo *) NULL)
3083 (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
cristy092d71c2011-10-14 18:01:29 +00003084 (size_t) GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003085 name=GetNextImageProfile(profile_image);
3086 }
3087 profile_image=DestroyImage(profile_image);
3088 break;
3089 }
3090 break;
3091 }
cristy947cb4c2011-10-20 18:41:46 +00003092 case 'q':
3093 {
3094 if (LocaleCompare("quantize",argv[0]+1) == 0)
3095 {
3096 if (*argv[0] == '+')
3097 {
3098 quantize_info->colorspace=UndefinedColorspace;
3099 break;
3100 }
3101 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
3102 MagickColorspaceOptions,MagickFalse,argv[1]);
3103 break;
3104 }
3105 break;
3106 }
anthony805a2d42011-09-25 08:25:12 +00003107 case 'r':
3108 {
cristy947cb4c2011-10-20 18:41:46 +00003109 if (LocaleCompare("radial-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003110 {
cristy6fccee12011-10-20 18:43:18 +00003111 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003112 flags=ParseGeometry(argv[1],&geometry_info);
3113 new_image=RadialBlurImage(*image,geometry_info.rho,
3114 geometry_info.sigma,exception);
3115 break;
3116 }
cristy947cb4c2011-10-20 18:41:46 +00003117 if (LocaleCompare("raise",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003118 {
anthony805a2d42011-09-25 08:25:12 +00003119 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3120 if ((flags & SigmaValue) == 0)
3121 geometry.height=geometry.width;
3122 (void) RaiseImage(*image,&geometry,*argv[0] == '-' ? MagickTrue :
3123 MagickFalse,exception);
3124 break;
3125 }
cristy947cb4c2011-10-20 18:41:46 +00003126 if (LocaleCompare("random-threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003127 {
cristy6fccee12011-10-20 18:43:18 +00003128 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003129 (void) RandomThresholdImage(*image,argv[1],exception);
3130 break;
3131 }
cristy947cb4c2011-10-20 18:41:46 +00003132 if (LocaleCompare("recolor",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003133 {
3134 KernelInfo
3135 *kernel;
3136
cristy6fccee12011-10-20 18:43:18 +00003137 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003138 kernel=AcquireKernelInfo(argv[1]);
3139 if (kernel == (KernelInfo *) NULL)
3140 break;
3141 new_image=ColorMatrixImage(*image,kernel,exception);
3142 kernel=DestroyKernelInfo(kernel);
3143 break;
3144 }
cristy947cb4c2011-10-20 18:41:46 +00003145 if (LocaleCompare("remap",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003146 {
3147 Image
3148 *remap_image;
3149
cristy6fccee12011-10-20 18:43:18 +00003150 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003151 if (*argv[0] == '+')
3152 break;
3153 remap_image=GetImageCache(image_info,argv[1],exception);
3154 if (remap_image == (Image *) NULL)
3155 break;
3156 (void) RemapImage(quantize_info,*image,remap_image,exception);
3157 remap_image=DestroyImage(remap_image);
3158 break;
3159 }
cristy947cb4c2011-10-20 18:41:46 +00003160 if (LocaleCompare("repage",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003161 {
3162 if (*argv[0] == '+')
3163 {
3164 (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
3165 break;
3166 }
3167 (void) ResetImagePage(*image,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00003168 break;
3169 }
cristy947cb4c2011-10-20 18:41:46 +00003170 if (LocaleCompare("resample",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003171 {
anthonyafbaed72011-10-26 12:05:04 +00003172 /* FUTURE: remove blur - no longer used */
cristy6fccee12011-10-20 18:43:18 +00003173 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003174 flags=ParseGeometry(argv[1],&geometry_info);
3175 if ((flags & SigmaValue) == 0)
3176 geometry_info.sigma=geometry_info.rho;
3177 new_image=ResampleImage(*image,geometry_info.rho,
3178 geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
3179 break;
3180 }
cristy947cb4c2011-10-20 18:41:46 +00003181 if (LocaleCompare("resize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003182 {
anthonyafbaed72011-10-26 12:05:04 +00003183 /* FUTURE: remove blur argument - no longer used */
cristy6fccee12011-10-20 18:43:18 +00003184 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003185 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3186 new_image=ResizeImage(*image,geometry.width,geometry.height,
3187 (*image)->filter,(*image)->blur,exception);
3188 break;
3189 }
cristy947cb4c2011-10-20 18:41:46 +00003190 if (LocaleCompare("roll",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003191 {
cristy6fccee12011-10-20 18:43:18 +00003192 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003193 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
3194 new_image=RollImage(*image,geometry.x,geometry.y,exception);
3195 break;
3196 }
cristy947cb4c2011-10-20 18:41:46 +00003197 if (LocaleCompare("rotate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003198 {
anthonyafbaed72011-10-26 12:05:04 +00003199 /* special case rotation flags */
cristy6fccee12011-10-20 18:43:18 +00003200 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003201 if (strchr(argv[1],'>') != (char *) NULL)
3202 if ((*image)->columns <= (*image)->rows)
3203 break;
3204 if (strchr(argv[1],'<') != (char *) NULL)
3205 if ((*image)->columns >= (*image)->rows)
3206 break;
anthonyafbaed72011-10-26 12:05:04 +00003207
3208 (void) ParseGeometry(argv[1],&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003209 new_image=RotateImage(*image,geometry_info.rho,exception);
3210 break;
3211 }
3212 break;
3213 }
3214 case 's':
3215 {
cristy947cb4c2011-10-20 18:41:46 +00003216 if (LocaleCompare("sample",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003217 {
cristy6fccee12011-10-20 18:43:18 +00003218 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003219 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3220 new_image=SampleImage(*image,geometry.width,geometry.height,
3221 exception);
3222 break;
3223 }
cristy947cb4c2011-10-20 18:41:46 +00003224 if (LocaleCompare("scale",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003225 {
cristy6fccee12011-10-20 18:43:18 +00003226 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003227 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3228 new_image=ScaleImage(*image,geometry.width,geometry.height,
3229 exception);
3230 break;
3231 }
cristy947cb4c2011-10-20 18:41:46 +00003232 if (LocaleCompare("selective-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003233 {
cristy6fccee12011-10-20 18:43:18 +00003234 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003235 flags=ParseGeometry(argv[1],&geometry_info);
3236 if ((flags & PercentValue) != 0)
3237 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3238 new_image=SelectiveBlurImage(*image,geometry_info.rho,
3239 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3240 break;
3241 }
cristy947cb4c2011-10-20 18:41:46 +00003242 if (LocaleCompare("separate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003243 {
3244 /*
3245 Break channels into separate images.
3246 WARNING: This can generate multiple images!
3247 */
cristy6fccee12011-10-20 18:43:18 +00003248 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003249 new_image=SeparateImages(*image,exception);
3250 break;
3251 }
cristy947cb4c2011-10-20 18:41:46 +00003252 if (LocaleCompare("sepia-tone",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003253 {
3254 double
3255 threshold;
3256
cristy6fccee12011-10-20 18:43:18 +00003257 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003258 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3259 new_image=SepiaToneImage(*image,threshold,exception);
3260 break;
3261 }
cristy947cb4c2011-10-20 18:41:46 +00003262 if (LocaleCompare("segment",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003263 {
cristy6fccee12011-10-20 18:43:18 +00003264 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003265 flags=ParseGeometry(argv[1],&geometry_info);
3266 if ((flags & SigmaValue) == 0)
3267 geometry_info.sigma=1.0;
3268 (void) SegmentImage(*image,(*image)->colorspace,
3269 image_info->verbose,geometry_info.rho,geometry_info.sigma,
3270 exception);
3271 break;
3272 }
cristy947cb4c2011-10-20 18:41:46 +00003273 if (LocaleCompare("set",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003274 {
3275 char
3276 *value;
3277
anthony805a2d42011-09-25 08:25:12 +00003278 if (*argv[0] == '+')
3279 {
3280 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3281 (void) DeleteImageRegistry(argv[1]+9);
3282 else
3283 if (LocaleNCompare(argv[1],"argv[0]:",7) == 0)
3284 {
3285 (void) DeleteImageOption(image_info,argv[1]+7);
3286 (void) DeleteImageArtifact(*image,argv[1]+7);
3287 }
3288 else
3289 (void) DeleteImageProperty(*image,argv[1]);
3290 break;
3291 }
3292 value=InterpretImageProperties(image_info,*image,argv[2],
3293 exception);
3294 if (value == (char *) NULL)
3295 break;
3296 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3297 (void) SetImageRegistry(StringRegistryType,argv[1]+9,value,
3298 exception);
3299 else
anthonya89dd172011-10-04 13:29:35 +00003300 if (LocaleNCompare(argv[1],"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003301 {
3302 (void) SetImageOption(image_info,argv[1]+7,value);
anthony805a2d42011-09-25 08:25:12 +00003303 (void) SetImageArtifact(*image,argv[1]+7,value);
3304 }
3305 else
cristyd15e6592011-10-15 00:13:06 +00003306 (void) SetImageProperty(*image,argv[1],value,exception);
anthony805a2d42011-09-25 08:25:12 +00003307 value=DestroyString(value);
3308 break;
3309 }
cristy947cb4c2011-10-20 18:41:46 +00003310 if (LocaleCompare("shade",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003311 {
cristy6fccee12011-10-20 18:43:18 +00003312 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003313 flags=ParseGeometry(argv[1],&geometry_info);
3314 if ((flags & SigmaValue) == 0)
3315 geometry_info.sigma=1.0;
3316 new_image=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue :
3317 MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
3318 break;
3319 }
cristy947cb4c2011-10-20 18:41:46 +00003320 if (LocaleCompare("shadow",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003321 {
cristy6fccee12011-10-20 18:43:18 +00003322 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003323 flags=ParseGeometry(argv[1],&geometry_info);
3324 if ((flags & SigmaValue) == 0)
3325 geometry_info.sigma=1.0;
3326 if ((flags & XiValue) == 0)
3327 geometry_info.xi=4.0;
3328 if ((flags & PsiValue) == 0)
3329 geometry_info.psi=4.0;
3330 new_image=ShadowImage(*image,geometry_info.rho,
3331 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3332 ceil(geometry_info.psi-0.5),exception);
3333 break;
3334 }
cristy947cb4c2011-10-20 18:41:46 +00003335 if (LocaleCompare("sharpen",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003336 {
cristy6fccee12011-10-20 18:43:18 +00003337 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003338 flags=ParseGeometry(argv[1],&geometry_info);
3339 if ((flags & SigmaValue) == 0)
3340 geometry_info.sigma=1.0;
3341 if ((flags & XiValue) == 0)
3342 geometry_info.xi=0.0;
3343 new_image=SharpenImage(*image,geometry_info.rho,
3344 geometry_info.sigma,geometry_info.xi,exception);
3345 break;
3346 }
cristy947cb4c2011-10-20 18:41:46 +00003347 if (LocaleCompare("shave",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003348 {
cristy6fccee12011-10-20 18:43:18 +00003349 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003350 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3351 new_image=ShaveImage(*image,&geometry,exception);
3352 break;
3353 }
cristy947cb4c2011-10-20 18:41:46 +00003354 if (LocaleCompare("shear",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003355 {
cristy6fccee12011-10-20 18:43:18 +00003356 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003357 flags=ParseGeometry(argv[1],&geometry_info);
3358 if ((flags & SigmaValue) == 0)
3359 geometry_info.sigma=geometry_info.rho;
3360 new_image=ShearImage(*image,geometry_info.rho,
3361 geometry_info.sigma,exception);
3362 break;
3363 }
cristy947cb4c2011-10-20 18:41:46 +00003364 if (LocaleCompare("sigmoidal-contrast",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003365 {
cristy6fccee12011-10-20 18:43:18 +00003366 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003367 flags=ParseGeometry(argv[1],&geometry_info);
3368 if ((flags & SigmaValue) == 0)
3369 geometry_info.sigma=(double) QuantumRange/2.0;
3370 if ((flags & PercentValue) != 0)
3371 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3372 100.0;
3373 (void) SigmoidalContrastImage(*image,(*argv[0] == '-') ?
3374 MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
3375 exception);
3376 break;
3377 }
cristy947cb4c2011-10-20 18:41:46 +00003378 if (LocaleCompare("sketch",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003379 {
cristy6fccee12011-10-20 18:43:18 +00003380 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003381 flags=ParseGeometry(argv[1],&geometry_info);
3382 if ((flags & SigmaValue) == 0)
3383 geometry_info.sigma=1.0;
3384 new_image=SketchImage(*image,geometry_info.rho,
3385 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3386 break;
3387 }
cristy947cb4c2011-10-20 18:41:46 +00003388 if (LocaleCompare("solarize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003389 {
3390 double
3391 threshold;
3392
cristy6fccee12011-10-20 18:43:18 +00003393 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003394 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3395 (void) SolarizeImage(*image,threshold,exception);
3396 break;
3397 }
cristy947cb4c2011-10-20 18:41:46 +00003398 if (LocaleCompare("sparse-color",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003399 {
3400 SparseColorMethod
3401 method;
3402
3403 char
3404 *arguments;
3405
cristy6fccee12011-10-20 18:43:18 +00003406 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003407 method=(SparseColorMethod) ParseCommandOption(
3408 MagickSparseColorOptions,MagickFalse,argv[1]);
3409 arguments=InterpretImageProperties(image_info,*image,argv[2],
3410 exception);
3411 if (arguments == (char *) NULL)
3412 break;
3413 new_image=SparseColorOption(*image,method,arguments,
3414 argv[0][0] == '+' ? MagickTrue : MagickFalse,exception);
3415 arguments=DestroyString(arguments);
3416 break;
3417 }
cristy947cb4c2011-10-20 18:41:46 +00003418 if (LocaleCompare("splice",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003419 {
cristy6fccee12011-10-20 18:43:18 +00003420 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003421 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
3422 new_image=SpliceImage(*image,&geometry,exception);
3423 break;
3424 }
cristy947cb4c2011-10-20 18:41:46 +00003425 if (LocaleCompare("spread",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003426 {
cristy6fccee12011-10-20 18:43:18 +00003427 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003428 (void) ParseGeometry(argv[1],&geometry_info);
3429 new_image=SpreadImage(*image,geometry_info.rho,
3430 interpolate_method,exception);
3431 break;
3432 }
cristy947cb4c2011-10-20 18:41:46 +00003433 if (LocaleCompare("statistic",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003434 {
3435 StatisticType
3436 type;
3437
cristy6fccee12011-10-20 18:43:18 +00003438 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003439 type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
3440 MagickFalse,argv[1]);
3441 (void) ParseGeometry(argv[2],&geometry_info);
3442 new_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
3443 (size_t) geometry_info.sigma,exception);
3444 break;
3445 }
cristy947cb4c2011-10-20 18:41:46 +00003446 if (LocaleCompare("strip",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003447 {
cristy6fccee12011-10-20 18:43:18 +00003448 (void) SyncImageSettings(image_info,*image,exception);
anthony6613bf32011-10-15 07:24:44 +00003449 (void) StripImage(*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003450 break;
3451 }
cristy947cb4c2011-10-20 18:41:46 +00003452 if (LocaleCompare("swirl",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003453 {
cristy6fccee12011-10-20 18:43:18 +00003454 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003455 (void) ParseGeometry(argv[1],&geometry_info);
3456 new_image=SwirlImage(*image,geometry_info.rho,
3457 interpolate_method,exception);
3458 break;
3459 }
3460 break;
3461 }
3462 case 't':
3463 {
cristy947cb4c2011-10-20 18:41:46 +00003464 if (LocaleCompare("threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003465 {
3466 double
3467 threshold;
3468
cristy6fccee12011-10-20 18:43:18 +00003469 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003470 if (*argv[0] == '+')
3471 threshold=(double) QuantumRange/2;
3472 else
3473 threshold=SiPrefixToDouble(argv[1],QuantumRange);
anthony6613bf32011-10-15 07:24:44 +00003474 (void) BilevelImage(*image,threshold,exception);
anthony805a2d42011-09-25 08:25:12 +00003475 break;
3476 }
cristy947cb4c2011-10-20 18:41:46 +00003477 if (LocaleCompare("thumbnail",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003478 {
3479 /*
3480 Thumbnail image.
3481 */
cristy6fccee12011-10-20 18:43:18 +00003482 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003483 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3484 new_image=ThumbnailImage(*image,geometry.width,geometry.height,
3485 exception);
3486 break;
3487 }
cristy947cb4c2011-10-20 18:41:46 +00003488 if (LocaleCompare("tint",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003489 {
cristy6fccee12011-10-20 18:43:18 +00003490 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003491 new_image=TintImage(*image,argv[1],&fill,exception);
3492 break;
3493 }
cristy947cb4c2011-10-20 18:41:46 +00003494 if (LocaleCompare("transform",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003495 {
cristy6fccee12011-10-20 18:43:18 +00003496 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003497 new_image=AffineTransformImage(*image,&draw_info->affine,
3498 exception);
3499 break;
3500 }
cristy947cb4c2011-10-20 18:41:46 +00003501 if (LocaleCompare("transparent",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003502 {
3503 PixelInfo
3504 target;
3505
cristy6fccee12011-10-20 18:43:18 +00003506 (void) SyncImageSettings(image_info,*image,exception);
cristy269c9412011-10-13 23:41:15 +00003507 (void) QueryColorCompliance(argv[1],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00003508 exception);
anthony805a2d42011-09-25 08:25:12 +00003509 (void) TransparentPaintImage(*image,&target,(Quantum)
3510 TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue,
cristy82d7af52011-10-16 16:26:41 +00003511 exception);
anthony805a2d42011-09-25 08:25:12 +00003512 break;
3513 }
cristy947cb4c2011-10-20 18:41:46 +00003514 if (LocaleCompare("transpose",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003515 {
cristy6fccee12011-10-20 18:43:18 +00003516 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003517 new_image=TransposeImage(*image,exception);
3518 break;
3519 }
cristy947cb4c2011-10-20 18:41:46 +00003520 if (LocaleCompare("transverse",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003521 {
cristy6fccee12011-10-20 18:43:18 +00003522 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003523 new_image=TransverseImage(*image,exception);
3524 break;
3525 }
cristy947cb4c2011-10-20 18:41:46 +00003526 if (LocaleCompare("treedepth",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003527 {
3528 quantize_info->tree_depth=StringToUnsignedLong(argv[1]);
3529 break;
3530 }
cristy947cb4c2011-10-20 18:41:46 +00003531 if (LocaleCompare("trim",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003532 {
cristy6fccee12011-10-20 18:43:18 +00003533 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003534 new_image=TrimImage(*image,exception);
3535 break;
3536 }
cristy947cb4c2011-10-20 18:41:46 +00003537 if (LocaleCompare("type",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003538 {
anthonyab3a50c2011-10-27 11:48:57 +00003539 /* Note that "type" setting should have already been defined */
cristy6fccee12011-10-20 18:43:18 +00003540 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003541 (void) SetImageType(*image,type,exception);
3542 break;
3543 }
3544 break;
3545 }
3546 case 'u':
3547 {
cristy947cb4c2011-10-20 18:41:46 +00003548 if (LocaleCompare("unique",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003549 {
3550 if (*argv[0] == '+')
3551 {
3552 (void) DeleteImageArtifact(*image,"identify:unique-colors");
3553 break;
3554 }
3555 (void) SetImageArtifact(*image,"identify:unique-colors","true");
3556 (void) SetImageArtifact(*image,"verbose","true");
3557 break;
3558 }
cristy947cb4c2011-10-20 18:41:46 +00003559 if (LocaleCompare("unique-colors",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003560 {
cristy6fccee12011-10-20 18:43:18 +00003561 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003562 new_image=UniqueImageColors(*image,exception);
3563 break;
3564 }
cristy947cb4c2011-10-20 18:41:46 +00003565 if (LocaleCompare("unsharp",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003566 {
cristy6fccee12011-10-20 18:43:18 +00003567 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003568 flags=ParseGeometry(argv[1],&geometry_info);
3569 if ((flags & SigmaValue) == 0)
3570 geometry_info.sigma=1.0;
3571 if ((flags & XiValue) == 0)
3572 geometry_info.xi=1.0;
3573 if ((flags & PsiValue) == 0)
3574 geometry_info.psi=0.05;
3575 new_image=UnsharpMaskImage(*image,geometry_info.rho,
3576 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3577 break;
3578 }
3579 break;
3580 }
3581 case 'v':
3582 {
cristy947cb4c2011-10-20 18:41:46 +00003583 if (LocaleCompare("verbose",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003584 {
cristy947cb4c2011-10-20 18:41:46 +00003585 (void) SetImageArtifact(*image,argv[0]+1,
anthonyab3a50c2011-10-27 11:48:57 +00003586 *argv[0] == '+' ? "false" : "true");
anthony805a2d42011-09-25 08:25:12 +00003587 break;
3588 }
cristy947cb4c2011-10-20 18:41:46 +00003589 if (LocaleCompare("vignette",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003590 {
3591 /*
3592 Vignette image.
3593 */
cristy6fccee12011-10-20 18:43:18 +00003594 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003595 flags=ParseGeometry(argv[1],&geometry_info);
3596 if ((flags & SigmaValue) == 0)
3597 geometry_info.sigma=1.0;
3598 if ((flags & XiValue) == 0)
3599 geometry_info.xi=0.1*(*image)->columns;
3600 if ((flags & PsiValue) == 0)
3601 geometry_info.psi=0.1*(*image)->rows;
3602 new_image=VignetteImage(*image,geometry_info.rho,
3603 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3604 ceil(geometry_info.psi-0.5),exception);
3605 break;
3606 }
cristy947cb4c2011-10-20 18:41:46 +00003607 if (LocaleCompare("virtual-pixel",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003608 {
anthonyab3a50c2011-10-27 11:48:57 +00003609 /* setting already defined in image_info structure */
3610 SetImageVirtualPixelMethod(*image, image_info->virtual_pixel_method);
anthony805a2d42011-09-25 08:25:12 +00003611 break;
3612 }
3613 break;
3614 }
3615 case 'w':
3616 {
cristy947cb4c2011-10-20 18:41:46 +00003617 if (LocaleCompare("wave",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003618 {
cristy6fccee12011-10-20 18:43:18 +00003619 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003620 flags=ParseGeometry(argv[1],&geometry_info);
3621 if ((flags & SigmaValue) == 0)
3622 geometry_info.sigma=1.0;
3623 new_image=WaveImage(*image,geometry_info.rho,
anthonya89dd172011-10-04 13:29:35 +00003624 geometry_info.sigma,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003625 break;
3626 }
cristy947cb4c2011-10-20 18:41:46 +00003627 if (LocaleCompare("white-threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003628 {
cristy6fccee12011-10-20 18:43:18 +00003629 (void) SyncImageSettings(image_info,*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003630 (void) WhiteThresholdImage(*image,argv[1],exception);
anthony805a2d42011-09-25 08:25:12 +00003631 break;
3632 }
3633 break;
3634 }
3635 default:
3636 break;
3637 }
3638 /*
3639 Replace current image with any image that was generated
3640 */
3641 if (new_image != (Image *) NULL)
3642 ReplaceImageInListReturnLast(image,new_image);
3643
3644 /*
3645 Free resources.
3646 */
3647 quantize_info=DestroyQuantizeInfo(quantize_info);
3648 draw_info=DestroyDrawInfo(draw_info);
cristy82d7af52011-10-16 16:26:41 +00003649 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthonya89dd172011-10-04 13:29:35 +00003650 return(status == 0 ? MagickFalse : MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003651}
3652
3653/*
3654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3655% %
3656% %
3657% %
3658+ S e q u e n c e O p e r a t i o n I m a g e s %
3659% %
3660% %
3661% %
3662%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3663%
3664% SequenceOperationImages() applies a single operation that apply to the
3665% entire image list (e.g. -append, -layers, -coalesce, etc.).
3666%
3667% The format of the MogrifyImage method is:
3668%
3669% MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3670% const int argc, const char **argv,Image **images,
3671% ExceptionInfo *exception)
3672%
3673% A description of each parameter follows:
3674%
3675% o image_info: the image info..
3676%
3677% o argc: Specifies a pointer to an integer describing the number of
3678% elements in the argument vector.
3679%
3680% o argv: Specifies a pointer to a text array containing the command line
3681% arguments.
3682%
3683% o images: pointer to pointer of the first image in image list.
3684%
3685% o exception: return any errors or warnings in this structure.
3686%
3687*/
3688WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3689 const int argc,const char **argv,Image **images,ExceptionInfo *exception)
3690{
3691
3692 MagickStatusType
3693 status;
3694
3695 QuantizeInfo
3696 *quantize_info;
3697
3698 assert(image_info != (ImageInfo *) NULL);
3699 assert(image_info->signature == MagickSignature);
3700 assert(images != (Image **) NULL);
3701 assert((*images)->previous == (Image *) NULL);
3702 assert((*images)->signature == MagickSignature);
3703 if ((*images)->debug != MagickFalse)
3704 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3705 (*images)->filename);
anthonya89dd172011-10-04 13:29:35 +00003706 if ((argc <= 0) || (*argv == (char *) NULL))
3707 return(MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003708 status=MagickTrue;
3709
3710 switch (*(argv[0]+1))
3711 {
3712 case 'a':
3713 {
3714 if (LocaleCompare("affinity",argv[0]+1) == 0)
3715 {
cristy6fccee12011-10-20 18:43:18 +00003716 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003717 if (*argv[0] == '+')
3718 {
3719 (void) RemapImages(quantize_info,*images,(Image *) NULL,
3720 exception);
3721 break;
3722 }
3723 break;
3724 }
3725 if (LocaleCompare("append",argv[0]+1) == 0)
3726 {
3727 Image
3728 *append_image;
3729
cristy6fccee12011-10-20 18:43:18 +00003730 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003731 append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue :
3732 MagickFalse,exception);
3733 if (append_image == (Image *) NULL)
3734 {
3735 status=MagickFalse;
3736 break;
3737 }
3738 *images=DestroyImageList(*images);
3739 *images=append_image;
3740 break;
3741 }
3742 if (LocaleCompare("average",argv[0]+1) == 0)
3743 {
3744 Image
3745 *average_image;
3746
3747 /*
3748 Average an image sequence (deprecated).
3749 */
cristy6fccee12011-10-20 18:43:18 +00003750 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003751 average_image=EvaluateImages(*images,MeanEvaluateOperator,
3752 exception);
3753 if (average_image == (Image *) NULL)
3754 {
3755 status=MagickFalse;
3756 break;
3757 }
3758 *images=DestroyImageList(*images);
3759 *images=average_image;
3760 break;
3761 }
3762 break;
3763 }
3764 case 'c':
3765 {
3766 if (LocaleCompare("channel",argv[0]+1) == 0)
3767 {
3768 ChannelType
3769 channel;
3770
3771 if (*argv[0] == '+')
3772 {
3773 channel=DefaultChannels;
3774 break;
3775 }
3776 channel=(ChannelType) ParseChannelOption(argv[1]);
3777 SetPixelChannelMap(*images,channel);
3778 break;
3779 }
3780 if (LocaleCompare("clut",argv[0]+1) == 0)
3781 {
3782 Image
3783 *clut_image,
3784 *image;
3785
cristy6fccee12011-10-20 18:43:18 +00003786 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003787 image=RemoveFirstImageFromList(images);
3788 clut_image=RemoveFirstImageFromList(images);
3789 if (clut_image == (Image *) NULL)
3790 {
3791 status=MagickFalse;
3792 break;
3793 }
anthonya89dd172011-10-04 13:29:35 +00003794 (void) ClutImage(image,clut_image,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003795 clut_image=DestroyImage(clut_image);
3796 *images=DestroyImageList(*images);
3797 *images=image;
3798 break;
3799 }
3800 if (LocaleCompare("coalesce",argv[0]+1) == 0)
3801 {
3802 Image
3803 *coalesce_image;
3804
cristy6fccee12011-10-20 18:43:18 +00003805 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003806 coalesce_image=CoalesceImages(*images,exception);
3807 if (coalesce_image == (Image *) NULL)
3808 {
3809 status=MagickFalse;
3810 break;
3811 }
3812 *images=DestroyImageList(*images);
3813 *images=coalesce_image;
3814 break;
3815 }
3816 if (LocaleCompare("combine",argv[0]+1) == 0)
3817 {
3818 Image
3819 *combine_image;
3820
cristy6fccee12011-10-20 18:43:18 +00003821 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003822 combine_image=CombineImages(*images,exception);
3823 if (combine_image == (Image *) NULL)
3824 {
3825 status=MagickFalse;
3826 break;
3827 }
3828 *images=DestroyImageList(*images);
3829 *images=combine_image;
3830 break;
3831 }
3832 if (LocaleCompare("composite",argv[0]+1) == 0)
3833 {
3834 Image
3835 *mask_image,
3836 *composite_image,
3837 *image;
3838
3839 RectangleInfo
3840 geometry;
3841
anthony5f867ae2011-10-09 10:28:34 +00003842 ComposeOperator
3843 compose;
3844
3845 const char*
3846 value;
3847
3848 value=GetImageOption(image_info,"compose");
3849 if (value != (const char *) NULL)
3850 compose=(CompositeOperator) ParseCommandOption(
3851 MagickComposeOptions,MagickFalse,value);
3852 else
3853 compose=OverCompositeOp; /* use Over not image->compose */
3854
3855 const char*
3856 value=GetImageOption(image_info,"compose");
3857
3858 if (value != (const char *) NULL)
3859 compose=(CompositeOperator) ParseCommandOption(
3860 MagickComposeOptions,MagickFalse,value);
3861 else
3862 compose=OverCompositeOp; /* use Over not image->compose */
3863
3864
cristy6fccee12011-10-20 18:43:18 +00003865 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003866 image=RemoveFirstImageFromList(images);
3867 composite_image=RemoveFirstImageFromList(images);
3868 if (composite_image == (Image *) NULL)
3869 {
3870 status=MagickFalse;
3871 break;
3872 }
3873 (void) TransformImage(&composite_image,(char *) NULL,
anthony6613bf32011-10-15 07:24:44 +00003874 composite_image->geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00003875 SetGeometry(composite_image,&geometry);
3876 (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
3877 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
3878 &geometry);
3879 mask_image=RemoveFirstImageFromList(images);
3880 if (mask_image != (Image *) NULL)
3881 {
anthony5f867ae2011-10-09 10:28:34 +00003882 if ((compose == DisplaceCompositeOp) ||
3883 (compose == DistortCompositeOp))
anthony805a2d42011-09-25 08:25:12 +00003884 {
3885 /*
3886 Merge Y displacement into X displacement image.
3887 */
3888 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
anthony6613bf32011-10-15 07:24:44 +00003889 mask_image,0,0,exception);
anthony805a2d42011-09-25 08:25:12 +00003890 mask_image=DestroyImage(mask_image);
3891 }
3892 else
3893 {
3894 /*
3895 Set a blending mask for the composition.
3896 Posible error, what if image->mask already set.
3897 */
3898 image->mask=mask_image;
3899 (void) NegateImage(image->mask,MagickFalse,exception);
3900 }
3901 }
anthony5f867ae2011-10-09 10:28:34 +00003902 (void) CompositeImage(image,compose,composite_image,
anthony6613bf32011-10-15 07:24:44 +00003903 geometry.x,geometry.y,exception);
anthony805a2d42011-09-25 08:25:12 +00003904 if (mask_image != (Image *) NULL)
3905 mask_image=image->mask=DestroyImage(image->mask);
3906 composite_image=DestroyImage(composite_image);
anthony805a2d42011-09-25 08:25:12 +00003907 *images=DestroyImageList(*images);
3908 *images=image;
3909 break;
3910 }
3911 break;
3912 }
3913 case 'd':
3914 {
3915 if (LocaleCompare("deconstruct",argv[0]+1) == 0)
3916 {
3917 Image
3918 *deconstruct_image;
3919
cristy6fccee12011-10-20 18:43:18 +00003920 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003921 deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
3922 exception);
3923 if (deconstruct_image == (Image *) NULL)
3924 {
3925 status=MagickFalse;
3926 break;
3927 }
3928 *images=DestroyImageList(*images);
3929 *images=deconstruct_image;
3930 break;
3931 }
3932 if (LocaleCompare("delete",argv[0]+1) == 0)
3933 {
3934 if (*argv[0] == '+')
3935 DeleteImages(images,"-1",exception);
3936 else
3937 DeleteImages(images,argv[1],exception);
3938 break;
3939 }
3940 if (LocaleCompare("dither",argv[0]+1) == 0)
3941 {
3942 if (*argv[0] == '+')
3943 {
3944 quantize_info->dither=MagickFalse;
3945 break;
3946 }
3947 quantize_info->dither=MagickTrue;
3948 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
3949 MagickDitherOptions,MagickFalse,argv[1]);
3950 break;
3951 }
3952 if (LocaleCompare("duplicate",argv[0]+1) == 0)
3953 {
3954 Image
3955 *duplicate_images;
3956
3957 if (*argv[0] == '+')
3958 duplicate_images=DuplicateImages(*images,1,"-1",exception);
3959 else
3960 {
3961 const char
3962 *p;
3963
3964 size_t
3965 number_duplicates;
3966
3967 number_duplicates=(size_t) StringToLong(argv[1]);
3968 p=strchr(argv[1],',');
3969 if (p == (const char *) NULL)
3970 duplicate_images=DuplicateImages(*images,number_duplicates,
3971 "-1",exception);
3972 else
3973 duplicate_images=DuplicateImages(*images,number_duplicates,p,
3974 exception);
3975 }
3976 AppendImageToList(images, duplicate_images);
cristy6fccee12011-10-20 18:43:18 +00003977 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00003978 break;
3979 }
3980 break;
3981 }
3982 case 'e':
3983 {
3984 if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0)
3985 {
3986 Image
3987 *evaluate_image;
3988
3989 MagickEvaluateOperator
3990 op;
3991
3992 (void) SyncImageSettings(image_info,*images);
3993 op=(MagickEvaluateOperator) ParseCommandOption(
3994 MagickEvaluateOptions,MagickFalse,argv[1]);
3995 evaluate_image=EvaluateImages(*images,op,exception);
3996 if (evaluate_image == (Image *) NULL)
3997 {
3998 status=MagickFalse;
3999 break;
4000 }
4001 *images=DestroyImageList(*images);
4002 *images=evaluate_image;
4003 break;
4004 }
4005 break;
4006 }
4007 case 'f':
4008 {
4009 if (LocaleCompare("fft",argv[0]+1) == 0)
4010 {
4011 Image
4012 *fourier_image;
4013
4014 /*
4015 Implements the discrete Fourier transform (DFT).
4016 */
4017 (void) SyncImageSettings(image_info,*images);
4018 fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ?
4019 MagickTrue : MagickFalse,exception);
4020 if (fourier_image == (Image *) NULL)
4021 break;
4022 *images=DestroyImage(*images);
4023 *images=fourier_image;
4024 break;
4025 }
4026 if (LocaleCompare("flatten",argv[0]+1) == 0)
4027 {
4028 Image
4029 *flatten_image;
4030
cristy6fccee12011-10-20 18:43:18 +00004031 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004032 flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
4033 if (flatten_image == (Image *) NULL)
4034 break;
4035 *images=DestroyImageList(*images);
4036 *images=flatten_image;
4037 break;
4038 }
4039 if (LocaleCompare("fx",argv[0]+1) == 0)
4040 {
4041 Image
4042 *fx_image;
4043
cristy6fccee12011-10-20 18:43:18 +00004044 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004045 fx_image=FxImage(*images,argv[1],exception);
4046 if (fx_image == (Image *) NULL)
4047 {
4048 status=MagickFalse;
4049 break;
4050 }
4051 *images=DestroyImageList(*images);
4052 *images=fx_image;
4053 break;
4054 }
4055 break;
4056 }
4057 case 'h':
4058 {
4059 if (LocaleCompare("hald-clut",argv[0]+1) == 0)
4060 {
4061 Image
4062 *hald_image,
4063 *image;
4064
cristy6fccee12011-10-20 18:43:18 +00004065 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004066 image=RemoveFirstImageFromList(images);
4067 hald_image=RemoveFirstImageFromList(images);
4068 if (hald_image == (Image *) NULL)
4069 {
4070 status=MagickFalse;
4071 break;
4072 }
4073 (void) HaldClutImage(image,hald_image,exception);
4074 hald_image=DestroyImage(hald_image);
4075 if (*images != (Image *) NULL)
4076 *images=DestroyImageList(*images);
4077 *images=image;
4078 break;
4079 }
4080 break;
4081 }
4082 case 'i':
4083 {
4084 if (LocaleCompare("ift",argv[0]+1) == 0)
4085 {
4086 Image
4087 *fourier_image,
4088 *magnitude_image,
4089 *phase_image;
4090
4091 /*
4092 Implements the inverse fourier discrete Fourier transform (DFT).
4093 */
cristy6fccee12011-10-20 18:43:18 +00004094 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004095 magnitude_image=RemoveFirstImageFromList(images);
4096 phase_image=RemoveFirstImageFromList(images);
4097 if (phase_image == (Image *) NULL)
4098 {
4099 status=MagickFalse;
4100 break;
4101 }
4102 fourier_image=InverseFourierTransformImage(magnitude_image,
4103 phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception);
4104 if (fourier_image == (Image *) NULL)
4105 break;
4106 if (*images != (Image *) NULL)
4107 *images=DestroyImage(*images);
4108 *images=fourier_image;
4109 break;
4110 }
4111 if (LocaleCompare("insert",argv[0]+1) == 0)
4112 {
4113 Image
4114 *p,
4115 *q;
4116
4117 index=0;
4118 if (*argv[0] != '+')
4119 index=(ssize_t) StringToLong(argv[1]);
4120 p=RemoveLastImageFromList(images);
4121 if (p == (Image *) NULL)
4122 {
4123 (void) ThrowMagickException(exception,GetMagickModule(),
4124 OptionError,"NoSuchImage","`%s'",argv[1]);
4125 status=MagickFalse;
4126 break;
4127 }
4128 q=p;
4129 if (index == 0)
4130 PrependImageToList(images,q);
4131 else
4132 if (index == (ssize_t) GetImageListLength(*images))
4133 AppendImageToList(images,q);
4134 else
4135 {
4136 q=GetImageFromList(*images,index-1);
4137 if (q == (Image *) NULL)
4138 {
4139 (void) ThrowMagickException(exception,GetMagickModule(),
4140 OptionError,"NoSuchImage","`%s'",argv[1]);
4141 status=MagickFalse;
4142 break;
4143 }
4144 InsertImageInList(&q,p);
4145 }
4146 *images=GetFirstImageInList(q);
4147 break;
4148 }
4149 if (LocaleCompare("interpolate",argv[0]+1) == 0)
4150 {
4151 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
4152 MagickInterpolateOptions,MagickFalse,argv[1]);
4153 break;
4154 }
4155 break;
4156 }
4157 case 'l':
4158 {
4159 if (LocaleCompare("layers",argv[0]+1) == 0)
4160 {
4161 Image
4162 *layers;
4163
4164 ImageLayerMethod
4165 method;
4166
cristy6fccee12011-10-20 18:43:18 +00004167 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004168 layers=(Image *) NULL;
4169 method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
4170 MagickFalse,argv[1]);
4171 switch (method)
4172 {
4173 case CoalesceLayer:
4174 {
4175 layers=CoalesceImages(*images,exception);
4176 break;
4177 }
4178 case CompareAnyLayer:
4179 case CompareClearLayer:
4180 case CompareOverlayLayer:
4181 default:
4182 {
4183 layers=CompareImagesLayers(*images,method,exception);
4184 break;
4185 }
4186 case MergeLayer:
4187 case FlattenLayer:
4188 case MosaicLayer:
4189 case TrimBoundsLayer:
4190 {
4191 layers=MergeImageLayers(*images,method,exception);
4192 break;
4193 }
4194 case DisposeLayer:
4195 {
4196 layers=DisposeImages(*images,exception);
4197 break;
4198 }
4199 case OptimizeImageLayer:
4200 {
4201 layers=OptimizeImageLayers(*images,exception);
4202 break;
4203 }
4204 case OptimizePlusLayer:
4205 {
4206 layers=OptimizePlusImageLayers(*images,exception);
4207 break;
4208 }
4209 case OptimizeTransLayer:
4210 {
4211 OptimizeImageTransparency(*images,exception);
4212 break;
4213 }
4214 case RemoveDupsLayer:
4215 {
4216 RemoveDuplicateLayers(images,exception);
4217 break;
4218 }
4219 case RemoveZeroLayer:
4220 {
4221 RemoveZeroDelayLayers(images,exception);
4222 break;
4223 }
4224 case OptimizeLayer:
4225 {
4226 /*
4227 General Purpose, GIF Animation Optimizer.
4228 */
4229 layers=CoalesceImages(*images,exception);
4230 if (layers == (Image *) NULL)
4231 {
4232 status=MagickFalse;
4233 break;
4234 }
4235 *images=DestroyImageList(*images);
4236 *images=layers;
4237 layers=OptimizeImageLayers(*images,exception);
4238 if (layers == (Image *) NULL)
4239 {
4240 status=MagickFalse;
4241 break;
4242 }
4243 *images=DestroyImageList(*images);
4244 *images=layers;
4245 layers=(Image *) NULL;
4246 OptimizeImageTransparency(*images,exception);
4247 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4248 exception);
4249 break;
4250 }
4251 case CompositeLayer:
4252 {
anthony805a2d42011-09-25 08:25:12 +00004253 Image
4254 *source;
4255
4256 RectangleInfo
4257 geometry;
4258
anthony5f867ae2011-10-09 10:28:34 +00004259 ComposeOperator
4260 compose;
4261
4262 const char*
4263 value;
4264
4265 value=GetImageOption(image_info,"compose");
4266 if (value != (const char *) NULL)
4267 compose=(CompositeOperator) ParseCommandOption(
4268 MagickComposeOptions,MagickFalse,value);
4269 else
4270 compose=OverCompositeOp; /* use Over not image->compose */
4271
anthony805a2d42011-09-25 08:25:12 +00004272 /*
4273 Split image sequence at the first 'NULL:' image.
4274 */
4275 source=(*images);
4276 while (source != (Image *) NULL)
4277 {
4278 source=GetNextImageInList(source);
4279 if ((source != (Image *) NULL) &&
4280 (LocaleCompare(source->magick,"NULL") == 0))
4281 break;
4282 }
4283 if (source != (Image *) NULL)
4284 {
4285 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4286 (GetNextImageInList(source) == (Image *) NULL))
4287 source=(Image *) NULL;
4288 else
4289 {
4290 /*
4291 Separate the two lists, junk the null: image.
4292 */
4293 source=SplitImageList(source->previous);
4294 DeleteImageFromList(&source);
4295 }
4296 }
4297 if (source == (Image *) NULL)
4298 {
4299 (void) ThrowMagickException(exception,GetMagickModule(),
4300 OptionError,"MissingNullSeparator","layers Composite");
4301 status=MagickFalse;
4302 break;
4303 }
4304 /*
4305 Adjust offset with gravity and virtual canvas.
4306 */
4307 SetGeometry(*images,&geometry);
4308 (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
4309 geometry.width=source->page.width != 0 ?
4310 source->page.width : source->columns;
4311 geometry.height=source->page.height != 0 ?
4312 source->page.height : source->rows;
4313 GravityAdjustGeometry((*images)->page.width != 0 ?
4314 (*images)->page.width : (*images)->columns,
4315 (*images)->page.height != 0 ? (*images)->page.height :
4316 (*images)->rows,(*images)->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004317
4318 /*
4319 Compose the two image sequences together
4320 */
anthony805a2d42011-09-25 08:25:12 +00004321 CompositeLayers(*images,compose,source,geometry.x,geometry.y,
4322 exception);
4323 source=DestroyImageList(source);
4324 break;
4325 }
4326 }
4327 if (layers == (Image *) NULL)
4328 break;
anthony805a2d42011-09-25 08:25:12 +00004329 *images=DestroyImageList(*images);
4330 *images=layers;
4331 break;
4332 }
4333 break;
4334 }
4335 case 'm':
4336 {
4337 if (LocaleCompare("map",argv[0]+1) == 0)
4338 {
cristy6fccee12011-10-20 18:43:18 +00004339 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004340 if (*argv[0] == '+')
4341 {
4342 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4343 exception);
4344 break;
4345 }
4346 break;
4347 }
4348 if (LocaleCompare("maximum",argv[0]+1) == 0)
4349 {
4350 Image
4351 *maximum_image;
4352
4353 /*
4354 Maximum image sequence (deprecated).
4355 */
cristy6fccee12011-10-20 18:43:18 +00004356 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004357 maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
4358 if (maximum_image == (Image *) NULL)
4359 {
4360 status=MagickFalse;
4361 break;
4362 }
4363 *images=DestroyImageList(*images);
4364 *images=maximum_image;
4365 break;
4366 }
4367 if (LocaleCompare("minimum",argv[0]+1) == 0)
4368 {
4369 Image
4370 *minimum_image;
4371
4372 /*
4373 Minimum image sequence (deprecated).
4374 */
cristy6fccee12011-10-20 18:43:18 +00004375 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004376 minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
4377 if (minimum_image == (Image *) NULL)
4378 {
4379 status=MagickFalse;
4380 break;
4381 }
4382 *images=DestroyImageList(*images);
4383 *images=minimum_image;
4384 break;
4385 }
4386 if (LocaleCompare("morph",argv[0]+1) == 0)
4387 {
4388 Image
4389 *morph_image;
4390
cristy6fccee12011-10-20 18:43:18 +00004391 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004392 morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]),
4393 exception);
4394 if (morph_image == (Image *) NULL)
4395 {
4396 status=MagickFalse;
4397 break;
4398 }
4399 *images=DestroyImageList(*images);
4400 *images=morph_image;
4401 break;
4402 }
4403 if (LocaleCompare("mosaic",argv[0]+1) == 0)
4404 {
4405 Image
4406 *mosaic_image;
4407
cristy6fccee12011-10-20 18:43:18 +00004408 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004409 mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
4410 if (mosaic_image == (Image *) NULL)
4411 {
4412 status=MagickFalse;
4413 break;
4414 }
4415 *images=DestroyImageList(*images);
4416 *images=mosaic_image;
4417 break;
4418 }
4419 break;
4420 }
4421 case 'p':
4422 {
4423 if (LocaleCompare("print",argv[0]+1) == 0)
4424 {
4425 char
4426 *string;
4427
cristy6fccee12011-10-20 18:43:18 +00004428 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004429 string=InterpretImageProperties(image_info,*images,argv[1],
4430 exception);
4431 if (string == (char *) NULL)
4432 break;
4433 (void) FormatLocaleFile(stdout,"%s",string);
4434 string=DestroyString(string);
4435 }
4436 if (LocaleCompare("process",argv[0]+1) == 0)
4437 {
4438 char
4439 **arguments;
4440
4441 int
4442 j,
4443 number_arguments;
4444
cristy6fccee12011-10-20 18:43:18 +00004445 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004446 arguments=StringToArgv(argv[1],&number_arguments);
4447 if (arguments == (char **) NULL)
4448 break;
4449 if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
4450 {
4451 char
4452 breaker,
4453 quote,
4454 *token;
4455
4456 const char
4457 *arguments;
4458
4459 int
4460 next,
4461 status;
4462
4463 size_t
4464 length;
4465
4466 TokenInfo
4467 *token_info;
4468
4469 /*
4470 Support old style syntax, filter="-option arg".
4471 */
4472 length=strlen(argv[1]);
4473 token=(char *) NULL;
4474 if (~length >= (MaxTextExtent-1))
4475 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4476 sizeof(*token));
4477 if (token == (char *) NULL)
4478 break;
4479 next=0;
4480 arguments=argv[1];
4481 token_info=AcquireTokenInfo();
4482 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4483 "\"",'\0',&breaker,&next,&quote);
4484 token_info=DestroyTokenInfo(token_info);
4485 if (status == 0)
4486 {
4487 const char
4488 *argv;
4489
4490 argv=(&(arguments[next]));
4491 (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
4492 exception);
4493 }
4494 token=DestroyString(token);
4495 break;
4496 }
4497 (void) SubstituteString(&arguments[1],"-","");
4498 (void) InvokeDynamicImageFilter(arguments[1],&(*images),
4499 number_arguments-2,(const char **) arguments+2,exception);
4500 for (j=0; j < number_arguments; j++)
4501 arguments[j]=DestroyString(arguments[j]);
4502 arguments=(char **) RelinquishMagickMemory(arguments);
4503 break;
4504 }
4505 break;
4506 }
4507 case 'r':
4508 {
4509 if (LocaleCompare("reverse",argv[0]+1) == 0)
4510 {
4511 ReverseImageList(images);
anthony805a2d42011-09-25 08:25:12 +00004512 break;
4513 }
4514 break;
4515 }
4516 case 's':
4517 {
4518 if (LocaleCompare("smush",argv[0]+1) == 0)
4519 {
4520 Image
4521 *smush_image;
4522
4523 ssize_t
4524 offset;
4525
cristy6fccee12011-10-20 18:43:18 +00004526 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004527 offset=(ssize_t) StringToLong(argv[1]);
4528 smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue :
4529 MagickFalse,offset,exception);
4530 if (smush_image == (Image *) NULL)
4531 {
4532 status=MagickFalse;
4533 break;
4534 }
4535 *images=DestroyImageList(*images);
4536 *images=smush_image;
4537 break;
4538 }
4539 if (LocaleCompare("swap",argv[0]+1) == 0)
4540 {
4541 Image
4542 *p,
4543 *q,
4544 *swap;
4545
4546 ssize_t
4547 swap_index;
4548
4549 index=(-1);
4550 swap_index=(-2);
4551 if (*argv[0] != '+')
4552 {
4553 GeometryInfo
4554 geometry_info;
4555
4556 MagickStatusType
4557 flags;
4558
4559 swap_index=(-1);
4560 flags=ParseGeometry(argv[1],&geometry_info);
4561 index=(ssize_t) geometry_info.rho;
4562 if ((flags & SigmaValue) != 0)
4563 swap_index=(ssize_t) geometry_info.sigma;
4564 }
4565 p=GetImageFromList(*images,index);
4566 q=GetImageFromList(*images,swap_index);
4567 if ((p == (Image *) NULL) || (q == (Image *) NULL))
4568 {
4569 (void) ThrowMagickException(exception,GetMagickModule(),
4570 OptionError,"NoSuchImage","`%s'",(*images)->filename);
4571 status=MagickFalse;
4572 break;
4573 }
4574 if (p == q)
4575 break;
4576 swap=CloneImage(p,0,0,MagickTrue,exception);
4577 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
4578 ReplaceImageInList(&q,swap);
4579 *images=GetFirstImageInList(q);
4580 break;
4581 }
4582 break;
4583 }
4584 case 'w':
4585 {
4586 if (LocaleCompare("write",argv[0]+1) == 0)
4587 {
4588 char
4589 key[MaxTextExtent];
4590
4591 Image
4592 *write_images;
4593
4594 ImageInfo
4595 *write_info;
4596
cristy6fccee12011-10-20 18:43:18 +00004597 (void) SyncImagesSettings(image_info,*images,exception);
anthony805a2d42011-09-25 08:25:12 +00004598 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]);
4599 (void) DeleteImageRegistry(key);
4600 write_images=(*images);
4601 if (*argv[0] == '+')
4602 write_images=CloneImageList(*images,exception);
4603 write_info=CloneImageInfo(image_info);
4604 status&=WriteImages(write_info,write_images,argv[1],exception);
4605 write_info=DestroyImageInfo(write_info);
4606 if (*argv[0] == '+')
4607 write_images=DestroyImageList(write_images);
4608 break;
4609 }
4610 break;
4611 }
4612 default:
4613 break;
4614 }
4615 quantize_info=DestroyQuantizeInfo(quantize_info);
4616
cristy82d7af52011-10-16 16:26:41 +00004617 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthony805a2d42011-09-25 08:25:12 +00004618 return(status != 0 ? MagickTrue : MagickFalse);
4619}
cristy0a0ca4f2011-09-28 01:15:28 +00004620#endif