blob: 8048026ea5e0b09889f94c4fae857e5ab11d2747 [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 */
anthony1afdc7a2011-10-05 11:54:28 +0000294 (void) QueryMagickColorCompliance(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 DeleteOption (const char*)NULL
437#define IfSetOption ((*argv[0])=='-')
438
439 switch (*option)
anthony805a2d42011-09-25 08:25:12 +0000440 {
441 case 'a':
442 {
anthony74b1cfc2011-10-06 12:44:16 +0000443 if (LocaleCompare("adjoin",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000444 {
anthony74b1cfc2011-10-06 12:44:16 +0000445 image_info->adjoin = IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000446 break;
447 }
anthony74b1cfc2011-10-06 12:44:16 +0000448 if (LocaleCompare("affine",option) == 0)
anthony1afdc7a2011-10-05 11:54:28 +0000449 {
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("attenuate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000466 {
anthony74b1cfc2011-10-06 12:44:16 +0000467 (void) SetImageOption(image_info,option,
468 IfSetOption ? argv[1] : DeleteOption);
anthony805a2d42011-09-25 08:25:12 +0000469 break;
470 }
anthony74b1cfc2011-10-06 12:44:16 +0000471 if (LocaleCompare("authenticate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000472 {
anthony74b1cfc2011-10-06 12:44:16 +0000473 (void) SetImageOption(image_info,option,
474 IfSetOption ? argv[1] : DeleteOption);
anthony805a2d42011-09-25 08:25:12 +0000475 break;
476 }
477 break;
478 }
479 case 'b':
480 {
anthony74b1cfc2011-10-06 12:44:16 +0000481 if (LocaleCompare("background",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000482 {
anthony74b1cfc2011-10-06 12:44:16 +0000483 /* FUTURE: both image_info attribute & ImageOption in use!
484 Note that +background, means fall-back to image attribute
485 so ImageOption is deleted, not set to a default.
486 */
487 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000488 {
anthony74b1cfc2011-10-06 12:44:16 +0000489 (void) DeleteImageOption(image_info,option);
anthony1afdc7a2011-10-05 11:54:28 +0000490 (void) QueryColorCompliance(BackgroundColor,AllCompliance,
anthony74b1cfc2011-10-06 12:44:16 +0000491 image_info->background_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000492 break;
493 }
anthony74b1cfc2011-10-06 12:44:16 +0000494 (void) SetImageOption(image_info,option,argv[1]);
anthony1afdc7a2011-10-05 11:54:28 +0000495 (void) QueryColorCompliance(argv[1],AllCompliance,
anthony74b1cfc2011-10-06 12:44:16 +0000496 image_info->background_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000497 break;
498 }
anthony74b1cfc2011-10-06 12:44:16 +0000499 if (LocaleCompare("bias",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000500 {
anthony74b1cfc2011-10-06 12:44:16 +0000501 /* FUTURE: bias OBSOLETED, replaced by "convolve:bias"
502 as it is actually rarely used except in direct convolve
503 Usage outside direct convolve is actally non-sensible!
504 */
505 (void) SetImageOption(image_info,option,
506 IfSetOption ? argv[1] : "0");
anthony805a2d42011-09-25 08:25:12 +0000507 break;
508 }
anthony74b1cfc2011-10-06 12:44:16 +0000509 if (LocaleCompare("black-point-compensation",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000510 {
anthony74b1cfc2011-10-06 12:44:16 +0000511 (void) SetImageOption(image_info,option,
512 IfSetOption ? "true" : "false" );
anthony805a2d42011-09-25 08:25:12 +0000513 break;
514 }
anthony74b1cfc2011-10-06 12:44:16 +0000515 if (LocaleCompare("blue-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000516 {
anthony74b1cfc2011-10-06 12:44:16 +0000517 (void) SetImageOption(image_info,option,
518 IfSetOption ? argv[1] : "0" );
anthony805a2d42011-09-25 08:25:12 +0000519 break;
520 }
anthony74b1cfc2011-10-06 12:44:16 +0000521 if (LocaleCompare("bordercolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000522 {
anthony74b1cfc2011-10-06 12:44:16 +0000523 /* FUTURE: both image_info attribute & ImageOption in use! */
524 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000525 {
anthony74b1cfc2011-10-06 12:44:16 +0000526 (void) SetImageOption(image_info,option,argv[1]);
527 (void) QueryColorCompliance(argv[1],AllCompliece,
528 &image_info->border_color,exception);
529 (void) QueryColorCompliance(argv[1],AllCompliance,
530 &draw_info->border_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000531 break;
532 }
anthony74b1cfc2011-10-06 12:44:16 +0000533 (void) DeleteImageOption(image_info,option);
534 (void) QueryColorCompliance(BorderColor,AllCompliance,
535 &image_info->border_color,exception);
536 (void) QueryColorCompliance(BorderColor,AllCompliance,
537 &draw_info->border_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000538 break;
539 }
anthony74b1cfc2011-10-06 12:44:16 +0000540 if (LocaleCompare("box",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000541 {
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,
568 IfSetOption ? argv[1] : DeleteOption);
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 {
anthony74b1cfc2011-10-06 12:44:16 +0000573 image_info->channel=(ChannelType) (
574 IfSetOption ? ParseChannelOption(argv[1]) : DefaultChannels );
575 /* this is also a SimpleImageOperator ??? why ??? */
anthony805a2d42011-09-25 08:25:12 +0000576 break;
577 }
anthony74b1cfc2011-10-06 12:44:16 +0000578 if (LocaleCompare("colors",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000579 {
anthony74b1cfc2011-10-06 12:44:16 +0000580 /* Why is this saved */
anthony805a2d42011-09-25 08:25:12 +0000581 image_info->colors=StringToUnsignedLong(argv[1]);
582 break;
583 }
anthony74b1cfc2011-10-06 12:44:16 +0000584 if (LocaleCompare("colorspace",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000585 {
586 if (*argv[0] == '+')
587 {
588 image_info->colorspace=UndefinedColorspace;
anthony74b1cfc2011-10-06 12:44:16 +0000589 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000590 break;
591 }
592 image_info->colorspace=(ColorspaceType) ParseCommandOption(
593 MagickColorspaceOptions,MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +0000594 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000595 break;
596 }
anthony74b1cfc2011-10-06 12:44:16 +0000597 if (LocaleCompare("comment",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000598 {
599 if (*argv[0] == '+')
600 {
anthony74b1cfc2011-10-06 12:44:16 +0000601 (void) DeleteImageOption(image_info,option);
anthony805a2d42011-09-25 08:25:12 +0000602 break;
603 }
anthony74b1cfc2011-10-06 12:44:16 +0000604 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000605 break;
606 }
anthony74b1cfc2011-10-06 12:44:16 +0000607 if (LocaleCompare("compose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000608 {
609 if (*argv[0] == '+')
610 {
anthony74b1cfc2011-10-06 12:44:16 +0000611 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000612 break;
613 }
anthony74b1cfc2011-10-06 12:44:16 +0000614 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000615 break;
616 }
anthony74b1cfc2011-10-06 12:44:16 +0000617 if (LocaleCompare("compress",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000618 {
619 if (*argv[0] == '+')
620 {
621 image_info->compression=UndefinedCompression;
anthony74b1cfc2011-10-06 12:44:16 +0000622 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000623 break;
624 }
625 image_info->compression=(CompressionType) ParseCommandOption(
626 MagickCompressOptions,MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +0000627 (void) SetImageOption(image_info,option,argv[1]);
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 {
636 if (*argv[0] == '+')
637 (void) SetLogEventMask("none");
638 else
639 (void) SetLogEventMask(argv[1]);
640 image_info->debug=IsEventLogging();
641 break;
642 }
anthony74b1cfc2011-10-06 12:44:16 +0000643 if (LocaleCompare("define",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000644 {
645 if (*argv[0] == '+')
646 {
647 if (LocaleNCompare(argv[1],"registry:",9) == 0)
648 (void) DeleteImageRegistry(argv[1]+9);
649 else
650 (void) DeleteImageOption(image_info,argv[1]);
651 break;
652 }
653 if (LocaleNCompare(argv[1],"registry:",9) == 0)
654 {
655 (void) DefineImageRegistry(StringRegistryType,argv[1]+9,
656 exception);
657 break;
658 }
659 (void) DefineImageOption(image_info,argv[1]);
660 break;
661 }
anthony74b1cfc2011-10-06 12:44:16 +0000662 if (LocaleCompare("delay",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000663 {
664 if (*argv[0] == '+')
665 {
anthony74b1cfc2011-10-06 12:44:16 +0000666 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +0000667 break;
668 }
anthony74b1cfc2011-10-06 12:44:16 +0000669 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000670 break;
671 }
anthony74b1cfc2011-10-06 12:44:16 +0000672 if (LocaleCompare("density",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000673 {
674 /*
675 Set image density.
676 */
677 if (*argv[0] == '+')
678 {
679 if (image_info->density != (char *) NULL)
680 image_info->density=DestroyString(image_info->density);
anthony74b1cfc2011-10-06 12:44:16 +0000681 (void) SetImageOption(image_info,option,"72");
anthony805a2d42011-09-25 08:25:12 +0000682 break;
683 }
684 (void) CloneString(&image_info->density,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +0000685 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000686 break;
687 }
anthony74b1cfc2011-10-06 12:44:16 +0000688 if (LocaleCompare("depth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000689 {
690 if (*argv[0] == '+')
691 {
692 image_info->depth=MAGICKCORE_QUANTUM_DEPTH;
693 break;
694 }
695 image_info->depth=StringToUnsignedLong(argv[1]);
696 break;
697 }
anthony74b1cfc2011-10-06 12:44:16 +0000698 if (LocaleCompare("direction",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000699 {
700 if (*argv[0] == '+')
701 {
anthony74b1cfc2011-10-06 12:44:16 +0000702 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000703 break;
704 }
anthony74b1cfc2011-10-06 12:44:16 +0000705 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000706 break;
707 }
anthony74b1cfc2011-10-06 12:44:16 +0000708 if (LocaleCompare("display",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000709 {
710 if (*argv[0] == '+')
711 {
712 if (image_info->server_name != (char *) NULL)
713 image_info->server_name=DestroyString(
714 image_info->server_name);
715 break;
716 }
717 (void) CloneString(&image_info->server_name,argv[1]);
718 break;
719 }
anthony74b1cfc2011-10-06 12:44:16 +0000720 if (LocaleCompare("dispose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000721 {
722 if (*argv[0] == '+')
723 {
anthony74b1cfc2011-10-06 12:44:16 +0000724 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000725 break;
726 }
anthony74b1cfc2011-10-06 12:44:16 +0000727 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000728 break;
729 }
anthony74b1cfc2011-10-06 12:44:16 +0000730 if (LocaleCompare("dither",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000731 {
732 if (*argv[0] == '+')
733 {
734 image_info->dither=MagickFalse;
anthony74b1cfc2011-10-06 12:44:16 +0000735 (void) SetImageOption(image_info,option,"none");
anthony805a2d42011-09-25 08:25:12 +0000736 break;
737 }
anthony74b1cfc2011-10-06 12:44:16 +0000738 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000739 image_info->dither=MagickTrue;
740 break;
741 }
742 break;
743 }
744 case 'e':
745 {
anthony74b1cfc2011-10-06 12:44:16 +0000746 if (LocaleCompare("encoding",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000747 {
748 if (*argv[0] == '+')
749 {
anthony74b1cfc2011-10-06 12:44:16 +0000750 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000751 break;
752 }
anthony74b1cfc2011-10-06 12:44:16 +0000753 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000754 break;
755 }
anthony74b1cfc2011-10-06 12:44:16 +0000756 if (LocaleCompare("endian",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000757 {
758 if (*argv[0] == '+')
759 {
760 image_info->endian=UndefinedEndian;
anthony74b1cfc2011-10-06 12:44:16 +0000761 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000762 break;
763 }
764 image_info->endian=(EndianType) ParseCommandOption(
765 MagickEndianOptions,MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +0000766 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000767 break;
768 }
anthony74b1cfc2011-10-06 12:44:16 +0000769 if (LocaleCompare("extract",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000770 {
771 /*
772 Set image extract geometry.
773 */
774 if (*argv[0] == '+')
775 {
776 if (image_info->extract != (char *) NULL)
777 image_info->extract=DestroyString(image_info->extract);
778 break;
779 }
780 (void) CloneString(&image_info->extract,argv[1]);
781 break;
782 }
783 break;
784 }
785 case 'f':
786 {
anthony74b1cfc2011-10-06 12:44:16 +0000787 if (LocaleCompare("fill",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000788 {
789 if (*argv[0] == '+')
790 {
anthony74b1cfc2011-10-06 12:44:16 +0000791 (void) SetImageOption(image_info,option,"none");
anthony805a2d42011-09-25 08:25:12 +0000792 break;
793 }
anthony74b1cfc2011-10-06 12:44:16 +0000794 (void) SetImageOption(image_info,option,argv[1]);
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 {
799 if (*argv[0] == '+')
800 {
anthony74b1cfc2011-10-06 12:44:16 +0000801 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000802 break;
803 }
anthony74b1cfc2011-10-06 12:44:16 +0000804 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000805 break;
806 }
anthony74b1cfc2011-10-06 12:44:16 +0000807 if (LocaleCompare("font",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000808 {
809 if (*argv[0] == '+')
810 {
811 if (image_info->font != (char *) NULL)
812 image_info->font=DestroyString(image_info->font);
813 break;
814 }
815 (void) CloneString(&image_info->font,argv[1]);
816 break;
817 }
anthony74b1cfc2011-10-06 12:44:16 +0000818 if (LocaleCompare("format",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000819 {
820 register const char
821 *q;
822
823 for (q=strchr(argv[1],'%'); q != (char *) NULL; q=strchr(q+1,'%'))
824 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
825 image_info->ping=MagickFalse;
anthony74b1cfc2011-10-06 12:44:16 +0000826 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000827 break;
828 }
anthony74b1cfc2011-10-06 12:44:16 +0000829 if (LocaleCompare("fuzz",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000830 {
831 if (*argv[0] == '+')
832 {
833 image_info->fuzz=0.0;
anthony74b1cfc2011-10-06 12:44:16 +0000834 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +0000835 break;
836 }
837 image_info->fuzz=SiPrefixToDouble(argv[1],(double) QuantumRange+
838 1.0);
anthony74b1cfc2011-10-06 12:44:16 +0000839 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000840 break;
841 }
842 break;
843 }
844 case 'g':
845 {
anthony74b1cfc2011-10-06 12:44:16 +0000846 if (LocaleCompare("gravity",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000847 {
848 if (*argv[0] == '+')
849 {
anthony74b1cfc2011-10-06 12:44:16 +0000850 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000851 break;
852 }
anthony74b1cfc2011-10-06 12:44:16 +0000853 (void) SetImageOption(image_info,option,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 {
858 if (*argv[0] == '+')
859 {
anthony74b1cfc2011-10-06 12:44:16 +0000860 (void) SetImageOption(image_info,option,"0.0");
anthony805a2d42011-09-25 08:25:12 +0000861 break;
862 }
anthony74b1cfc2011-10-06 12:44:16 +0000863 (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 {
872 if (*argv[0] == '+')
873 {
anthony74b1cfc2011-10-06 12:44:16 +0000874 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000875 break;
876 }
anthony74b1cfc2011-10-06 12:44:16 +0000877 (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 {
882 if (*argv[0] == '+')
883 {
884 image_info->interlace=UndefinedInterlace;
anthony74b1cfc2011-10-06 12:44:16 +0000885 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000886 break;
887 }
888 image_info->interlace=(InterlaceType) ParseCommandOption(
889 MagickInterlaceOptions,MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +0000890 (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 {
895 if (*argv[0] == '+')
896 {
anthony74b1cfc2011-10-06 12:44:16 +0000897 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000898 break;
899 }
anthony74b1cfc2011-10-06 12:44:16 +0000900 (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 {
905 if (*argv[0] == '+')
906 {
anthony74b1cfc2011-10-06 12:44:16 +0000907 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000908 break;
909 }
anthony74b1cfc2011-10-06 12:44:16 +0000910 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000911 break;
912 }
anthony74b1cfc2011-10-06 12:44:16 +0000913 if (LocaleCompare("interword-spacing",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000914 {
915 if (*argv[0] == '+')
916 {
anthony74b1cfc2011-10-06 12:44:16 +0000917 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000918 break;
919 }
anthony74b1cfc2011-10-06 12:44:16 +0000920 (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 {
929 if (*argv[0] == '+')
930 {
anthony74b1cfc2011-10-06 12:44:16 +0000931 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000932 break;
933 }
anthony74b1cfc2011-10-06 12:44:16 +0000934 (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 {
943 if (*argv[0] == '+')
944 {
anthony74b1cfc2011-10-06 12:44:16 +0000945 (void) DeleteImageOption(image_info,option);
anthony805a2d42011-09-25 08:25:12 +0000946 break;
947 }
anthony74b1cfc2011-10-06 12:44:16 +0000948 (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
959 if (*argv[0] == '+')
960 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
974 /*
975 Display configuration list.
976 */
977 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 {
1061 if (*argv[0] == '+')
1062 break;
1063 (void) SetLogFormat(argv[1]);
1064 break;
1065 }
anthony74b1cfc2011-10-06 12:44:16 +00001066 if (LocaleCompare("loop",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001067 {
1068 if (*argv[0] == '+')
1069 {
anthony74b1cfc2011-10-06 12:44:16 +00001070 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001071 break;
1072 }
anthony74b1cfc2011-10-06 12:44:16 +00001073 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001074 break;
1075 }
1076 break;
1077 }
1078 case 'm':
1079 {
anthony74b1cfc2011-10-06 12:44:16 +00001080 if (LocaleCompare("matte",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001081 {
1082 if (*argv[0] == '+')
1083 {
anthony74b1cfc2011-10-06 12:44:16 +00001084 (void) SetImageOption(image_info,option,"false");
anthony805a2d42011-09-25 08:25:12 +00001085 break;
1086 }
anthony74b1cfc2011-10-06 12:44:16 +00001087 (void) SetImageOption(image_info,option,"true");
anthony805a2d42011-09-25 08:25:12 +00001088 break;
1089 }
anthony74b1cfc2011-10-06 12:44:16 +00001090 if (LocaleCompare("mattecolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001091 {
1092 if (*argv[0] == '+')
1093 {
anthony74b1cfc2011-10-06 12:44:16 +00001094 (void) SetImageOption(image_info,option,argv[1]);
anthony1afdc7a2011-10-05 11:54:28 +00001095 (void) QueryColorCompliance(MatteColor,AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00001096 &image_info->matte_color,exception);
anthony805a2d42011-09-25 08:25:12 +00001097 break;
1098 }
anthony74b1cfc2011-10-06 12:44:16 +00001099 (void) SetImageOption(image_info,option,argv[1]);
anthony1afdc7a2011-10-05 11:54:28 +00001100 (void) QueryColorCompliance(argv[1],AllCompliance,&image_info->matte_color,
anthony805a2d42011-09-25 08:25:12 +00001101 exception);
1102 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 {
1112 image_info->monochrome=(*argv[0] == '-') ? MagickTrue : MagickFalse;
1113 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 {
1121 if (*argv[0] == '+')
1122 {
1123 image_info->orientation=UndefinedOrientation;
anthony74b1cfc2011-10-06 12:44:16 +00001124 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +00001125 break;
1126 }
1127 image_info->orientation=(OrientationType) ParseCommandOption(
1128 MagickOrientationOptions,MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001129 (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
1150 if (*argv[0] == '+')
1151 {
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 }
anthony74b1cfc2011-10-06 12:44:16 +00001173 if (LocaleCompare("pen",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001174 {
1175 if (*argv[0] == '+')
1176 {
anthony74b1cfc2011-10-06 12:44:16 +00001177 (void) SetImageOption(image_info,option,"none");
anthony805a2d42011-09-25 08:25:12 +00001178 break;
1179 }
anthony74b1cfc2011-10-06 12:44:16 +00001180 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001181 break;
1182 }
anthony74b1cfc2011-10-06 12:44:16 +00001183 if (LocaleCompare("ping",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001184 {
1185 image_info->ping=(*argv[0] == '-') ? MagickTrue : MagickFalse;
1186 break;
1187 }
anthony74b1cfc2011-10-06 12:44:16 +00001188 if (LocaleCompare("pointsize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001189 {
1190 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;
1195 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 {
1204 /*
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]);
1214 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 {
1222 /*
1223 Set image compression quality.
1224 */
1225 if (*argv[0] == '+')
1226 {
1227 image_info->quality=UndefinedCompressionQuality;
anthony74b1cfc2011-10-06 12:44:16 +00001228 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001229 break;
1230 }
1231 image_info->quality=StringToUnsignedLong(argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001232 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001233 break;
1234 }
anthony74b1cfc2011-10-06 12:44:16 +00001235 if (LocaleCompare("quiet",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001236 {
1237 static WarningHandler
1238 warning_handler = (WarningHandler) NULL;
1239
1240 if (*argv[0] == '+')
1241 {
1242 /*
1243 Restore error or warning messages.
1244 */
1245 warning_handler=SetWarningHandler(warning_handler);
1246 break;
1247 }
1248 /*
1249 Suppress error or warning messages.
1250 */
1251 warning_handler=SetWarningHandler((WarningHandler) NULL);
1252 break;
1253 }
1254 break;
1255 }
1256 case 'r':
1257 {
anthony74b1cfc2011-10-06 12:44:16 +00001258 if (LocaleCompare("red-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001259 {
1260 if (*argv[0] == '+')
1261 {
anthony74b1cfc2011-10-06 12:44:16 +00001262 (void) SetImageOption(image_info,option,"0.0");
anthony805a2d42011-09-25 08:25:12 +00001263 break;
1264 }
anthony74b1cfc2011-10-06 12:44:16 +00001265 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001266 break;
1267 }
1268 break;
1269 }
1270 case 's':
1271 {
anthony74b1cfc2011-10-06 12:44:16 +00001272 if (LocaleCompare("sampling-factor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001273 {
1274 /*
1275 Set image sampling factor.
1276 */
1277 if (*argv[0] == '+')
1278 {
1279 if (image_info->sampling_factor != (char *) NULL)
1280 image_info->sampling_factor=DestroyString(
1281 image_info->sampling_factor);
1282 break;
1283 }
1284 (void) CloneString(&image_info->sampling_factor,argv[1]);
1285 break;
1286 }
anthony74b1cfc2011-10-06 12:44:16 +00001287 if (LocaleCompare("scene",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001288 {
1289 /*
1290 Set image scene.
1291 */
1292 if (*argv[0] == '+')
1293 {
1294 image_info->scene=0;
anthony74b1cfc2011-10-06 12:44:16 +00001295 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001296 break;
1297 }
1298 image_info->scene=StringToUnsignedLong(argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001299 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001300 break;
1301 }
anthony74b1cfc2011-10-06 12:44:16 +00001302 if (LocaleCompare("seed",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001303 {
1304 size_t
1305 seed;
1306
1307 if (*argv[0] == '+')
1308 {
1309 seed=(size_t) time((time_t *) NULL);
1310 SeedPseudoRandomGenerator(seed);
1311 break;
1312 }
1313 seed=StringToUnsignedLong(argv[1]);
1314 SeedPseudoRandomGenerator(seed);
1315 break;
1316 }
anthony74b1cfc2011-10-06 12:44:16 +00001317 if (LocaleCompare("size",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001318 {
anthony74b1cfc2011-10-06 12:44:16 +00001319 /* FUTURE: convert to ImageOption
1320 Look at special handling for "size" in SetImageOption()
1321 */
anthony805a2d42011-09-25 08:25:12 +00001322 if (*argv[0] == '+')
1323 {
1324 if (image_info->size != (char *) NULL)
1325 image_info->size=DestroyString(image_info->size);
1326 break;
1327 }
1328 (void) CloneString(&image_info->size,argv[1]);
1329 break;
1330 }
anthony74b1cfc2011-10-06 12:44:16 +00001331 if (LocaleCompare("stroke",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001332 {
1333 if (*argv[0] == '+')
1334 {
anthony74b1cfc2011-10-06 12:44:16 +00001335 (void) SetImageOption(image_info,option,"none");
anthony805a2d42011-09-25 08:25:12 +00001336 break;
1337 }
anthony74b1cfc2011-10-06 12:44:16 +00001338 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001339 break;
1340 }
anthony74b1cfc2011-10-06 12:44:16 +00001341 if (LocaleCompare("strokewidth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001342 {
1343 if (*argv[0] == '+')
1344 {
anthony74b1cfc2011-10-06 12:44:16 +00001345 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001346 break;
1347 }
anthony74b1cfc2011-10-06 12:44:16 +00001348 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001349 break;
1350 }
anthony74b1cfc2011-10-06 12:44:16 +00001351 if (LocaleCompare("synchronize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001352 {
1353 if (*argv[0] == '+')
1354 {
1355 image_info->synchronize=MagickFalse;
1356 break;
1357 }
1358 image_info->synchronize=MagickTrue;
1359 break;
1360 }
1361 break;
1362 }
1363 case 't':
1364 {
anthony74b1cfc2011-10-06 12:44:16 +00001365 if (LocaleCompare("taint",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001366 {
1367 if (*argv[0] == '+')
1368 {
anthony74b1cfc2011-10-06 12:44:16 +00001369 (void) SetImageOption(image_info,option,"false");
anthony805a2d42011-09-25 08:25:12 +00001370 break;
1371 }
anthony74b1cfc2011-10-06 12:44:16 +00001372 (void) SetImageOption(image_info,option,"true");
anthony805a2d42011-09-25 08:25:12 +00001373 break;
1374 }
anthony74b1cfc2011-10-06 12:44:16 +00001375 if (LocaleCompare("texture",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001376 {
1377 if (*argv[0] == '+')
1378 {
1379 if (image_info->texture != (char *) NULL)
1380 image_info->texture=DestroyString(image_info->texture);
1381 break;
1382 }
1383 (void) CloneString(&image_info->texture,argv[1]);
1384 break;
1385 }
anthony74b1cfc2011-10-06 12:44:16 +00001386 if (LocaleCompare("tile-offset",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001387 {
1388 if (*argv[0] == '+')
1389 {
anthony74b1cfc2011-10-06 12:44:16 +00001390 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001391 break;
1392 }
anthony74b1cfc2011-10-06 12:44:16 +00001393 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001394 break;
1395 }
anthony74b1cfc2011-10-06 12:44:16 +00001396 if (LocaleCompare("transparent-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001397 {
1398 if (*argv[0] == '+')
1399 {
anthony1afdc7a2011-10-05 11:54:28 +00001400 (void) QueryColorCompliance("none",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00001401 &image_info->transparent_color,exception);
anthony74b1cfc2011-10-06 12:44:16 +00001402 (void) SetImageOption(image_info,option,"none");
anthony805a2d42011-09-25 08:25:12 +00001403 break;
1404 }
anthony1afdc7a2011-10-05 11:54:28 +00001405 (void) QueryColorCompliance("none",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00001406 &image_info->transparent_color,exception);
anthony805a2d42011-09-25 08:25:12 +00001407 exception);
anthony74b1cfc2011-10-06 12:44:16 +00001408 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001409 break;
1410 }
anthony74b1cfc2011-10-06 12:44:16 +00001411 if (LocaleCompare("type",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001412 {
1413 if (*argv[0] == '+')
1414 {
1415 image_info->type=UndefinedType;
anthony74b1cfc2011-10-06 12:44:16 +00001416 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +00001417 break;
1418 }
1419 image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
1420 MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001421 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001422 break;
1423 }
1424 break;
1425 }
1426 case 'u':
1427 {
anthony74b1cfc2011-10-06 12:44:16 +00001428 if (LocaleCompare("undercolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001429 {
1430 if (*argv[0] == '+')
1431 {
anthony74b1cfc2011-10-06 12:44:16 +00001432 (void) DeleteImageOption(image_info,option);
anthony805a2d42011-09-25 08:25:12 +00001433 break;
1434 }
anthony74b1cfc2011-10-06 12:44:16 +00001435 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001436 break;
1437 }
anthony74b1cfc2011-10-06 12:44:16 +00001438 if (LocaleCompare("units",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001439 {
1440 if (*argv[0] == '+')
1441 {
1442 image_info->units=UndefinedResolution;
anthony74b1cfc2011-10-06 12:44:16 +00001443 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +00001444 break;
1445 }
1446 image_info->units=(ResolutionType) ParseCommandOption(
1447 MagickResolutionOptions,MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001448 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001449 break;
1450 }
1451 break;
1452 }
1453 case 'v':
1454 {
anthony74b1cfc2011-10-06 12:44:16 +00001455 if (LocaleCompare("verbose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001456 {
1457 if (*argv[0] == '+')
1458 {
1459 image_info->verbose=MagickFalse;
1460 break;
1461 }
1462 image_info->verbose=MagickTrue;
1463 image_info->ping=MagickFalse;
1464 break;
1465 }
anthony74b1cfc2011-10-06 12:44:16 +00001466 if (LocaleCompare("view",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001467 {
1468 if (*argv[0] == '+')
1469 {
1470 if (image_info->view != (char *) NULL)
1471 image_info->view=DestroyString(image_info->view);
1472 break;
1473 }
1474 (void) CloneString(&image_info->view,argv[1]);
1475 break;
1476 }
anthony74b1cfc2011-10-06 12:44:16 +00001477 if (LocaleCompare("virtual-pixel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001478 {
1479 if (*argv[0] == '+')
1480 {
1481 image_info->virtual_pixel_method=UndefinedVirtualPixelMethod;
anthony74b1cfc2011-10-06 12:44:16 +00001482 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +00001483 break;
1484 }
1485 image_info->virtual_pixel_method=(VirtualPixelMethod)
1486 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001487 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001488 break;
1489 }
1490 break;
1491 }
1492 case 'w':
1493 {
anthony74b1cfc2011-10-06 12:44:16 +00001494 if (LocaleCompare("white-point",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001495 {
1496 if (*argv[0] == '+')
1497 {
anthony74b1cfc2011-10-06 12:44:16 +00001498 (void) SetImageOption(image_info,option,"0.0");
anthony805a2d42011-09-25 08:25:12 +00001499 break;
1500 }
anthony74b1cfc2011-10-06 12:44:16 +00001501 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001502 break;
1503 }
1504 break;
1505 }
1506 default:
1507 break;
1508 }
1509 return(MagickTrue);
1510}
1511
1512/*
1513%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1514% %
1515% %
1516% %
anthony74b1cfc2011-10-06 12:44:16 +00001517+ A p p l y I m a g e O p e r a t o r %
anthony805a2d42011-09-25 08:25:12 +00001518% %
1519% %
1520% %
1521%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1522%
anthony74b1cfc2011-10-06 12:44:16 +00001523% ApplyImageOperator() apply one simple image operation to just the current
1524% image.
anthony805a2d42011-09-25 08:25:12 +00001525%
1526% The image in the list may be modified in three different ways...
1527%
1528% * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1529% * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1530% * replace by a list of images (-separate and -crop only!)
1531%
1532% In each case the result is returned into the list, and the pointer to the
1533% modified image (last image added if replaced by a list of images) is
1534% returned. As the image pointed to may be replaced, the first image in the
1535% list may also change. GetFirstImageInList() should be used by caller if
1536% they wish return the Image pointer to the first image in list.
1537%
anthony74b1cfc2011-10-06 12:44:16 +00001538% The format of the ApplyImageOperator method is:
anthony805a2d42011-09-25 08:25:12 +00001539%
anthony74b1cfc2011-10-06 12:44:16 +00001540% MagickBooleanType ApplyImageOperator(MagickWand *wand,
1541% const int argc,const char **argv)
anthony805a2d42011-09-25 08:25:12 +00001542%
1543% A description of each parameter follows:
1544%
anthony74b1cfc2011-10-06 12:44:16 +00001545% o wand: The CLI wand holding all the settings and pointer to image
anthony805a2d42011-09-25 08:25:12 +00001546%
1547% o argc: Specifies a pointer to an integer describing the number of
1548% elements in the argument vector.
1549%
1550% o argv: Specifies a pointer to a text array containing the command line
1551% arguments.
1552%
anthony805a2d42011-09-25 08:25:12 +00001553% o exception: return any errors or warnings in this structure.
1554%
1555*/
anthony74b1cfc2011-10-06 12:44:16 +00001556MagickExport MagickBooleanType ApplyImageOperator(MagickWand *wand,
1557 const int wand_unused(argc), const char **argv, ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +00001558{
1559 Image *
1560 new_image;
1561
1562 ChannelType
1563 channel;
1564
1565 const char
1566 *format;
1567
1568 DrawInfo
1569 *draw_info;
1570
1571 GeometryInfo
1572 geometry_info;
1573
1574 RectangleInfo
1575 geometry;
1576
1577 MagickStatusType
1578 status;
1579
1580 PixelInfo
1581 fill;
1582
1583 MagickStatusType
1584 flags;
1585
1586 QuantizeInfo
1587 *quantize_info;
1588
1589 assert(image_info != (const ImageInfo *) NULL);
1590 assert(image_info->signature == MagickSignature);
1591 assert(image != (Image **) NULL);
1592 assert((*image)->signature == MagickSignature);
1593 if ((*image)->debug != MagickFalse)
1594 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
anthonya89dd172011-10-04 13:29:35 +00001595 if (argc < 0)
1596 return(MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00001597 draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
1598 quantize_info=AcquireQuantizeInfo(image_info);
1599 SetGeometryInfo(&geometry_info);
1600 GetPixelInfo(*image,&fill);
1601 SetPixelInfoPacket(*image,&(*image)->background_color,&fill);
1602 channel=image_info->channel;
1603 format=GetImageOption(image_info,"format");
1604
1605 new_image = (Image *)NULL;
1606
1607 switch (*(argv[0]+1))
1608 {
1609 case 'a':
1610 {
1611 if (LocaleCompare("adaptive-blur",argv[0]+1) == 0)
1612 {
anthony805a2d42011-09-25 08:25:12 +00001613 (void) SyncImageSettings(image_info,*image);
1614 flags=ParseGeometry(argv[1],&geometry_info);
1615 if ((flags & SigmaValue) == 0)
1616 geometry_info.sigma=1.0;
1617 if ((flags & XiValue) == 0)
1618 geometry_info.xi=0.0;
1619 new_image=AdaptiveBlurImage(*image,geometry_info.rho,
1620 geometry_info.sigma,geometry_info.xi,exception);
1621 break;
1622 }
1623 if (LocaleCompare("adaptive-resize",argv[0]+1) == 0)
1624 {
anthony1afdc7a2011-10-05 11:54:28 +00001625 /* FUTURE: this is really a "interpolate-resize" operator
1626 "adaptive-resize" uses a fixed "Mesh" interpolation
anthony805a2d42011-09-25 08:25:12 +00001627 */
1628 (void) SyncImageSettings(image_info,*image);
1629 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
1630 new_image=AdaptiveResizeImage(*image,geometry.width,
anthonya89dd172011-10-04 13:29:35 +00001631 geometry.height,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00001632 break;
1633 }
1634 if (LocaleCompare("adaptive-sharpen",argv[0]+1) == 0)
1635 {
1636 /*
1637 Adaptive sharpen image.
1638 */
1639 (void) SyncImageSettings(image_info,*image);
1640 flags=ParseGeometry(argv[1],&geometry_info);
1641 if ((flags & SigmaValue) == 0)
1642 geometry_info.sigma=1.0;
1643 if ((flags & XiValue) == 0)
1644 geometry_info.xi=0.0;
1645 new_image=AdaptiveSharpenImage(*image,geometry_info.rho,
1646 geometry_info.sigma,geometry_info.xi,exception);
1647 break;
1648 }
anthony805a2d42011-09-25 08:25:12 +00001649 if (LocaleCompare("alpha",argv[0]+1) == 0)
1650 {
1651 AlphaChannelType
1652 alpha_type;
1653
1654 (void) SyncImageSettings(image_info,*image);
1655 alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
1656 MagickFalse,argv[1]);
1657 (void) SetImageAlphaChannel(*image,alpha_type,exception);
1658 break;
1659 }
1660 if (LocaleCompare("annotate",argv[0]+1) == 0)
1661 {
1662 char
1663 *text,
1664 geometry[MaxTextExtent];
1665
anthony805a2d42011-09-25 08:25:12 +00001666 (void) SyncImageSettings(image_info,*image);
1667 SetGeometryInfo(&geometry_info);
1668 flags=ParseGeometry(argv[1],&geometry_info);
1669 if ((flags & SigmaValue) == 0)
1670 geometry_info.sigma=geometry_info.rho;
1671 text=InterpretImageProperties(image_info,*image,argv[2],
1672 exception);
1673 if (text == (char *) NULL)
1674 break;
1675 (void) CloneString(&draw_info->text,text);
1676 text=DestroyString(text);
1677 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1678 geometry_info.xi,geometry_info.psi);
1679 (void) CloneString(&draw_info->geometry,geometry);
1680 draw_info->affine.sx=cos(DegreesToRadians(
1681 fmod(geometry_info.rho,360.0)));
1682 draw_info->affine.rx=sin(DegreesToRadians(
1683 fmod(geometry_info.rho,360.0)));
1684 draw_info->affine.ry=(-sin(DegreesToRadians(
1685 fmod(geometry_info.sigma,360.0))));
1686 draw_info->affine.sy=cos(DegreesToRadians(
1687 fmod(geometry_info.sigma,360.0)));
1688 (void) AnnotateImage(*image,draw_info,exception);
1689 break;
1690 }
anthony805a2d42011-09-25 08:25:12 +00001691 if (LocaleCompare("auto-gamma",argv[0]+1) == 0)
1692 {
1693 /*
1694 Auto Adjust Gamma of image based on its mean
1695 */
1696 (void) SyncImageSettings(image_info,*image);
1697 (void) AutoGammaImage(*image,exception);
1698 break;
1699 }
1700 if (LocaleCompare("auto-level",argv[0]+1) == 0)
1701 {
1702 /*
1703 Perfectly Normalize (max/min stretch) the image
1704 */
1705 (void) SyncImageSettings(image_info,*image);
1706 (void) AutoLevelImage(*image,exception);
1707 break;
1708 }
1709 if (LocaleCompare("auto-orient",argv[0]+1) == 0)
1710 {
1711 (void) SyncImageSettings(image_info,*image);
1712 switch ((*image)->orientation)
1713 {
1714 case TopRightOrientation:
1715 {
1716 new_image=FlopImage(*image,exception);
1717 break;
1718 }
1719 case BottomRightOrientation:
1720 {
1721 new_image=RotateImage(*image,180.0,exception);
1722 break;
1723 }
1724 case BottomLeftOrientation:
1725 {
1726 new_image=FlipImage(*image,exception);
1727 break;
1728 }
1729 case LeftTopOrientation:
1730 {
1731 new_image=TransposeImage(*image,exception);
1732 break;
1733 }
1734 case RightTopOrientation:
1735 {
1736 new_image=RotateImage(*image,90.0,exception);
1737 break;
1738 }
1739 case RightBottomOrientation:
1740 {
1741 new_image=TransverseImage(*image,exception);
1742 break;
1743 }
1744 case LeftBottomOrientation:
1745 {
1746 new_image=RotateImage(*image,270.0,exception);
1747 break;
1748 }
1749 default:
1750 break;
1751 }
1752 if (new_image != (Image *) NULL)
1753 new_image->orientation=TopLeftOrientation;
1754 break;
1755 }
1756 break;
1757 }
1758 case 'b':
1759 {
1760 if (LocaleCompare("black-threshold",argv[0]+1) == 0)
1761 {
anthony805a2d42011-09-25 08:25:12 +00001762 (void) SyncImageSettings(image_info,*image);
1763 (void) BlackThresholdImage(*image,argv[1],exception);
1764 InheritException(exception,&(*image)->exception);
1765 break;
1766 }
1767 if (LocaleCompare("blue-shift",argv[0]+1) == 0)
1768 {
anthony805a2d42011-09-25 08:25:12 +00001769 (void) SyncImageSettings(image_info,*image);
1770 geometry_info.rho=1.5;
1771 if (*argv[0] == '-')
1772 flags=ParseGeometry(argv[1],&geometry_info);
1773 new_image=BlueShiftImage(*image,geometry_info.rho,exception);
1774 break;
1775 }
1776 if (LocaleCompare("blur",argv[0]+1) == 0)
1777 {
anthony74b1cfc2011-10-06 12:44:16 +00001778 /* FUTURE: use of "bias" in a blur is non-sensible */
anthony805a2d42011-09-25 08:25:12 +00001779 (void) SyncImageSettings(image_info,*image);
1780 flags=ParseGeometry(argv[1],&geometry_info);
1781 if ((flags & SigmaValue) == 0)
1782 geometry_info.sigma=1.0;
1783 if ((flags & XiValue) == 0)
1784 geometry_info.xi=0.0;
1785 new_image=BlurImage(*image,geometry_info.rho,
1786 geometry_info.sigma,geometry_info.xi,exception);
1787 break;
1788 }
1789 if (LocaleCompare("border",argv[0]+1) == 0)
1790 {
anthony805a2d42011-09-25 08:25:12 +00001791 (void) SyncImageSettings(image_info,*image);
1792 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
1793 if ((flags & SigmaValue) == 0)
1794 geometry.height=geometry.width;
anthonya89dd172011-10-04 13:29:35 +00001795 new_image=BorderImage(*image,&geometry,compose,exception);
anthony805a2d42011-09-25 08:25:12 +00001796 break;
1797 }
anthony805a2d42011-09-25 08:25:12 +00001798 if (LocaleCompare("brightness-contrast",argv[0]+1) == 0)
1799 {
1800 double
1801 brightness,
1802 contrast;
1803
1804 GeometryInfo
1805 geometry_info;
1806
1807 MagickStatusType
1808 flags;
1809
anthony805a2d42011-09-25 08:25:12 +00001810 (void) SyncImageSettings(image_info,*image);
1811 flags=ParseGeometry(argv[1],&geometry_info);
1812 brightness=geometry_info.rho;
1813 contrast=0.0;
1814 if ((flags & SigmaValue) != 0)
1815 contrast=geometry_info.sigma;
1816 (void) BrightnessContrastImage(*image,brightness,contrast,
1817 exception);
1818 InheritException(exception,&(*image)->exception);
1819 break;
1820 }
1821 break;
1822 }
1823 case 'c':
1824 {
1825 if (LocaleCompare("cdl",argv[0]+1) == 0)
1826 {
1827 char
1828 *color_correction_collection;
1829
1830 /*
1831 Color correct with a color decision list.
1832 */
1833 (void) SyncImageSettings(image_info,*image);
1834 color_correction_collection=FileToString(argv[1],~0,exception);
1835 if (color_correction_collection == (char *) NULL)
1836 break;
1837 (void) ColorDecisionListImage(*image,color_correction_collection,
1838 exception);
1839 InheritException(exception,&(*image)->exception);
1840 break;
1841 }
1842 if (LocaleCompare("channel",argv[0]+1) == 0)
1843 {
anthony74b1cfc2011-10-06 12:44:16 +00001844 /* The "channel" setting has already been set */
1845 SetPixelChannelMap(*image,image_info->channel);
anthony805a2d42011-09-25 08:25:12 +00001846 break;
1847 }
1848 if (LocaleCompare("charcoal",argv[0]+1) == 0)
1849 {
anthony805a2d42011-09-25 08:25:12 +00001850 (void) SyncImageSettings(image_info,*image);
1851 flags=ParseGeometry(argv[1],&geometry_info);
1852 if ((flags & SigmaValue) == 0)
1853 geometry_info.sigma=1.0;
1854 if ((flags & XiValue) == 0)
1855 geometry_info.xi=1.0;
1856 new_image=CharcoalImage(*image,geometry_info.rho,
1857 geometry_info.sigma,geometry_info.xi,exception);
1858 break;
1859 }
1860 if (LocaleCompare("chop",argv[0]+1) == 0)
1861 {
anthony805a2d42011-09-25 08:25:12 +00001862 (void) SyncImageSettings(image_info,*image);
1863 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
1864 new_image=ChopImage(*image,&geometry,exception);
1865 break;
1866 }
1867 if (LocaleCompare("clamp",argv[0]+1) == 0)
1868 {
anthony805a2d42011-09-25 08:25:12 +00001869 (void) SyncImageSettings(image_info,*image);
1870 (void) ClampImage(*image);
1871 InheritException(exception,&(*image)->exception);
1872 break;
1873 }
1874 if (LocaleCompare("clip",argv[0]+1) == 0)
1875 {
1876 (void) SyncImageSettings(image_info,*image);
1877 if (*argv[0] == '+')
1878 {
1879 (void) SetImageClipMask(*image,(Image *) NULL,exception);
1880 break;
1881 }
1882 (void) ClipImage(*image,exception);
1883 break;
1884 }
1885 if (LocaleCompare("clip-mask",argv[0]+1) == 0)
1886 {
1887 CacheView
1888 *mask_view;
1889
1890 Image
1891 *mask_image;
1892
1893 register Quantum
1894 *restrict q;
1895
1896 register ssize_t
1897 x;
1898
1899 ssize_t
1900 y;
1901
1902 (void) SyncImageSettings(image_info,*image);
1903 if (*argv[0] == '+')
1904 {
anthony74b1cfc2011-10-06 12:44:16 +00001905 /* Remove the write mask */
anthony805a2d42011-09-25 08:25:12 +00001906 (void) SetImageMask(*image,(Image *) NULL,exception);
1907 break;
1908 }
1909 mask_image=GetImageCache(image_info,argv[1],exception);
1910 if (mask_image == (Image *) NULL)
1911 break;
1912 if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
1913 return(MagickFalse);
anthony74b1cfc2011-10-06 12:44:16 +00001914 /* create a write mask from clip-mask image */
1915 /* FUTURE: use Alpha operations instead */
anthony805a2d42011-09-25 08:25:12 +00001916 mask_view=AcquireCacheView(mask_image);
1917 for (y=0; y < (ssize_t) mask_image->rows; y++)
1918 {
1919 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
1920 exception);
1921 if (q == (Quantum *) NULL)
1922 break;
1923 for (x=0; x < (ssize_t) mask_image->columns; x++)
1924 {
1925 if (mask_image->matte == MagickFalse)
1926 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1927 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1928 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1929 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1930 q+=GetPixelChannels(mask_image);
1931 }
1932 if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
1933 break;
1934 }
anthony74b1cfc2011-10-06 12:44:16 +00001935 /* set the write mask */
anthony805a2d42011-09-25 08:25:12 +00001936 mask_view=DestroyCacheView(mask_view);
1937 mask_image->matte=MagickTrue;
anthonya89dd172011-10-04 13:29:35 +00001938 (void) SetImageClipMask(*image,mask_image,exception);
anthony805a2d42011-09-25 08:25:12 +00001939 mask_image=DestroyImage(mask_image);
1940 InheritException(exception,&(*image)->exception);
1941 break;
1942 }
1943 if (LocaleCompare("clip-path",argv[0]+1) == 0)
1944 {
1945 (void) SyncImageSettings(image_info,*image);
1946 (void) ClipImagePath(*image,argv[1],*argv[0] == '-' ? MagickTrue :
1947 MagickFalse,exception);
1948 break;
1949 }
1950 if (LocaleCompare("colorize",argv[0]+1) == 0)
1951 {
anthony805a2d42011-09-25 08:25:12 +00001952 (void) SyncImageSettings(image_info,*image);
1953 new_image=ColorizeImage(*image,argv[1],draw_info->fill,
1954 exception);
1955 break;
1956 }
1957 if (LocaleCompare("color-matrix",argv[0]+1) == 0)
1958 {
1959 KernelInfo
1960 *kernel;
1961
1962 (void) SyncImageSettings(image_info,*image);
1963 kernel=AcquireKernelInfo(argv[1]);
1964 if (kernel == (KernelInfo *) NULL)
1965 break;
1966 new_image=ColorMatrixImage(*image,kernel,exception);
1967 kernel=DestroyKernelInfo(kernel);
1968 break;
1969 }
1970 if (LocaleCompare("colors",argv[0]+1) == 0)
1971 {
anthony74b1cfc2011-10-06 12:44:16 +00001972 /* Reduce the number of colors in the image. */
anthony805a2d42011-09-25 08:25:12 +00001973 (void) SyncImageSettings(image_info,*image);
1974 quantize_info->number_colors=StringToUnsignedLong(argv[1]);
1975 if (quantize_info->number_colors == 0)
1976 break;
1977 if (((*image)->storage_class == DirectClass) ||
1978 (*image)->colors > quantize_info->number_colors)
1979 (void) QuantizeImage(quantize_info,*image,exception);
1980 else
1981 (void) CompressImageColormap(*image,exception);
1982 break;
1983 }
1984 if (LocaleCompare("colorspace",argv[0]+1) == 0)
1985 {
1986 ColorspaceType
1987 colorspace;
1988
1989 (void) SyncImageSettings(image_info,*image);
1990 if (*argv[0] == '+')
1991 {
1992 (void) TransformImageColorspace(*image,RGBColorspace);
1993 InheritException(exception,&(*image)->exception);
1994 break;
1995 }
1996 colorspace=(ColorspaceType) ParseCommandOption(
1997 MagickColorspaceOptions,MagickFalse,argv[1]);
1998 (void) TransformImageColorspace(*image,colorspace);
1999 InheritException(exception,&(*image)->exception);
2000 break;
2001 }
anthonya89dd172011-10-04 13:29:35 +00002002 if (LocaleCompare("compose",argv[0]+1) == 0)
2003 {
2004 (void) SyncImageSettings(image_info,*image);
2005 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
2006 MagickFalse,argv[1]);
2007 break;
2008 }
anthony805a2d42011-09-25 08:25:12 +00002009 if (LocaleCompare("contrast",argv[0]+1) == 0)
2010 {
2011 (void) SyncImageSettings(image_info,*image);
2012 (void) ContrastImage(*image,(*argv[0] == '-') ? MagickTrue :
2013 MagickFalse,exception);
2014 break;
2015 }
2016 if (LocaleCompare("contrast-stretch",argv[0]+1) == 0)
2017 {
2018 double
2019 black_point,
2020 white_point;
2021
2022 MagickStatusType
2023 flags;
2024
2025 /*
2026 Contrast stretch image.
2027 */
2028 (void) SyncImageSettings(image_info,*image);
2029 flags=ParseGeometry(argv[1],&geometry_info);
2030 black_point=geometry_info.rho;
2031 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2032 black_point;
2033 if ((flags & PercentValue) != 0)
2034 {
2035 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2036 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2037 }
2038 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2039 white_point;
2040 (void) ContrastStretchImage(*image,black_point,white_point,
2041 exception);
2042 InheritException(exception,&(*image)->exception);
2043 break;
2044 }
2045 if (LocaleCompare("convolve",argv[0]+1) == 0)
2046 {
2047 KernelInfo
2048 *kernel_info;
2049
2050 (void) SyncImageSettings(image_info,*image);
2051 kernel_info=AcquireKernelInfo(argv[1]);
2052 if (kernel_info == (KernelInfo *) NULL)
2053 break;
2054 kernel_info->bias=(*image)->bias;
2055 new_image=ConvolveImage(*image,kernel_info,exception);
2056 kernel_info=DestroyKernelInfo(kernel_info);
2057 break;
2058 }
2059 if (LocaleCompare("crop",argv[0]+1) == 0)
2060 {
2061 /*
2062 Crop a image to a smaller size
2063 */
2064 (void) SyncImageSettings(image_info,*image);
2065 new_image=CropImageToTiles(*image,argv[1],exception);
2066 break;
2067 }
2068 if (LocaleCompare("cycle",argv[0]+1) == 0)
2069 {
2070 /*
2071 Cycle an image colormap.
2072 */
2073 (void) SyncImageSettings(image_info,*image);
2074 (void) CycleColormapImage(*image,(ssize_t) StringToLong(argv[1]),
2075 exception);
2076 break;
2077 }
2078 break;
2079 }
2080 case 'd':
2081 {
2082 if (LocaleCompare("decipher",argv[0]+1) == 0)
2083 {
2084 StringInfo
2085 *passkey;
2086
2087 /*
2088 Decipher pixels.
2089 */
2090 (void) SyncImageSettings(image_info,*image);
2091 passkey=FileToStringInfo(argv[1],~0,exception);
2092 if (passkey != (StringInfo *) NULL)
2093 {
2094 (void) PasskeyDecipherImage(*image,passkey,exception);
2095 passkey=DestroyStringInfo(passkey);
2096 }
2097 break;
2098 }
2099 if (LocaleCompare("density",argv[0]+1) == 0)
2100 {
2101 /*
2102 Set image density.
2103 */
2104 (void) CloneString(&draw_info->density,argv[1]);
2105 break;
2106 }
2107 if (LocaleCompare("depth",argv[0]+1) == 0)
2108 {
2109 (void) SyncImageSettings(image_info,*image);
2110 if (*argv[0] == '+')
2111 {
2112 (void) SetImageDepth(*image,MAGICKCORE_QUANTUM_DEPTH);
2113 break;
2114 }
2115 (void) SetImageDepth(*image,StringToUnsignedLong(argv[1]));
2116 break;
2117 }
2118 if (LocaleCompare("deskew",argv[0]+1) == 0)
2119 {
2120 double
2121 threshold;
2122
2123 /*
2124 Straighten the image.
2125 */
2126 (void) SyncImageSettings(image_info,*image);
2127 if (*argv[0] == '+')
2128 threshold=40.0*QuantumRange/100.0;
2129 else
2130 threshold=SiPrefixToDouble(argv[1],QuantumRange);
2131 new_image=DeskewImage(*image,threshold,exception);
2132 break;
2133 }
2134 if (LocaleCompare("despeckle",argv[0]+1) == 0)
2135 {
2136 /*
2137 Reduce the speckles within an image.
2138 */
2139 (void) SyncImageSettings(image_info,*image);
2140 new_image=DespeckleImage(*image,exception);
2141 break;
2142 }
2143 if (LocaleCompare("display",argv[0]+1) == 0)
2144 {
2145 (void) CloneString(&draw_info->server_name,argv[1]);
2146 break;
2147 }
2148 if (LocaleCompare("distort",argv[0]+1) == 0)
2149 {
2150 char
2151 *args,
2152 token[MaxTextExtent];
2153
2154 const char
2155 *p;
2156
2157 DistortImageMethod
2158 method;
2159
2160 double
2161 *arguments;
2162
2163 register ssize_t
2164 x;
2165
2166 size_t
2167 number_arguments;
2168
2169 /*
2170 Distort image.
2171 */
2172 (void) SyncImageSettings(image_info,*image);
2173 method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
2174 MagickFalse,argv[1]);
2175 if ( method == ResizeDistortion )
2176 {
2177 /* Special Case - Argument is actually a resize geometry!
2178 ** Convert that to an appropriate distortion argument array.
2179 */
2180 double
2181 resize_args[2];
2182 (void) ParseRegionGeometry(*image,argv[2],&geometry,
2183 exception);
2184 resize_args[0]=(double)geometry.width;
2185 resize_args[1]=(double)geometry.height;
2186 new_image=DistortImage(*image,method,(size_t)2,
2187 resize_args,MagickTrue,exception);
2188 break;
2189 }
2190 args=InterpretImageProperties(image_info,*image,argv[2],
2191 exception);
2192 if (args == (char *) NULL)
2193 break;
2194 p=(char *) args;
2195 for (x=0; *p != '\0'; x++)
2196 {
2197 GetMagickToken(p,&p,token);
2198 if (*token == ',')
2199 GetMagickToken(p,&p,token);
2200 }
2201 number_arguments=(size_t) x;
2202 arguments=(double *) AcquireQuantumMemory(number_arguments,
2203 sizeof(*arguments));
2204 if (arguments == (double *) NULL)
2205 ThrowWandFatalException(ResourceLimitFatalError,
2206 "MemoryAllocationFailed",(*image)->filename);
2207 (void) ResetMagickMemory(arguments,0,number_arguments*
2208 sizeof(*arguments));
2209 p=(char *) args;
2210 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2211 {
2212 GetMagickToken(p,&p,token);
2213 if (*token == ',')
2214 GetMagickToken(p,&p,token);
2215 arguments[x]=InterpretLocaleValue(token,(char **) NULL);
2216 }
2217 args=DestroyString(args);
2218 new_image=DistortImage(*image,method,number_arguments,arguments,
2219 (*argv[0] == '+') ? MagickTrue : MagickFalse,exception);
2220 arguments=(double *) RelinquishMagickMemory(arguments);
2221 break;
2222 }
2223 if (LocaleCompare("dither",argv[0]+1) == 0)
2224 {
2225 if (*argv[0] == '+')
2226 {
2227 quantize_info->dither=MagickFalse;
2228 break;
2229 }
2230 quantize_info->dither=MagickTrue;
2231 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
2232 MagickDitherOptions,MagickFalse,argv[1]);
2233 if (quantize_info->dither_method == NoDitherMethod)
2234 quantize_info->dither=MagickFalse;
2235 break;
2236 }
2237 if (LocaleCompare("draw",argv[0]+1) == 0)
2238 {
2239 /*
2240 Draw image.
2241 */
2242 (void) SyncImageSettings(image_info,*image);
2243 (void) CloneString(&draw_info->primitive,argv[1]);
2244 (void) DrawImage(*image,draw_info,exception);
2245 break;
2246 }
2247 break;
2248 }
2249 case 'e':
2250 {
2251 if (LocaleCompare("edge",argv[0]+1) == 0)
2252 {
2253 /*
2254 Enhance edges in the image.
2255 */
2256 (void) SyncImageSettings(image_info,*image);
2257 flags=ParseGeometry(argv[1],&geometry_info);
2258 if ((flags & SigmaValue) == 0)
2259 geometry_info.sigma=1.0;
2260 new_image=EdgeImage(*image,geometry_info.rho,
2261 geometry_info.sigma,exception);
2262 break;
2263 }
2264 if (LocaleCompare("emboss",argv[0]+1) == 0)
2265 {
2266 /*
2267 Gaussian embossen image.
2268 */
2269 (void) SyncImageSettings(image_info,*image);
2270 flags=ParseGeometry(argv[1],&geometry_info);
2271 if ((flags & SigmaValue) == 0)
2272 geometry_info.sigma=1.0;
2273 new_image=EmbossImage(*image,geometry_info.rho,
2274 geometry_info.sigma,exception);
2275 break;
2276 }
2277 if (LocaleCompare("encipher",argv[0]+1) == 0)
2278 {
2279 StringInfo
2280 *passkey;
2281
2282 /*
2283 Encipher pixels.
2284 */
2285 (void) SyncImageSettings(image_info,*image);
2286 passkey=FileToStringInfo(argv[1],~0,exception);
2287 if (passkey != (StringInfo *) NULL)
2288 {
2289 (void) PasskeyEncipherImage(*image,passkey,exception);
2290 passkey=DestroyStringInfo(passkey);
2291 }
2292 break;
2293 }
2294 if (LocaleCompare("encoding",argv[0]+1) == 0)
2295 {
2296 (void) CloneString(&draw_info->encoding,argv[1]);
2297 break;
2298 }
2299 if (LocaleCompare("enhance",argv[0]+1) == 0)
2300 {
2301 /*
2302 Enhance image.
2303 */
2304 (void) SyncImageSettings(image_info,*image);
2305 new_image=EnhanceImage(*image,exception);
2306 break;
2307 }
2308 if (LocaleCompare("equalize",argv[0]+1) == 0)
2309 {
2310 /*
2311 Equalize image.
2312 */
2313 (void) SyncImageSettings(image_info,*image);
2314 (void) EqualizeImage(*image,exception);
2315 break;
2316 }
2317 if (LocaleCompare("evaluate",argv[0]+1) == 0)
2318 {
2319 double
2320 constant;
2321
2322 MagickEvaluateOperator
2323 op;
2324
2325 (void) SyncImageSettings(image_info,*image);
2326 op=(MagickEvaluateOperator) ParseCommandOption(
2327 MagickEvaluateOptions,MagickFalse,argv[1]);
2328 constant=SiPrefixToDouble(argv[2],QuantumRange);
2329 (void) EvaluateImage(*image,op,constant,exception);
2330 break;
2331 }
2332 if (LocaleCompare("extent",argv[0]+1) == 0)
2333 {
2334 /*
2335 Set the image extent.
2336 */
2337 (void) SyncImageSettings(image_info,*image);
2338 flags=ParseGravityGeometry(*image,argv[1],&geometry,exception);
2339 if (geometry.width == 0)
2340 geometry.width=(*image)->columns;
2341 if (geometry.height == 0)
2342 geometry.height=(*image)->rows;
2343 new_image=ExtentImage(*image,&geometry,exception);
2344 break;
2345 }
2346 break;
2347 }
2348 case 'f':
2349 {
2350 if (LocaleCompare("family",argv[0]+1) == 0)
2351 {
2352 if (*argv[0] == '+')
2353 {
2354 if (draw_info->family != (char *) NULL)
2355 draw_info->family=DestroyString(draw_info->family);
2356 break;
2357 }
2358 (void) CloneString(&draw_info->family,argv[1]);
2359 break;
2360 }
2361 if (LocaleCompare("features",argv[0]+1) == 0)
2362 {
2363 if (*argv[0] == '+')
2364 {
2365 (void) DeleteImageArtifact(*image,"identify:features");
2366 break;
2367 }
2368 (void) SetImageArtifact(*image,"identify:features",argv[1]);
2369 break;
2370 }
2371 if (LocaleCompare("fill",argv[0]+1) == 0)
2372 {
2373 ExceptionInfo
2374 *sans;
2375
2376 GetPixelInfo(*image,&fill);
2377 if (*argv[0] == '+')
2378 {
anthonya89dd172011-10-04 13:29:35 +00002379 (void) QueryMagickColorCompliance("none",AllCompliance,&fill,
anthony74b1cfc2011-10-06 12:44:16 +00002380 exception);
anthony1afdc7a2011-10-05 11:54:28 +00002381 (void) QueryColorCompliance("none",AllCompliance,&draw_info->fill,
anthonya89dd172011-10-04 13:29:35 +00002382 exception);
anthony805a2d42011-09-25 08:25:12 +00002383 if (draw_info->fill_pattern != (Image *) NULL)
2384 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
2385 break;
2386 }
2387 sans=AcquireExceptionInfo();
anthonya89dd172011-10-04 13:29:35 +00002388 (void) QueryMagickColorCompliance(argv[1],AllCompliance,&fill,sans);
anthony1afdc7a2011-10-05 11:54:28 +00002389 status=QueryColorCompliance(argv[1],AllCompliance,&draw_info->fill,sans);
anthony805a2d42011-09-25 08:25:12 +00002390 sans=DestroyExceptionInfo(sans);
2391 if (status == MagickFalse)
2392 draw_info->fill_pattern=GetImageCache(image_info,argv[1],
2393 exception);
2394 break;
2395 }
2396 if (LocaleCompare("flip",argv[0]+1) == 0)
2397 {
2398 /*
2399 Flip image scanlines.
2400 */
2401 (void) SyncImageSettings(image_info,*image);
2402 new_image=FlipImage(*image,exception);
2403 break;
2404 }
2405 if (LocaleCompare("flop",argv[0]+1) == 0)
2406 {
2407 /*
2408 Flop image scanlines.
2409 */
2410 (void) SyncImageSettings(image_info,*image);
2411 new_image=FlopImage(*image,exception);
2412 break;
2413 }
2414 if (LocaleCompare("floodfill",argv[0]+1) == 0)
2415 {
2416 PixelInfo
2417 target;
2418
2419 /*
2420 Floodfill image.
2421 */
2422 (void) SyncImageSettings(image_info,*image);
2423 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
anthonya89dd172011-10-04 13:29:35 +00002424 (void) QueryMagickColorCompliance(argv[2],AllCompliance,&target,
2425 exception);
anthony805a2d42011-09-25 08:25:12 +00002426 (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
2427 geometry.y,*argv[0] == '-' ? MagickFalse : MagickTrue,exception);
2428 break;
2429 }
2430 if (LocaleCompare("font",argv[0]+1) == 0)
2431 {
2432 if (*argv[0] == '+')
2433 {
2434 if (draw_info->font != (char *) NULL)
2435 draw_info->font=DestroyString(draw_info->font);
2436 break;
2437 }
2438 (void) CloneString(&draw_info->font,argv[1]);
2439 break;
2440 }
2441 if (LocaleCompare("format",argv[0]+1) == 0)
2442 {
2443 format=argv[1];
2444 break;
2445 }
2446 if (LocaleCompare("frame",argv[0]+1) == 0)
2447 {
2448 FrameInfo
2449 frame_info;
2450
2451 /*
2452 Surround image with an ornamental border.
2453 */
2454 (void) SyncImageSettings(image_info,*image);
2455 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
2456 frame_info.width=geometry.width;
2457 frame_info.height=geometry.height;
2458 if ((flags & HeightValue) == 0)
2459 frame_info.height=geometry.width;
2460 frame_info.outer_bevel=geometry.x;
2461 frame_info.inner_bevel=geometry.y;
2462 frame_info.x=(ssize_t) frame_info.width;
2463 frame_info.y=(ssize_t) frame_info.height;
2464 frame_info.width=(*image)->columns+2*frame_info.width;
2465 frame_info.height=(*image)->rows+2*frame_info.height;
anthonya89dd172011-10-04 13:29:35 +00002466 new_image=FrameImage(*image,&frame_info,compose,exception);
anthony805a2d42011-09-25 08:25:12 +00002467 break;
2468 }
2469 if (LocaleCompare("function",argv[0]+1) == 0)
2470 {
2471 char
2472 *arguments,
2473 token[MaxTextExtent];
2474
2475 const char
2476 *p;
2477
2478 double
2479 *parameters;
2480
2481 MagickFunction
2482 function;
2483
2484 register ssize_t
2485 x;
2486
2487 size_t
2488 number_parameters;
2489
2490 /*
2491 Function Modify Image Values
2492 */
2493 (void) SyncImageSettings(image_info,*image);
2494 function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
2495 MagickFalse,argv[1]);
2496 arguments=InterpretImageProperties(image_info,*image,argv[2],
2497 exception);
2498 if (arguments == (char *) NULL)
2499 break;
2500 p=(char *) arguments;
2501 for (x=0; *p != '\0'; x++)
2502 {
2503 GetMagickToken(p,&p,token);
2504 if (*token == ',')
2505 GetMagickToken(p,&p,token);
2506 }
2507 number_parameters=(size_t) x;
2508 parameters=(double *) AcquireQuantumMemory(number_parameters,
2509 sizeof(*parameters));
2510 if (parameters == (double *) NULL)
2511 ThrowWandFatalException(ResourceLimitFatalError,
2512 "MemoryAllocationFailed",(*image)->filename);
2513 (void) ResetMagickMemory(parameters,0,number_parameters*
2514 sizeof(*parameters));
2515 p=(char *) arguments;
2516 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
2517 {
2518 GetMagickToken(p,&p,token);
2519 if (*token == ',')
2520 GetMagickToken(p,&p,token);
2521 parameters[x]=InterpretLocaleValue(token,(char **) NULL);
2522 }
2523 arguments=DestroyString(arguments);
2524 (void) FunctionImage(*image,function,number_parameters,parameters,
2525 exception);
2526 parameters=(double *) RelinquishMagickMemory(parameters);
2527 break;
2528 }
2529 break;
2530 }
2531 case 'g':
2532 {
2533 if (LocaleCompare("gamma",argv[0]+1) == 0)
2534 {
2535 /*
2536 Gamma image.
2537 */
2538 (void) SyncImageSettings(image_info,*image);
2539 if (*argv[0] == '+')
2540 (*image)->gamma=InterpretLocaleValue(argv[1],(char **) NULL);
2541 else
2542 (void) GammaImage(*image,InterpretLocaleValue(argv[1],
2543 (char **) NULL),exception);
2544 break;
2545 }
2546 if ((LocaleCompare("gaussian-blur",argv[0]+1) == 0) ||
2547 (LocaleCompare("gaussian",argv[0]+1) == 0))
2548 {
2549 /*
2550 Gaussian blur image.
2551 */
2552 (void) SyncImageSettings(image_info,*image);
2553 flags=ParseGeometry(argv[1],&geometry_info);
2554 if ((flags & SigmaValue) == 0)
2555 geometry_info.sigma=1.0;
2556 if ((flags & XiValue) == 0)
2557 geometry_info.xi=0.0;
2558 new_image=GaussianBlurImage(*image,geometry_info.rho,
2559 geometry_info.sigma,geometry_info.xi,exception);
2560 break;
2561 }
2562 if (LocaleCompare("geometry",argv[0]+1) == 0)
2563 {
2564 /*
2565 Record Image offset, Resize last image.
2566 */
2567 (void) SyncImageSettings(image_info,*image);
2568 if (*argv[0] == '+')
2569 {
2570 if ((*image)->geometry != (char *) NULL)
2571 (*image)->geometry=DestroyString((*image)->geometry);
2572 break;
2573 }
2574 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2575 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2576 (void) CloneString(&(*image)->geometry,argv[1]);
2577 else
2578 new_image=ResizeImage(*image,geometry.width,geometry.height,
2579 (*image)->filter,(*image)->blur,exception);
2580 break;
2581 }
2582 if (LocaleCompare("gravity",argv[0]+1) == 0)
2583 {
2584 if (*argv[0] == '+')
2585 {
2586 draw_info->gravity=UndefinedGravity;
2587 break;
2588 }
2589 draw_info->gravity=(GravityType) ParseCommandOption(
2590 MagickGravityOptions,MagickFalse,argv[1]);
2591 break;
2592 }
2593 break;
2594 }
2595 case 'h':
2596 {
2597 if (LocaleCompare("highlight-color",argv[0]+1) == 0)
2598 {
2599 (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
2600 break;
2601 }
2602 break;
2603 }
2604 case 'i':
2605 {
2606 if (LocaleCompare("identify",argv[0]+1) == 0)
2607 {
2608 char
2609 *text;
2610
2611 (void) SyncImageSettings(image_info,*image);
2612 if (format == (char *) NULL)
2613 {
2614 (void) IdentifyImage(*image,stdout,image_info->verbose,
2615 exception);
2616 break;
2617 }
2618 text=InterpretImageProperties(image_info,*image,format,
2619 exception);
2620 if (text == (char *) NULL)
2621 break;
2622 (void) fputs(text,stdout);
2623 (void) fputc('\n',stdout);
2624 text=DestroyString(text);
2625 break;
2626 }
2627 if (LocaleCompare("implode",argv[0]+1) == 0)
2628 {
2629 /*
2630 Implode image.
2631 */
2632 (void) SyncImageSettings(image_info,*image);
2633 (void) ParseGeometry(argv[1],&geometry_info);
anthonya89dd172011-10-04 13:29:35 +00002634 new_image=ImplodeImage(*image,geometry_info.rho,
2635 interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00002636 break;
2637 }
2638 if (LocaleCompare("interline-spacing",argv[0]+1) == 0)
2639 {
2640 if (*argv[0] == '+')
2641 (void) ParseGeometry("0",&geometry_info);
2642 else
2643 (void) ParseGeometry(argv[1],&geometry_info);
2644 draw_info->interline_spacing=geometry_info.rho;
2645 break;
2646 }
anthonya89dd172011-10-04 13:29:35 +00002647 if (LocaleCompare("interpolate",argv[0]+1) == 0)
2648 {
2649 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
2650 MagickInterpolateOptions,MagickFalse,argv[1]);
2651 break;
2652 }
anthony805a2d42011-09-25 08:25:12 +00002653 if (LocaleCompare("interword-spacing",argv[0]+1) == 0)
2654 {
2655 if (*argv[0] == '+')
2656 (void) ParseGeometry("0",&geometry_info);
2657 else
2658 (void) ParseGeometry(argv[1],&geometry_info);
2659 draw_info->interword_spacing=geometry_info.rho;
2660 break;
2661 }
2662 break;
2663 }
2664 case 'k':
2665 {
2666 if (LocaleCompare("kerning",argv[0]+1) == 0)
2667 {
2668 if (*argv[0] == '+')
2669 (void) ParseGeometry("0",&geometry_info);
2670 else
2671 (void) ParseGeometry(argv[1],&geometry_info);
2672 draw_info->kerning=geometry_info.rho;
2673 break;
2674 }
2675 break;
2676 }
2677 case 'l':
2678 {
2679 if (LocaleCompare("lat",argv[0]+1) == 0)
2680 {
2681 /*
2682 Local adaptive threshold image.
2683 */
2684 (void) SyncImageSettings(image_info,*image);
2685 flags=ParseGeometry(argv[1],&geometry_info);
2686 if ((flags & PercentValue) != 0)
2687 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2688 new_image=AdaptiveThresholdImage(*image,(size_t)
2689 geometry_info.rho,(size_t) geometry_info.sigma,(double)
2690 geometry_info.xi,exception);
2691 break;
2692 }
2693 if (LocaleCompare("level",argv[0]+1) == 0)
2694 {
2695 MagickRealType
2696 black_point,
2697 gamma,
2698 white_point;
2699
2700 MagickStatusType
2701 flags;
2702
2703 /*
2704 Parse levels.
2705 */
2706 (void) SyncImageSettings(image_info,*image);
2707 flags=ParseGeometry(argv[1],&geometry_info);
2708 black_point=geometry_info.rho;
2709 white_point=(MagickRealType) QuantumRange;
2710 if ((flags & SigmaValue) != 0)
2711 white_point=geometry_info.sigma;
2712 gamma=1.0;
2713 if ((flags & XiValue) != 0)
2714 gamma=geometry_info.xi;
2715 if ((flags & PercentValue) != 0)
2716 {
2717 black_point*=(MagickRealType) (QuantumRange/100.0);
2718 white_point*=(MagickRealType) (QuantumRange/100.0);
2719 }
2720 if ((flags & SigmaValue) == 0)
2721 white_point=(MagickRealType) QuantumRange-black_point;
2722 if ((*argv[0] == '+') || ((flags & AspectValue) != 0))
2723 (void) LevelizeImage(*image,black_point,white_point,gamma,
2724 exception);
2725 else
2726 (void) LevelImage(*image,black_point,white_point,gamma,
2727 exception);
2728 InheritException(exception,&(*image)->exception);
2729 break;
2730 }
2731 if (LocaleCompare("level-colors",argv[0]+1) == 0)
2732 {
2733 char
2734 token[MaxTextExtent];
2735
2736 const char
2737 *p;
2738
2739 PixelInfo
2740 black_point,
2741 white_point;
2742
2743 p=(const char *) argv[1];
2744 GetMagickToken(p,&p,token); /* get black point color */
2745 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
anthonya89dd172011-10-04 13:29:35 +00002746 (void) QueryMagickColorCompliance(token,AllCompliance,
2747 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002748 else
anthonya89dd172011-10-04 13:29:35 +00002749 (void) QueryMagickColorCompliance("#000000",AllCompliance,
2750 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002751 if (isalpha((int) token[0]) || (token[0] == '#'))
2752 GetMagickToken(p,&p,token);
2753 if (*token == '\0')
2754 white_point=black_point; /* set everything to that color */
2755 else
2756 {
2757 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2758 GetMagickToken(p,&p,token); /* Get white point color. */
2759 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
anthonya89dd172011-10-04 13:29:35 +00002760 (void) QueryMagickColorCompliance(token,AllCompliance,
2761 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002762 else
anthonya89dd172011-10-04 13:29:35 +00002763 (void) QueryMagickColorCompliance("#ffffff",AllCompliance,
2764 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002765 }
2766 (void) LevelImageColors(*image,&black_point,&white_point,
2767 *argv[0] == '+' ? MagickTrue : MagickFalse,exception);
2768 break;
2769 }
2770 if (LocaleCompare("linear-stretch",argv[0]+1) == 0)
2771 {
2772 double
2773 black_point,
2774 white_point;
2775
2776 MagickStatusType
2777 flags;
2778
2779 (void) SyncImageSettings(image_info,*image);
2780 flags=ParseGeometry(argv[1],&geometry_info);
2781 black_point=geometry_info.rho;
2782 white_point=(MagickRealType) (*image)->columns*(*image)->rows;
2783 if ((flags & SigmaValue) != 0)
2784 white_point=geometry_info.sigma;
2785 if ((flags & PercentValue) != 0)
2786 {
2787 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2788 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2789 }
2790 if ((flags & SigmaValue) == 0)
2791 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2792 black_point;
2793 (void) LinearStretchImage(*image,black_point,white_point,exception);
2794 InheritException(exception,&(*image)->exception);
2795 break;
2796 }
2797 if (LocaleCompare("linewidth",argv[0]+1) == 0)
2798 {
2799 draw_info->stroke_width=InterpretLocaleValue(argv[1],
2800 (char **) NULL);
2801 break;
2802 }
2803 if (LocaleCompare("liquid-rescale",argv[0]+1) == 0)
2804 {
2805 /*
2806 Liquid rescale image.
2807 */
2808 (void) SyncImageSettings(image_info,*image);
2809 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2810 if ((flags & XValue) == 0)
2811 geometry.x=1;
2812 if ((flags & YValue) == 0)
2813 geometry.y=0;
2814 new_image=LiquidRescaleImage(*image,geometry.width,
2815 geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
2816 break;
2817 }
2818 if (LocaleCompare("lowlight-color",argv[0]+1) == 0)
2819 {
2820 (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
2821 break;
2822 }
2823 break;
2824 }
2825 case 'm':
2826 {
2827 if (LocaleCompare("map",argv[0]+1) == 0)
2828 {
2829 Image
2830 *remap_image;
2831
2832 /*
2833 Transform image colors to match this set of colors.
2834 */
2835 (void) SyncImageSettings(image_info,*image);
2836 if (*argv[0] == '+')
2837 break;
2838 remap_image=GetImageCache(image_info,argv[1],exception);
2839 if (remap_image == (Image *) NULL)
2840 break;
2841 (void) RemapImage(quantize_info,*image,remap_image,exception);
2842 remap_image=DestroyImage(remap_image);
2843 break;
2844 }
2845 if (LocaleCompare("mask",argv[0]+1) == 0)
2846 {
2847 Image
2848 *mask;
2849
2850 (void) SyncImageSettings(image_info,*image);
2851 if (*argv[0] == '+')
2852 {
2853 /*
2854 Remove a mask.
2855 */
2856 (void) SetImageMask(*image,(Image *) NULL,exception);
2857 break;
2858 }
2859 /*
2860 Set the image mask.
2861 */
2862 mask=GetImageCache(image_info,argv[1],exception);
2863 if (mask == (Image *) NULL)
2864 break;
2865 (void) SetImageMask(*image,mask,exception);
2866 mask=DestroyImage(mask);
2867 break;
2868 }
2869 if (LocaleCompare("matte",argv[0]+1) == 0)
2870 {
2871 (void) SetImageAlphaChannel(*image,(*argv[0] == '-') ?
2872 SetAlphaChannel : DeactivateAlphaChannel,exception);
2873 break;
2874 }
2875 if (LocaleCompare("median",argv[0]+1) == 0)
2876 {
2877 /*
2878 Median filter image.
2879 */
2880 (void) SyncImageSettings(image_info,*image);
2881 flags=ParseGeometry(argv[1],&geometry_info);
2882 if ((flags & SigmaValue) == 0)
2883 geometry_info.sigma=geometry_info.rho;
2884 new_image=StatisticImage(*image,MedianStatistic,(size_t)
2885 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2886 break;
2887 }
2888 if (LocaleCompare("mode",argv[0]+1) == 0)
2889 {
2890 /*
2891 Mode image.
2892 */
2893 (void) SyncImageSettings(image_info,*image);
2894 flags=ParseGeometry(argv[1],&geometry_info);
2895 if ((flags & SigmaValue) == 0)
2896 geometry_info.sigma=geometry_info.rho;
2897 new_image=StatisticImage(*image,ModeStatistic,(size_t)
2898 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2899 break;
2900 }
2901 if (LocaleCompare("modulate",argv[0]+1) == 0)
2902 {
2903 (void) SyncImageSettings(image_info,*image);
2904 (void) ModulateImage(*image,argv[1],exception);
2905 break;
2906 }
2907 if (LocaleCompare("monitor",argv[0]+1) == 0)
2908 {
2909 if (*argv[0] == '+')
2910 {
2911 (void) SetImageProgressMonitor(*image,
2912 (MagickProgressMonitor) NULL,(void *) NULL);
2913 break;
2914 }
2915 (void) SetImageProgressMonitor(*image,MonitorProgress,
2916 (void *) NULL);
2917 break;
2918 }
2919 if (LocaleCompare("monochrome",argv[0]+1) == 0)
2920 {
2921 (void) SyncImageSettings(image_info,*image);
2922 (void) SetImageType(*image,BilevelType,exception);
2923 break;
2924 }
2925 if (LocaleCompare("morphology",argv[0]+1) == 0)
2926 {
2927 char
2928 token[MaxTextExtent];
2929
2930 const char
2931 *p;
2932
2933 KernelInfo
2934 *kernel;
2935
2936 MorphologyMethod
2937 method;
2938
2939 ssize_t
2940 iterations;
2941
2942 /*
2943 Morphological Image Operation
2944 */
2945 (void) SyncImageSettings(image_info,*image);
2946 p=argv[1];
2947 GetMagickToken(p,&p,token);
2948 method=(MorphologyMethod) ParseCommandOption(
2949 MagickMorphologyOptions,MagickFalse,token);
2950 iterations=1L;
2951 GetMagickToken(p,&p,token);
2952 if ((*p == ':') || (*p == ','))
2953 GetMagickToken(p,&p,token);
2954 if ((*p != '\0'))
2955 iterations=(ssize_t) StringToLong(p);
2956 kernel=AcquireKernelInfo(argv[2]);
2957 if (kernel == (KernelInfo *) NULL)
2958 {
2959 (void) ThrowMagickException(exception,GetMagickModule(),
2960 OptionError,"UnabletoParseKernel","morphology");
2961 status=MagickFalse;
2962 break;
2963 }
2964 new_image=MorphologyImage(*image,method,iterations,kernel,
2965 exception);
2966 kernel=DestroyKernelInfo(kernel);
2967 break;
2968 }
2969 if (LocaleCompare("motion-blur",argv[0]+1) == 0)
2970 {
2971 /*
2972 Motion blur image.
2973 */
2974 (void) SyncImageSettings(image_info,*image);
2975 flags=ParseGeometry(argv[1],&geometry_info);
2976 if ((flags & SigmaValue) == 0)
2977 geometry_info.sigma=1.0;
2978 new_image=MotionBlurImage(*image,geometry_info.rho,
2979 geometry_info.sigma,geometry_info.xi,geometry_info.psi,
2980 exception);
2981 break;
2982 }
2983 break;
2984 }
2985 case 'n':
2986 {
2987 if (LocaleCompare("negate",argv[0]+1) == 0)
2988 {
2989 (void) SyncImageSettings(image_info,*image);
2990 (void) NegateImage(*image,*argv[0] == '+' ? MagickTrue :
2991 MagickFalse,exception);
2992 break;
2993 }
2994 if (LocaleCompare("noise",argv[0]+1) == 0)
2995 {
2996 (void) SyncImageSettings(image_info,*image);
2997 if (*argv[0] == '-')
2998 {
2999 flags=ParseGeometry(argv[1],&geometry_info);
3000 if ((flags & SigmaValue) == 0)
3001 geometry_info.sigma=geometry_info.rho;
3002 new_image=StatisticImage(*image,NonpeakStatistic,(size_t)
3003 geometry_info.rho,(size_t) geometry_info.sigma,exception);
3004 }
3005 else
3006 {
3007 NoiseType
3008 noise;
3009
3010 noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
3011 MagickFalse,argv[1]);
3012 new_image=AddNoiseImage(*image,noise,exception);
3013 }
3014 break;
3015 }
3016 if (LocaleCompare("normalize",argv[0]+1) == 0)
3017 {
3018 (void) SyncImageSettings(image_info,*image);
3019 (void) NormalizeImage(*image,exception);
3020 break;
3021 }
3022 break;
3023 }
3024 case 'o':
3025 {
3026 if (LocaleCompare("opaque",argv[0]+1) == 0)
3027 {
3028 PixelInfo
3029 target;
3030
3031 (void) SyncImageSettings(image_info,*image);
anthonya89dd172011-10-04 13:29:35 +00003032 (void) QueryMagickColorCompliance(argv[1],AllCompliance,&target,
3033 exception);
anthony805a2d42011-09-25 08:25:12 +00003034 (void) OpaquePaintImage(*image,&target,&fill,*argv[0] == '-' ?
3035 MagickFalse : MagickTrue,exception);
3036 break;
3037 }
3038 if (LocaleCompare("ordered-dither",argv[0]+1) == 0)
3039 {
3040 (void) SyncImageSettings(image_info,*image);
3041 (void) OrderedPosterizeImage(*image,argv[1],exception);
3042 break;
3043 }
3044 break;
3045 }
3046 case 'p':
3047 {
3048 if (LocaleCompare("paint",argv[0]+1) == 0)
3049 {
3050 (void) SyncImageSettings(image_info,*image);
3051 (void) ParseGeometry(argv[1],&geometry_info);
3052 new_image=OilPaintImage(*image,geometry_info.rho,
3053 geometry_info.sigma,exception);
3054 break;
3055 }
3056 if (LocaleCompare("pen",argv[0]+1) == 0)
3057 {
3058 if (*argv[0] == '+')
3059 {
anthony1afdc7a2011-10-05 11:54:28 +00003060 (void) QueryColorCompliance("none",AllCompliance,&draw_info->fill,
anthonya89dd172011-10-04 13:29:35 +00003061 exception);
anthony805a2d42011-09-25 08:25:12 +00003062 break;
3063 }
anthony1afdc7a2011-10-05 11:54:28 +00003064 (void) QueryColorCompliance(argv[1],AllCompliance,&draw_info->fill,
anthonya89dd172011-10-04 13:29:35 +00003065 exception);
anthony805a2d42011-09-25 08:25:12 +00003066 break;
3067 }
3068 if (LocaleCompare("pointsize",argv[0]+1) == 0)
3069 {
3070 if (*argv[0] == '+')
3071 (void) ParseGeometry("12",&geometry_info);
3072 else
3073 (void) ParseGeometry(argv[1],&geometry_info);
3074 draw_info->pointsize=geometry_info.rho;
3075 break;
3076 }
3077 if (LocaleCompare("polaroid",argv[0]+1) == 0)
3078 {
3079 double
3080 angle;
3081
3082 RandomInfo
3083 *random_info;
3084
3085 /*
3086 Simulate a Polaroid picture.
3087 */
3088 (void) SyncImageSettings(image_info,*image);
3089 random_info=AcquireRandomInfo();
3090 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
3091 random_info=DestroyRandomInfo(random_info);
3092 if (*argv[0] == '-')
3093 {
3094 SetGeometryInfo(&geometry_info);
3095 flags=ParseGeometry(argv[1],&geometry_info);
3096 angle=geometry_info.rho;
3097 }
3098 new_image=PolaroidImage(*image,draw_info,angle,
3099 interpolate_method,exception);
3100 break;
3101 }
3102 if (LocaleCompare("posterize",argv[0]+1) == 0)
3103 {
3104 /*
3105 Posterize image.
3106 */
3107 (void) SyncImageSettings(image_info,*image);
3108 (void) PosterizeImage(*image,StringToUnsignedLong(argv[1]),
3109 quantize_info->dither,exception);
3110 break;
3111 }
3112 if (LocaleCompare("preview",argv[0]+1) == 0)
3113 {
3114 PreviewType
3115 preview_type;
3116
3117 /*
3118 Preview image.
3119 */
3120 (void) SyncImageSettings(image_info,*image);
3121 if (*argv[0] == '+')
3122 preview_type=UndefinedPreview;
3123 else
3124 preview_type=(PreviewType) ParseCommandOption(
3125 MagickPreviewOptions,MagickFalse,argv[1]);
3126 new_image=PreviewImage(*image,preview_type,exception);
3127 break;
3128 }
3129 if (LocaleCompare("profile",argv[0]+1) == 0)
3130 {
3131 const char
3132 *name;
3133
3134 const StringInfo
3135 *profile;
3136
3137 Image
3138 *profile_image;
3139
3140 ImageInfo
3141 *profile_info;
3142
3143 (void) SyncImageSettings(image_info,*image);
3144 if (*argv[0] == '+')
3145 {
3146 /*
3147 Remove a profile from the image.
3148 */
3149 (void) ProfileImage(*image,argv[1],(const unsigned char *)
3150 NULL,0,MagickTrue);
3151 InheritException(exception,&(*image)->exception);
3152 break;
3153 }
3154 /*
3155 Associate a profile with the image.
3156 */
3157 profile_info=CloneImageInfo(image_info);
3158 profile=GetImageProfile(*image,"iptc");
3159 if (profile != (StringInfo *) NULL)
3160 profile_info->profile=(void *) CloneStringInfo(profile);
3161 profile_image=GetImageCache(profile_info,argv[1],exception);
3162 profile_info=DestroyImageInfo(profile_info);
3163 if (profile_image == (Image *) NULL)
3164 {
3165 StringInfo
3166 *profile;
3167
3168 profile_info=CloneImageInfo(image_info);
3169 (void) CopyMagickString(profile_info->filename,argv[1],
3170 MaxTextExtent);
3171 profile=FileToStringInfo(profile_info->filename,~0UL,exception);
3172 if (profile != (StringInfo *) NULL)
3173 {
3174 (void) ProfileImage(*image,profile_info->magick,
3175 GetStringInfoDatum(profile),(size_t)
3176 GetStringInfoLength(profile),MagickFalse);
3177 profile=DestroyStringInfo(profile);
3178 }
3179 profile_info=DestroyImageInfo(profile_info);
3180 break;
3181 }
3182 ResetImageProfileIterator(profile_image);
3183 name=GetNextImageProfile(profile_image);
3184 while (name != (const char *) NULL)
3185 {
3186 profile=GetImageProfile(profile_image,name);
3187 if (profile != (StringInfo *) NULL)
3188 (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
3189 (size_t) GetStringInfoLength(profile),MagickFalse);
3190 name=GetNextImageProfile(profile_image);
3191 }
3192 profile_image=DestroyImage(profile_image);
3193 break;
3194 }
3195 break;
3196 }
3197 case 'q':
3198 {
3199 if (LocaleCompare("quantize",argv[0]+1) == 0)
3200 {
3201 if (*argv[0] == '+')
3202 {
3203 quantize_info->colorspace=UndefinedColorspace;
3204 break;
3205 }
3206 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
3207 MagickColorspaceOptions,MagickFalse,argv[1]);
3208 break;
3209 }
3210 break;
3211 }
3212 case 'r':
3213 {
3214 if (LocaleCompare("radial-blur",argv[0]+1) == 0)
3215 {
3216 /*
3217 Radial blur image.
3218 */
3219 (void) SyncImageSettings(image_info,*image);
3220 flags=ParseGeometry(argv[1],&geometry_info);
3221 new_image=RadialBlurImage(*image,geometry_info.rho,
3222 geometry_info.sigma,exception);
3223 break;
3224 }
3225 if (LocaleCompare("raise",argv[0]+1) == 0)
3226 {
3227 /*
3228 Surround image with a raise of solid color.
3229 */
3230 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3231 if ((flags & SigmaValue) == 0)
3232 geometry.height=geometry.width;
3233 (void) RaiseImage(*image,&geometry,*argv[0] == '-' ? MagickTrue :
3234 MagickFalse,exception);
3235 break;
3236 }
3237 if (LocaleCompare("random-threshold",argv[0]+1) == 0)
3238 {
3239 /*
3240 Threshold image.
3241 */
3242 (void) SyncImageSettings(image_info,*image);
3243 (void) RandomThresholdImage(*image,argv[1],exception);
3244 break;
3245 }
3246 if (LocaleCompare("recolor",argv[0]+1) == 0)
3247 {
3248 KernelInfo
3249 *kernel;
3250
3251 (void) SyncImageSettings(image_info,*image);
3252 kernel=AcquireKernelInfo(argv[1]);
3253 if (kernel == (KernelInfo *) NULL)
3254 break;
3255 new_image=ColorMatrixImage(*image,kernel,exception);
3256 kernel=DestroyKernelInfo(kernel);
3257 break;
3258 }
3259 if (LocaleCompare("render",argv[0]+1) == 0)
3260 {
3261 (void) SyncImageSettings(image_info,*image);
3262 draw_info->render=(*argv[0] == '+') ? MagickTrue : MagickFalse;
3263 break;
3264 }
3265 if (LocaleCompare("remap",argv[0]+1) == 0)
3266 {
3267 Image
3268 *remap_image;
3269
3270 /*
3271 Transform image colors to match this set of colors.
3272 */
3273 (void) SyncImageSettings(image_info,*image);
3274 if (*argv[0] == '+')
3275 break;
3276 remap_image=GetImageCache(image_info,argv[1],exception);
3277 if (remap_image == (Image *) NULL)
3278 break;
3279 (void) RemapImage(quantize_info,*image,remap_image,exception);
3280 remap_image=DestroyImage(remap_image);
3281 break;
3282 }
3283 if (LocaleCompare("repage",argv[0]+1) == 0)
3284 {
3285 if (*argv[0] == '+')
3286 {
3287 (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
3288 break;
3289 }
3290 (void) ResetImagePage(*image,argv[1]);
3291 InheritException(exception,&(*image)->exception);
3292 break;
3293 }
3294 if (LocaleCompare("resample",argv[0]+1) == 0)
3295 {
3296 /*
3297 Resample image.
3298 */
3299 (void) SyncImageSettings(image_info,*image);
3300 flags=ParseGeometry(argv[1],&geometry_info);
3301 if ((flags & SigmaValue) == 0)
3302 geometry_info.sigma=geometry_info.rho;
3303 new_image=ResampleImage(*image,geometry_info.rho,
3304 geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
3305 break;
3306 }
3307 if (LocaleCompare("resize",argv[0]+1) == 0)
3308 {
3309 /*
3310 Resize image.
3311 */
3312 (void) SyncImageSettings(image_info,*image);
3313 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3314 new_image=ResizeImage(*image,geometry.width,geometry.height,
3315 (*image)->filter,(*image)->blur,exception);
3316 break;
3317 }
3318 if (LocaleCompare("roll",argv[0]+1) == 0)
3319 {
3320 /*
3321 Roll image.
3322 */
3323 (void) SyncImageSettings(image_info,*image);
3324 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
3325 new_image=RollImage(*image,geometry.x,geometry.y,exception);
3326 break;
3327 }
3328 if (LocaleCompare("rotate",argv[0]+1) == 0)
3329 {
3330 char
3331 *geometry;
3332
3333 /*
3334 Check for conditional image rotation.
3335 */
3336 (void) SyncImageSettings(image_info,*image);
3337 if (strchr(argv[1],'>') != (char *) NULL)
3338 if ((*image)->columns <= (*image)->rows)
3339 break;
3340 if (strchr(argv[1],'<') != (char *) NULL)
3341 if ((*image)->columns >= (*image)->rows)
3342 break;
3343 /*
3344 Rotate image.
3345 */
3346 geometry=ConstantString(argv[1]);
3347 (void) SubstituteString(&geometry,">","");
3348 (void) SubstituteString(&geometry,"<","");
3349 (void) ParseGeometry(geometry,&geometry_info);
3350 geometry=DestroyString(geometry);
3351 new_image=RotateImage(*image,geometry_info.rho,exception);
3352 break;
3353 }
3354 break;
3355 }
3356 case 's':
3357 {
3358 if (LocaleCompare("sample",argv[0]+1) == 0)
3359 {
3360 /*
3361 Sample image with pixel replication.
3362 */
3363 (void) SyncImageSettings(image_info,*image);
3364 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3365 new_image=SampleImage(*image,geometry.width,geometry.height,
3366 exception);
3367 break;
3368 }
3369 if (LocaleCompare("scale",argv[0]+1) == 0)
3370 {
3371 /*
3372 Resize image.
3373 */
3374 (void) SyncImageSettings(image_info,*image);
3375 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3376 new_image=ScaleImage(*image,geometry.width,geometry.height,
3377 exception);
3378 break;
3379 }
3380 if (LocaleCompare("selective-blur",argv[0]+1) == 0)
3381 {
3382 /*
3383 Selectively blur pixels within a contrast threshold.
3384 */
3385 (void) SyncImageSettings(image_info,*image);
3386 flags=ParseGeometry(argv[1],&geometry_info);
3387 if ((flags & PercentValue) != 0)
3388 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3389 new_image=SelectiveBlurImage(*image,geometry_info.rho,
3390 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3391 break;
3392 }
3393 if (LocaleCompare("separate",argv[0]+1) == 0)
3394 {
3395 /*
3396 Break channels into separate images.
3397 WARNING: This can generate multiple images!
3398 */
3399 (void) SyncImageSettings(image_info,*image);
3400 new_image=SeparateImages(*image,exception);
3401 break;
3402 }
3403 if (LocaleCompare("sepia-tone",argv[0]+1) == 0)
3404 {
3405 double
3406 threshold;
3407
3408 /*
3409 Sepia-tone image.
3410 */
3411 (void) SyncImageSettings(image_info,*image);
3412 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3413 new_image=SepiaToneImage(*image,threshold,exception);
3414 break;
3415 }
3416 if (LocaleCompare("segment",argv[0]+1) == 0)
3417 {
3418 /*
3419 Segment image.
3420 */
3421 (void) SyncImageSettings(image_info,*image);
3422 flags=ParseGeometry(argv[1],&geometry_info);
3423 if ((flags & SigmaValue) == 0)
3424 geometry_info.sigma=1.0;
3425 (void) SegmentImage(*image,(*image)->colorspace,
3426 image_info->verbose,geometry_info.rho,geometry_info.sigma,
3427 exception);
3428 break;
3429 }
3430 if (LocaleCompare("set",argv[0]+1) == 0)
3431 {
3432 char
3433 *value;
3434
anthony805a2d42011-09-25 08:25:12 +00003435 if (*argv[0] == '+')
3436 {
3437 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3438 (void) DeleteImageRegistry(argv[1]+9);
3439 else
3440 if (LocaleNCompare(argv[1],"argv[0]:",7) == 0)
3441 {
3442 (void) DeleteImageOption(image_info,argv[1]+7);
3443 (void) DeleteImageArtifact(*image,argv[1]+7);
3444 }
3445 else
3446 (void) DeleteImageProperty(*image,argv[1]);
3447 break;
3448 }
3449 value=InterpretImageProperties(image_info,*image,argv[2],
3450 exception);
3451 if (value == (char *) NULL)
3452 break;
3453 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3454 (void) SetImageRegistry(StringRegistryType,argv[1]+9,value,
3455 exception);
3456 else
anthonya89dd172011-10-04 13:29:35 +00003457 if (LocaleNCompare(argv[1],"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003458 {
3459 (void) SetImageOption(image_info,argv[1]+7,value);
anthony805a2d42011-09-25 08:25:12 +00003460 (void) SetImageArtifact(*image,argv[1]+7,value);
3461 }
3462 else
3463 (void) SetImageProperty(*image,argv[1],value);
3464 value=DestroyString(value);
3465 break;
3466 }
3467 if (LocaleCompare("shade",argv[0]+1) == 0)
3468 {
3469 /*
3470 Shade image.
3471 */
3472 (void) SyncImageSettings(image_info,*image);
3473 flags=ParseGeometry(argv[1],&geometry_info);
3474 if ((flags & SigmaValue) == 0)
3475 geometry_info.sigma=1.0;
3476 new_image=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue :
3477 MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
3478 break;
3479 }
3480 if (LocaleCompare("shadow",argv[0]+1) == 0)
3481 {
3482 /*
3483 Shadow image.
3484 */
3485 (void) SyncImageSettings(image_info,*image);
3486 flags=ParseGeometry(argv[1],&geometry_info);
3487 if ((flags & SigmaValue) == 0)
3488 geometry_info.sigma=1.0;
3489 if ((flags & XiValue) == 0)
3490 geometry_info.xi=4.0;
3491 if ((flags & PsiValue) == 0)
3492 geometry_info.psi=4.0;
3493 new_image=ShadowImage(*image,geometry_info.rho,
3494 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3495 ceil(geometry_info.psi-0.5),exception);
3496 break;
3497 }
3498 if (LocaleCompare("sharpen",argv[0]+1) == 0)
3499 {
3500 /*
3501 Sharpen image.
3502 */
3503 (void) SyncImageSettings(image_info,*image);
3504 flags=ParseGeometry(argv[1],&geometry_info);
3505 if ((flags & SigmaValue) == 0)
3506 geometry_info.sigma=1.0;
3507 if ((flags & XiValue) == 0)
3508 geometry_info.xi=0.0;
3509 new_image=SharpenImage(*image,geometry_info.rho,
3510 geometry_info.sigma,geometry_info.xi,exception);
3511 break;
3512 }
3513 if (LocaleCompare("shave",argv[0]+1) == 0)
3514 {
3515 /*
3516 Shave the image edges.
3517 */
3518 (void) SyncImageSettings(image_info,*image);
3519 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3520 new_image=ShaveImage(*image,&geometry,exception);
3521 break;
3522 }
3523 if (LocaleCompare("shear",argv[0]+1) == 0)
3524 {
3525 /*
3526 Shear image.
3527 */
3528 (void) SyncImageSettings(image_info,*image);
3529 flags=ParseGeometry(argv[1],&geometry_info);
3530 if ((flags & SigmaValue) == 0)
3531 geometry_info.sigma=geometry_info.rho;
3532 new_image=ShearImage(*image,geometry_info.rho,
3533 geometry_info.sigma,exception);
3534 break;
3535 }
3536 if (LocaleCompare("sigmoidal-contrast",argv[0]+1) == 0)
3537 {
3538 /*
3539 Sigmoidal non-linearity contrast control.
3540 */
3541 (void) SyncImageSettings(image_info,*image);
3542 flags=ParseGeometry(argv[1],&geometry_info);
3543 if ((flags & SigmaValue) == 0)
3544 geometry_info.sigma=(double) QuantumRange/2.0;
3545 if ((flags & PercentValue) != 0)
3546 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3547 100.0;
3548 (void) SigmoidalContrastImage(*image,(*argv[0] == '-') ?
3549 MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
3550 exception);
3551 break;
3552 }
3553 if (LocaleCompare("sketch",argv[0]+1) == 0)
3554 {
3555 /*
3556 Sketch image.
3557 */
3558 (void) SyncImageSettings(image_info,*image);
3559 flags=ParseGeometry(argv[1],&geometry_info);
3560 if ((flags & SigmaValue) == 0)
3561 geometry_info.sigma=1.0;
3562 new_image=SketchImage(*image,geometry_info.rho,
3563 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3564 break;
3565 }
3566 if (LocaleCompare("solarize",argv[0]+1) == 0)
3567 {
3568 double
3569 threshold;
3570
3571 (void) SyncImageSettings(image_info,*image);
3572 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3573 (void) SolarizeImage(*image,threshold,exception);
3574 break;
3575 }
3576 if (LocaleCompare("sparse-color",argv[0]+1) == 0)
3577 {
3578 SparseColorMethod
3579 method;
3580
3581 char
3582 *arguments;
3583
3584 /*
3585 Sparse Color Interpolated Gradient
3586 */
3587 (void) SyncImageSettings(image_info,*image);
3588 method=(SparseColorMethod) ParseCommandOption(
3589 MagickSparseColorOptions,MagickFalse,argv[1]);
3590 arguments=InterpretImageProperties(image_info,*image,argv[2],
3591 exception);
3592 if (arguments == (char *) NULL)
3593 break;
3594 new_image=SparseColorOption(*image,method,arguments,
3595 argv[0][0] == '+' ? MagickTrue : MagickFalse,exception);
3596 arguments=DestroyString(arguments);
3597 break;
3598 }
3599 if (LocaleCompare("splice",argv[0]+1) == 0)
3600 {
3601 /*
3602 Splice a solid color into the image.
3603 */
3604 (void) SyncImageSettings(image_info,*image);
3605 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
3606 new_image=SpliceImage(*image,&geometry,exception);
3607 break;
3608 }
3609 if (LocaleCompare("spread",argv[0]+1) == 0)
3610 {
3611 /*
3612 Spread an image.
3613 */
3614 (void) SyncImageSettings(image_info,*image);
3615 (void) ParseGeometry(argv[1],&geometry_info);
3616 new_image=SpreadImage(*image,geometry_info.rho,
3617 interpolate_method,exception);
3618 break;
3619 }
3620 if (LocaleCompare("statistic",argv[0]+1) == 0)
3621 {
3622 StatisticType
3623 type;
3624
3625 (void) SyncImageSettings(image_info,*image);
3626 type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
3627 MagickFalse,argv[1]);
3628 (void) ParseGeometry(argv[2],&geometry_info);
3629 new_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
3630 (size_t) geometry_info.sigma,exception);
3631 break;
3632 }
3633 if (LocaleCompare("stretch",argv[0]+1) == 0)
3634 {
3635 if (*argv[0] == '+')
3636 {
3637 draw_info->stretch=UndefinedStretch;
3638 break;
3639 }
3640 draw_info->stretch=(StretchType) ParseCommandOption(
3641 MagickStretchOptions,MagickFalse,argv[1]);
3642 break;
3643 }
3644 if (LocaleCompare("strip",argv[0]+1) == 0)
3645 {
3646 /*
3647 Strip image of profiles and comments.
3648 */
3649 (void) SyncImageSettings(image_info,*image);
3650 (void) StripImage(*image);
3651 InheritException(exception,&(*image)->exception);
3652 break;
3653 }
3654 if (LocaleCompare("stroke",argv[0]+1) == 0)
3655 {
3656 ExceptionInfo
3657 *sans;
3658
3659 if (*argv[0] == '+')
3660 {
anthony1afdc7a2011-10-05 11:54:28 +00003661 (void) QueryColorCompliance("none",AllCompliance,&draw_info->stroke,
anthonya89dd172011-10-04 13:29:35 +00003662 exception);
anthony805a2d42011-09-25 08:25:12 +00003663 if (draw_info->stroke_pattern != (Image *) NULL)
3664 draw_info->stroke_pattern=DestroyImage(
3665 draw_info->stroke_pattern);
3666 break;
3667 }
3668 sans=AcquireExceptionInfo();
anthony1afdc7a2011-10-05 11:54:28 +00003669 status=QueryColorCompliance(argv[1],AllCompliance,&draw_info->stroke,sans);
anthony805a2d42011-09-25 08:25:12 +00003670 sans=DestroyExceptionInfo(sans);
3671 if (status == MagickFalse)
3672 draw_info->stroke_pattern=GetImageCache(image_info,argv[1],
3673 exception);
3674 break;
3675 }
3676 if (LocaleCompare("strokewidth",argv[0]+1) == 0)
3677 {
3678 draw_info->stroke_width=InterpretLocaleValue(argv[1],
3679 (char **) NULL);
3680 break;
3681 }
3682 if (LocaleCompare("style",argv[0]+1) == 0)
3683 {
3684 if (*argv[0] == '+')
3685 {
3686 draw_info->style=UndefinedStyle;
3687 break;
3688 }
3689 draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
3690 MagickFalse,argv[1]);
3691 break;
3692 }
3693 if (LocaleCompare("swirl",argv[0]+1) == 0)
3694 {
3695 /*
3696 Swirl image.
3697 */
3698 (void) SyncImageSettings(image_info,*image);
3699 (void) ParseGeometry(argv[1],&geometry_info);
3700 new_image=SwirlImage(*image,geometry_info.rho,
3701 interpolate_method,exception);
3702 break;
3703 }
3704 break;
3705 }
3706 case 't':
3707 {
3708 if (LocaleCompare("threshold",argv[0]+1) == 0)
3709 {
3710 double
3711 threshold;
3712
3713 /*
3714 Threshold image.
3715 */
3716 (void) SyncImageSettings(image_info,*image);
3717 if (*argv[0] == '+')
3718 threshold=(double) QuantumRange/2;
3719 else
3720 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3721 (void) BilevelImage(*image,threshold);
3722 InheritException(exception,&(*image)->exception);
3723 break;
3724 }
3725 if (LocaleCompare("thumbnail",argv[0]+1) == 0)
3726 {
3727 /*
3728 Thumbnail image.
3729 */
3730 (void) SyncImageSettings(image_info,*image);
3731 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3732 new_image=ThumbnailImage(*image,geometry.width,geometry.height,
3733 exception);
3734 break;
3735 }
3736 if (LocaleCompare("tile",argv[0]+1) == 0)
3737 {
3738 if (*argv[0] == '+')
3739 {
3740 if (draw_info->fill_pattern != (Image *) NULL)
3741 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
3742 break;
3743 }
3744 draw_info->fill_pattern=GetImageCache(image_info,argv[1],
3745 exception);
3746 break;
3747 }
3748 if (LocaleCompare("tint",argv[0]+1) == 0)
3749 {
3750 /*
3751 Tint the image.
3752 */
3753 (void) SyncImageSettings(image_info,*image);
3754 new_image=TintImage(*image,argv[1],&fill,exception);
3755 break;
3756 }
3757 if (LocaleCompare("transform",argv[0]+1) == 0)
3758 {
3759 /*
3760 Affine transform image.
3761 */
3762 (void) SyncImageSettings(image_info,*image);
3763 new_image=AffineTransformImage(*image,&draw_info->affine,
3764 exception);
3765 break;
3766 }
3767 if (LocaleCompare("transparent",argv[0]+1) == 0)
3768 {
3769 PixelInfo
3770 target;
3771
3772 (void) SyncImageSettings(image_info,*image);
anthonya89dd172011-10-04 13:29:35 +00003773 (void) QueryMagickColorCompliance(argv[1],AllCompliance,&target,
3774 exception);
anthony805a2d42011-09-25 08:25:12 +00003775 (void) TransparentPaintImage(*image,&target,(Quantum)
3776 TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue,
3777 &(*image)->exception);
3778 break;
3779 }
3780 if (LocaleCompare("transpose",argv[0]+1) == 0)
3781 {
3782 /*
3783 Transpose image scanlines.
3784 */
3785 (void) SyncImageSettings(image_info,*image);
3786 new_image=TransposeImage(*image,exception);
3787 break;
3788 }
3789 if (LocaleCompare("transverse",argv[0]+1) == 0)
3790 {
3791 /*
3792 Transverse image scanlines.
3793 */
3794 (void) SyncImageSettings(image_info,*image);
3795 new_image=TransverseImage(*image,exception);
3796 break;
3797 }
3798 if (LocaleCompare("treedepth",argv[0]+1) == 0)
3799 {
3800 quantize_info->tree_depth=StringToUnsignedLong(argv[1]);
3801 break;
3802 }
3803 if (LocaleCompare("trim",argv[0]+1) == 0)
3804 {
3805 /*
3806 Trim image.
3807 */
3808 (void) SyncImageSettings(image_info,*image);
3809 new_image=TrimImage(*image,exception);
3810 break;
3811 }
3812 if (LocaleCompare("type",argv[0]+1) == 0)
3813 {
3814 ImageType
3815 type;
3816
3817 (void) SyncImageSettings(image_info,*image);
3818 if (*argv[0] == '+')
3819 type=UndefinedType;
3820 else
3821 type=(ImageType) ParseCommandOption(MagickTypeOptions,MagickFalse,
3822 argv[1]);
3823 (*image)->type=UndefinedType;
3824 (void) SetImageType(*image,type,exception);
3825 break;
3826 }
3827 break;
3828 }
3829 case 'u':
3830 {
3831 if (LocaleCompare("undercolor",argv[0]+1) == 0)
3832 {
anthony1afdc7a2011-10-05 11:54:28 +00003833 (void) QueryColorCompliance(argv[1],AllCompliance,&draw_info->undercolor,
anthony805a2d42011-09-25 08:25:12 +00003834 exception);
3835 break;
3836 }
3837 if (LocaleCompare("unique",argv[0]+1) == 0)
3838 {
3839 if (*argv[0] == '+')
3840 {
3841 (void) DeleteImageArtifact(*image,"identify:unique-colors");
3842 break;
3843 }
3844 (void) SetImageArtifact(*image,"identify:unique-colors","true");
3845 (void) SetImageArtifact(*image,"verbose","true");
3846 break;
3847 }
3848 if (LocaleCompare("unique-colors",argv[0]+1) == 0)
3849 {
3850 /*
3851 Unique image colors.
3852 */
3853 (void) SyncImageSettings(image_info,*image);
3854 new_image=UniqueImageColors(*image,exception);
3855 break;
3856 }
3857 if (LocaleCompare("unsharp",argv[0]+1) == 0)
3858 {
3859 /*
3860 Unsharp mask image.
3861 */
3862 (void) SyncImageSettings(image_info,*image);
3863 flags=ParseGeometry(argv[1],&geometry_info);
3864 if ((flags & SigmaValue) == 0)
3865 geometry_info.sigma=1.0;
3866 if ((flags & XiValue) == 0)
3867 geometry_info.xi=1.0;
3868 if ((flags & PsiValue) == 0)
3869 geometry_info.psi=0.05;
3870 new_image=UnsharpMaskImage(*image,geometry_info.rho,
3871 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3872 break;
3873 }
3874 break;
3875 }
3876 case 'v':
3877 {
3878 if (LocaleCompare("verbose",argv[0]+1) == 0)
3879 {
3880 (void) SetImageArtifact(*image,argv[0]+1,
3881 *argv[0] == '+' ? "false" : "true");
3882 break;
3883 }
3884 if (LocaleCompare("vignette",argv[0]+1) == 0)
3885 {
3886 /*
3887 Vignette image.
3888 */
3889 (void) SyncImageSettings(image_info,*image);
3890 flags=ParseGeometry(argv[1],&geometry_info);
3891 if ((flags & SigmaValue) == 0)
3892 geometry_info.sigma=1.0;
3893 if ((flags & XiValue) == 0)
3894 geometry_info.xi=0.1*(*image)->columns;
3895 if ((flags & PsiValue) == 0)
3896 geometry_info.psi=0.1*(*image)->rows;
3897 new_image=VignetteImage(*image,geometry_info.rho,
3898 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3899 ceil(geometry_info.psi-0.5),exception);
3900 break;
3901 }
3902 if (LocaleCompare("virtual-pixel",argv[0]+1) == 0)
3903 {
3904 if (*argv[0] == '+')
3905 {
3906 (void) SetImageVirtualPixelMethod(*image,
3907 UndefinedVirtualPixelMethod);
3908 break;
3909 }
3910 (void) SetImageVirtualPixelMethod(*image,(VirtualPixelMethod)
3911 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
3912 argv[1]));
3913 break;
3914 }
3915 break;
3916 }
3917 case 'w':
3918 {
3919 if (LocaleCompare("wave",argv[0]+1) == 0)
3920 {
3921 /*
3922 Wave image.
3923 */
3924 (void) SyncImageSettings(image_info,*image);
3925 flags=ParseGeometry(argv[1],&geometry_info);
3926 if ((flags & SigmaValue) == 0)
3927 geometry_info.sigma=1.0;
3928 new_image=WaveImage(*image,geometry_info.rho,
anthonya89dd172011-10-04 13:29:35 +00003929 geometry_info.sigma,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003930 break;
3931 }
3932 if (LocaleCompare("weight",argv[0]+1) == 0)
3933 {
3934 draw_info->weight=StringToUnsignedLong(argv[1]);
3935 if (LocaleCompare(argv[1],"all") == 0)
3936 draw_info->weight=0;
3937 if (LocaleCompare(argv[1],"bold") == 0)
3938 draw_info->weight=700;
3939 if (LocaleCompare(argv[1],"bolder") == 0)
3940 if (draw_info->weight <= 800)
3941 draw_info->weight+=100;
3942 if (LocaleCompare(argv[1],"lighter") == 0)
3943 if (draw_info->weight >= 100)
3944 draw_info->weight-=100;
3945 if (LocaleCompare(argv[1],"normal") == 0)
3946 draw_info->weight=400;
3947 break;
3948 }
3949 if (LocaleCompare("white-threshold",argv[0]+1) == 0)
3950 {
3951 /*
3952 White threshold image.
3953 */
3954 (void) SyncImageSettings(image_info,*image);
3955 (void) WhiteThresholdImage(*image,argv[1],exception);
3956 InheritException(exception,&(*image)->exception);
3957 break;
3958 }
3959 break;
3960 }
3961 default:
3962 break;
3963 }
3964 /*
3965 Replace current image with any image that was generated
3966 */
3967 if (new_image != (Image *) NULL)
3968 ReplaceImageInListReturnLast(image,new_image);
3969
3970 /*
3971 Free resources.
3972 */
3973 quantize_info=DestroyQuantizeInfo(quantize_info);
3974 draw_info=DestroyDrawInfo(draw_info);
anthonya89dd172011-10-04 13:29:35 +00003975 status=(MagickStatusType) ((*image)->exception.severity ==
3976 UndefinedException ? 1 : 0);
3977 return(status == 0 ? MagickFalse : MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003978}
3979
3980/*
3981%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3982% %
3983% %
3984% %
3985+ S e q u e n c e O p e r a t i o n I m a g e s %
3986% %
3987% %
3988% %
3989%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3990%
3991% SequenceOperationImages() applies a single operation that apply to the
3992% entire image list (e.g. -append, -layers, -coalesce, etc.).
3993%
3994% The format of the MogrifyImage method is:
3995%
3996% MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3997% const int argc, const char **argv,Image **images,
3998% ExceptionInfo *exception)
3999%
4000% A description of each parameter follows:
4001%
4002% o image_info: the image info..
4003%
4004% o argc: Specifies a pointer to an integer describing the number of
4005% elements in the argument vector.
4006%
4007% o argv: Specifies a pointer to a text array containing the command line
4008% arguments.
4009%
4010% o images: pointer to pointer of the first image in image list.
4011%
4012% o exception: return any errors or warnings in this structure.
4013%
4014*/
4015WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
4016 const int argc,const char **argv,Image **images,ExceptionInfo *exception)
4017{
4018
4019 MagickStatusType
4020 status;
4021
4022 QuantizeInfo
4023 *quantize_info;
4024
4025 assert(image_info != (ImageInfo *) NULL);
4026 assert(image_info->signature == MagickSignature);
4027 assert(images != (Image **) NULL);
4028 assert((*images)->previous == (Image *) NULL);
4029 assert((*images)->signature == MagickSignature);
4030 if ((*images)->debug != MagickFalse)
4031 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
4032 (*images)->filename);
anthonya89dd172011-10-04 13:29:35 +00004033 if ((argc <= 0) || (*argv == (char *) NULL))
4034 return(MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00004035 status=MagickTrue;
4036
4037 switch (*(argv[0]+1))
4038 {
4039 case 'a':
4040 {
4041 if (LocaleCompare("affinity",argv[0]+1) == 0)
4042 {
4043 (void) SyncImagesSettings(image_info,*images);
4044 if (*argv[0] == '+')
4045 {
4046 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4047 exception);
4048 break;
4049 }
4050 break;
4051 }
4052 if (LocaleCompare("append",argv[0]+1) == 0)
4053 {
4054 Image
4055 *append_image;
4056
4057 (void) SyncImagesSettings(image_info,*images);
4058 append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue :
4059 MagickFalse,exception);
4060 if (append_image == (Image *) NULL)
4061 {
4062 status=MagickFalse;
4063 break;
4064 }
4065 *images=DestroyImageList(*images);
4066 *images=append_image;
4067 break;
4068 }
4069 if (LocaleCompare("average",argv[0]+1) == 0)
4070 {
4071 Image
4072 *average_image;
4073
4074 /*
4075 Average an image sequence (deprecated).
4076 */
4077 (void) SyncImagesSettings(image_info,*images);
4078 average_image=EvaluateImages(*images,MeanEvaluateOperator,
4079 exception);
4080 if (average_image == (Image *) NULL)
4081 {
4082 status=MagickFalse;
4083 break;
4084 }
4085 *images=DestroyImageList(*images);
4086 *images=average_image;
4087 break;
4088 }
4089 break;
4090 }
4091 case 'c':
4092 {
4093 if (LocaleCompare("channel",argv[0]+1) == 0)
4094 {
4095 ChannelType
4096 channel;
4097
4098 if (*argv[0] == '+')
4099 {
4100 channel=DefaultChannels;
4101 break;
4102 }
4103 channel=(ChannelType) ParseChannelOption(argv[1]);
4104 SetPixelChannelMap(*images,channel);
4105 break;
4106 }
4107 if (LocaleCompare("clut",argv[0]+1) == 0)
4108 {
4109 Image
4110 *clut_image,
4111 *image;
4112
4113 (void) SyncImagesSettings(image_info,*images);
4114 image=RemoveFirstImageFromList(images);
4115 clut_image=RemoveFirstImageFromList(images);
4116 if (clut_image == (Image *) NULL)
4117 {
4118 status=MagickFalse;
4119 break;
4120 }
anthonya89dd172011-10-04 13:29:35 +00004121 (void) ClutImage(image,clut_image,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00004122 clut_image=DestroyImage(clut_image);
4123 *images=DestroyImageList(*images);
4124 *images=image;
4125 break;
4126 }
4127 if (LocaleCompare("coalesce",argv[0]+1) == 0)
4128 {
4129 Image
4130 *coalesce_image;
4131
4132 (void) SyncImagesSettings(image_info,*images);
4133 coalesce_image=CoalesceImages(*images,exception);
4134 if (coalesce_image == (Image *) NULL)
4135 {
4136 status=MagickFalse;
4137 break;
4138 }
4139 *images=DestroyImageList(*images);
4140 *images=coalesce_image;
4141 break;
4142 }
4143 if (LocaleCompare("combine",argv[0]+1) == 0)
4144 {
4145 Image
4146 *combine_image;
4147
4148 (void) SyncImagesSettings(image_info,*images);
4149 combine_image=CombineImages(*images,exception);
4150 if (combine_image == (Image *) NULL)
4151 {
4152 status=MagickFalse;
4153 break;
4154 }
4155 *images=DestroyImageList(*images);
4156 *images=combine_image;
4157 break;
4158 }
4159 if (LocaleCompare("composite",argv[0]+1) == 0)
4160 {
4161 Image
4162 *mask_image,
4163 *composite_image,
4164 *image;
4165
4166 RectangleInfo
4167 geometry;
4168
4169 (void) SyncImagesSettings(image_info,*images);
4170 image=RemoveFirstImageFromList(images);
4171 composite_image=RemoveFirstImageFromList(images);
4172 if (composite_image == (Image *) NULL)
4173 {
4174 status=MagickFalse;
4175 break;
4176 }
4177 (void) TransformImage(&composite_image,(char *) NULL,
4178 composite_image->geometry);
4179 SetGeometry(composite_image,&geometry);
4180 (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
4181 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
4182 &geometry);
4183 mask_image=RemoveFirstImageFromList(images);
4184 if (mask_image != (Image *) NULL)
4185 {
4186 if ((image->compose == DisplaceCompositeOp) ||
4187 (image->compose == DistortCompositeOp))
4188 {
4189 /*
4190 Merge Y displacement into X displacement image.
4191 */
4192 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
4193 mask_image,0,0);
4194 mask_image=DestroyImage(mask_image);
4195 }
4196 else
4197 {
4198 /*
4199 Set a blending mask for the composition.
4200 Posible error, what if image->mask already set.
4201 */
4202 image->mask=mask_image;
4203 (void) NegateImage(image->mask,MagickFalse,exception);
4204 }
4205 }
4206 (void) CompositeImage(image,image->compose,composite_image,
4207 geometry.x,geometry.y);
4208 if (mask_image != (Image *) NULL)
4209 mask_image=image->mask=DestroyImage(image->mask);
4210 composite_image=DestroyImage(composite_image);
4211 InheritException(exception,&image->exception);
4212 *images=DestroyImageList(*images);
4213 *images=image;
4214 break;
4215 }
4216 break;
4217 }
4218 case 'd':
4219 {
4220 if (LocaleCompare("deconstruct",argv[0]+1) == 0)
4221 {
4222 Image
4223 *deconstruct_image;
4224
4225 (void) SyncImagesSettings(image_info,*images);
4226 deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
4227 exception);
4228 if (deconstruct_image == (Image *) NULL)
4229 {
4230 status=MagickFalse;
4231 break;
4232 }
4233 *images=DestroyImageList(*images);
4234 *images=deconstruct_image;
4235 break;
4236 }
4237 if (LocaleCompare("delete",argv[0]+1) == 0)
4238 {
4239 if (*argv[0] == '+')
4240 DeleteImages(images,"-1",exception);
4241 else
4242 DeleteImages(images,argv[1],exception);
4243 break;
4244 }
4245 if (LocaleCompare("dither",argv[0]+1) == 0)
4246 {
4247 if (*argv[0] == '+')
4248 {
4249 quantize_info->dither=MagickFalse;
4250 break;
4251 }
4252 quantize_info->dither=MagickTrue;
4253 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
4254 MagickDitherOptions,MagickFalse,argv[1]);
4255 break;
4256 }
4257 if (LocaleCompare("duplicate",argv[0]+1) == 0)
4258 {
4259 Image
4260 *duplicate_images;
4261
4262 if (*argv[0] == '+')
4263 duplicate_images=DuplicateImages(*images,1,"-1",exception);
4264 else
4265 {
4266 const char
4267 *p;
4268
4269 size_t
4270 number_duplicates;
4271
4272 number_duplicates=(size_t) StringToLong(argv[1]);
4273 p=strchr(argv[1],',');
4274 if (p == (const char *) NULL)
4275 duplicate_images=DuplicateImages(*images,number_duplicates,
4276 "-1",exception);
4277 else
4278 duplicate_images=DuplicateImages(*images,number_duplicates,p,
4279 exception);
4280 }
4281 AppendImageToList(images, duplicate_images);
4282 (void) SyncImagesSettings(image_info,*images);
4283 break;
4284 }
4285 break;
4286 }
4287 case 'e':
4288 {
4289 if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0)
4290 {
4291 Image
4292 *evaluate_image;
4293
4294 MagickEvaluateOperator
4295 op;
4296
4297 (void) SyncImageSettings(image_info,*images);
4298 op=(MagickEvaluateOperator) ParseCommandOption(
4299 MagickEvaluateOptions,MagickFalse,argv[1]);
4300 evaluate_image=EvaluateImages(*images,op,exception);
4301 if (evaluate_image == (Image *) NULL)
4302 {
4303 status=MagickFalse;
4304 break;
4305 }
4306 *images=DestroyImageList(*images);
4307 *images=evaluate_image;
4308 break;
4309 }
4310 break;
4311 }
4312 case 'f':
4313 {
4314 if (LocaleCompare("fft",argv[0]+1) == 0)
4315 {
4316 Image
4317 *fourier_image;
4318
4319 /*
4320 Implements the discrete Fourier transform (DFT).
4321 */
4322 (void) SyncImageSettings(image_info,*images);
4323 fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ?
4324 MagickTrue : MagickFalse,exception);
4325 if (fourier_image == (Image *) NULL)
4326 break;
4327 *images=DestroyImage(*images);
4328 *images=fourier_image;
4329 break;
4330 }
4331 if (LocaleCompare("flatten",argv[0]+1) == 0)
4332 {
4333 Image
4334 *flatten_image;
4335
4336 (void) SyncImagesSettings(image_info,*images);
4337 flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
4338 if (flatten_image == (Image *) NULL)
4339 break;
4340 *images=DestroyImageList(*images);
4341 *images=flatten_image;
4342 break;
4343 }
4344 if (LocaleCompare("fx",argv[0]+1) == 0)
4345 {
4346 Image
4347 *fx_image;
4348
4349 (void) SyncImagesSettings(image_info,*images);
4350 fx_image=FxImage(*images,argv[1],exception);
4351 if (fx_image == (Image *) NULL)
4352 {
4353 status=MagickFalse;
4354 break;
4355 }
4356 *images=DestroyImageList(*images);
4357 *images=fx_image;
4358 break;
4359 }
4360 break;
4361 }
4362 case 'h':
4363 {
4364 if (LocaleCompare("hald-clut",argv[0]+1) == 0)
4365 {
4366 Image
4367 *hald_image,
4368 *image;
4369
4370 (void) SyncImagesSettings(image_info,*images);
4371 image=RemoveFirstImageFromList(images);
4372 hald_image=RemoveFirstImageFromList(images);
4373 if (hald_image == (Image *) NULL)
4374 {
4375 status=MagickFalse;
4376 break;
4377 }
4378 (void) HaldClutImage(image,hald_image,exception);
4379 hald_image=DestroyImage(hald_image);
4380 if (*images != (Image *) NULL)
4381 *images=DestroyImageList(*images);
4382 *images=image;
4383 break;
4384 }
4385 break;
4386 }
4387 case 'i':
4388 {
4389 if (LocaleCompare("ift",argv[0]+1) == 0)
4390 {
4391 Image
4392 *fourier_image,
4393 *magnitude_image,
4394 *phase_image;
4395
4396 /*
4397 Implements the inverse fourier discrete Fourier transform (DFT).
4398 */
4399 (void) SyncImagesSettings(image_info,*images);
4400 magnitude_image=RemoveFirstImageFromList(images);
4401 phase_image=RemoveFirstImageFromList(images);
4402 if (phase_image == (Image *) NULL)
4403 {
4404 status=MagickFalse;
4405 break;
4406 }
4407 fourier_image=InverseFourierTransformImage(magnitude_image,
4408 phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception);
4409 if (fourier_image == (Image *) NULL)
4410 break;
4411 if (*images != (Image *) NULL)
4412 *images=DestroyImage(*images);
4413 *images=fourier_image;
4414 break;
4415 }
4416 if (LocaleCompare("insert",argv[0]+1) == 0)
4417 {
4418 Image
4419 *p,
4420 *q;
4421
4422 index=0;
4423 if (*argv[0] != '+')
4424 index=(ssize_t) StringToLong(argv[1]);
4425 p=RemoveLastImageFromList(images);
4426 if (p == (Image *) NULL)
4427 {
4428 (void) ThrowMagickException(exception,GetMagickModule(),
4429 OptionError,"NoSuchImage","`%s'",argv[1]);
4430 status=MagickFalse;
4431 break;
4432 }
4433 q=p;
4434 if (index == 0)
4435 PrependImageToList(images,q);
4436 else
4437 if (index == (ssize_t) GetImageListLength(*images))
4438 AppendImageToList(images,q);
4439 else
4440 {
4441 q=GetImageFromList(*images,index-1);
4442 if (q == (Image *) NULL)
4443 {
4444 (void) ThrowMagickException(exception,GetMagickModule(),
4445 OptionError,"NoSuchImage","`%s'",argv[1]);
4446 status=MagickFalse;
4447 break;
4448 }
4449 InsertImageInList(&q,p);
4450 }
4451 *images=GetFirstImageInList(q);
4452 break;
4453 }
4454 if (LocaleCompare("interpolate",argv[0]+1) == 0)
4455 {
4456 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
4457 MagickInterpolateOptions,MagickFalse,argv[1]);
4458 break;
4459 }
4460 break;
4461 }
4462 case 'l':
4463 {
4464 if (LocaleCompare("layers",argv[0]+1) == 0)
4465 {
4466 Image
4467 *layers;
4468
4469 ImageLayerMethod
4470 method;
4471
4472 (void) SyncImagesSettings(image_info,*images);
4473 layers=(Image *) NULL;
4474 method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
4475 MagickFalse,argv[1]);
4476 switch (method)
4477 {
4478 case CoalesceLayer:
4479 {
4480 layers=CoalesceImages(*images,exception);
4481 break;
4482 }
4483 case CompareAnyLayer:
4484 case CompareClearLayer:
4485 case CompareOverlayLayer:
4486 default:
4487 {
4488 layers=CompareImagesLayers(*images,method,exception);
4489 break;
4490 }
4491 case MergeLayer:
4492 case FlattenLayer:
4493 case MosaicLayer:
4494 case TrimBoundsLayer:
4495 {
4496 layers=MergeImageLayers(*images,method,exception);
4497 break;
4498 }
4499 case DisposeLayer:
4500 {
4501 layers=DisposeImages(*images,exception);
4502 break;
4503 }
4504 case OptimizeImageLayer:
4505 {
4506 layers=OptimizeImageLayers(*images,exception);
4507 break;
4508 }
4509 case OptimizePlusLayer:
4510 {
4511 layers=OptimizePlusImageLayers(*images,exception);
4512 break;
4513 }
4514 case OptimizeTransLayer:
4515 {
4516 OptimizeImageTransparency(*images,exception);
4517 break;
4518 }
4519 case RemoveDupsLayer:
4520 {
4521 RemoveDuplicateLayers(images,exception);
4522 break;
4523 }
4524 case RemoveZeroLayer:
4525 {
4526 RemoveZeroDelayLayers(images,exception);
4527 break;
4528 }
4529 case OptimizeLayer:
4530 {
4531 /*
4532 General Purpose, GIF Animation Optimizer.
4533 */
4534 layers=CoalesceImages(*images,exception);
4535 if (layers == (Image *) NULL)
4536 {
4537 status=MagickFalse;
4538 break;
4539 }
4540 *images=DestroyImageList(*images);
4541 *images=layers;
4542 layers=OptimizeImageLayers(*images,exception);
4543 if (layers == (Image *) NULL)
4544 {
4545 status=MagickFalse;
4546 break;
4547 }
4548 *images=DestroyImageList(*images);
4549 *images=layers;
4550 layers=(Image *) NULL;
4551 OptimizeImageTransparency(*images,exception);
4552 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4553 exception);
4554 break;
4555 }
4556 case CompositeLayer:
4557 {
4558 CompositeOperator
4559 compose;
4560
4561 Image
4562 *source;
4563
4564 RectangleInfo
4565 geometry;
4566
4567 /*
4568 Split image sequence at the first 'NULL:' image.
4569 */
4570 source=(*images);
4571 while (source != (Image *) NULL)
4572 {
4573 source=GetNextImageInList(source);
4574 if ((source != (Image *) NULL) &&
4575 (LocaleCompare(source->magick,"NULL") == 0))
4576 break;
4577 }
4578 if (source != (Image *) NULL)
4579 {
4580 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4581 (GetNextImageInList(source) == (Image *) NULL))
4582 source=(Image *) NULL;
4583 else
4584 {
4585 /*
4586 Separate the two lists, junk the null: image.
4587 */
4588 source=SplitImageList(source->previous);
4589 DeleteImageFromList(&source);
4590 }
4591 }
4592 if (source == (Image *) NULL)
4593 {
4594 (void) ThrowMagickException(exception,GetMagickModule(),
4595 OptionError,"MissingNullSeparator","layers Composite");
4596 status=MagickFalse;
4597 break;
4598 }
4599 /*
4600 Adjust offset with gravity and virtual canvas.
4601 */
4602 SetGeometry(*images,&geometry);
4603 (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
4604 geometry.width=source->page.width != 0 ?
4605 source->page.width : source->columns;
4606 geometry.height=source->page.height != 0 ?
4607 source->page.height : source->rows;
4608 GravityAdjustGeometry((*images)->page.width != 0 ?
4609 (*images)->page.width : (*images)->columns,
4610 (*images)->page.height != 0 ? (*images)->page.height :
4611 (*images)->rows,(*images)->gravity,&geometry);
4612 compose=OverCompositeOp;
4613 argv[0]=GetImageOption(image_info,"compose");
4614 if (argv[0] != (const char *) NULL)
4615 compose=(CompositeOperator) ParseCommandOption(
4616 MagickComposeOptions,MagickFalse,argv[0]);
4617 CompositeLayers(*images,compose,source,geometry.x,geometry.y,
4618 exception);
4619 source=DestroyImageList(source);
4620 break;
4621 }
4622 }
4623 if (layers == (Image *) NULL)
4624 break;
4625 InheritException(exception,&layers->exception);
4626 *images=DestroyImageList(*images);
4627 *images=layers;
4628 break;
4629 }
4630 break;
4631 }
4632 case 'm':
4633 {
4634 if (LocaleCompare("map",argv[0]+1) == 0)
4635 {
4636 (void) SyncImagesSettings(image_info,*images);
4637 if (*argv[0] == '+')
4638 {
4639 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4640 exception);
4641 break;
4642 }
4643 break;
4644 }
4645 if (LocaleCompare("maximum",argv[0]+1) == 0)
4646 {
4647 Image
4648 *maximum_image;
4649
4650 /*
4651 Maximum image sequence (deprecated).
4652 */
4653 (void) SyncImagesSettings(image_info,*images);
4654 maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
4655 if (maximum_image == (Image *) NULL)
4656 {
4657 status=MagickFalse;
4658 break;
4659 }
4660 *images=DestroyImageList(*images);
4661 *images=maximum_image;
4662 break;
4663 }
4664 if (LocaleCompare("minimum",argv[0]+1) == 0)
4665 {
4666 Image
4667 *minimum_image;
4668
4669 /*
4670 Minimum image sequence (deprecated).
4671 */
4672 (void) SyncImagesSettings(image_info,*images);
4673 minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
4674 if (minimum_image == (Image *) NULL)
4675 {
4676 status=MagickFalse;
4677 break;
4678 }
4679 *images=DestroyImageList(*images);
4680 *images=minimum_image;
4681 break;
4682 }
4683 if (LocaleCompare("morph",argv[0]+1) == 0)
4684 {
4685 Image
4686 *morph_image;
4687
4688 (void) SyncImagesSettings(image_info,*images);
4689 morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]),
4690 exception);
4691 if (morph_image == (Image *) NULL)
4692 {
4693 status=MagickFalse;
4694 break;
4695 }
4696 *images=DestroyImageList(*images);
4697 *images=morph_image;
4698 break;
4699 }
4700 if (LocaleCompare("mosaic",argv[0]+1) == 0)
4701 {
4702 Image
4703 *mosaic_image;
4704
4705 (void) SyncImagesSettings(image_info,*images);
4706 mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
4707 if (mosaic_image == (Image *) NULL)
4708 {
4709 status=MagickFalse;
4710 break;
4711 }
4712 *images=DestroyImageList(*images);
4713 *images=mosaic_image;
4714 break;
4715 }
4716 break;
4717 }
4718 case 'p':
4719 {
4720 if (LocaleCompare("print",argv[0]+1) == 0)
4721 {
4722 char
4723 *string;
4724
4725 (void) SyncImagesSettings(image_info,*images);
4726 string=InterpretImageProperties(image_info,*images,argv[1],
4727 exception);
4728 if (string == (char *) NULL)
4729 break;
4730 (void) FormatLocaleFile(stdout,"%s",string);
4731 string=DestroyString(string);
4732 }
4733 if (LocaleCompare("process",argv[0]+1) == 0)
4734 {
4735 char
4736 **arguments;
4737
4738 int
4739 j,
4740 number_arguments;
4741
4742 (void) SyncImagesSettings(image_info,*images);
4743 arguments=StringToArgv(argv[1],&number_arguments);
4744 if (arguments == (char **) NULL)
4745 break;
4746 if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
4747 {
4748 char
4749 breaker,
4750 quote,
4751 *token;
4752
4753 const char
4754 *arguments;
4755
4756 int
4757 next,
4758 status;
4759
4760 size_t
4761 length;
4762
4763 TokenInfo
4764 *token_info;
4765
4766 /*
4767 Support old style syntax, filter="-option arg".
4768 */
4769 length=strlen(argv[1]);
4770 token=(char *) NULL;
4771 if (~length >= (MaxTextExtent-1))
4772 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4773 sizeof(*token));
4774 if (token == (char *) NULL)
4775 break;
4776 next=0;
4777 arguments=argv[1];
4778 token_info=AcquireTokenInfo();
4779 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4780 "\"",'\0',&breaker,&next,&quote);
4781 token_info=DestroyTokenInfo(token_info);
4782 if (status == 0)
4783 {
4784 const char
4785 *argv;
4786
4787 argv=(&(arguments[next]));
4788 (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
4789 exception);
4790 }
4791 token=DestroyString(token);
4792 break;
4793 }
4794 (void) SubstituteString(&arguments[1],"-","");
4795 (void) InvokeDynamicImageFilter(arguments[1],&(*images),
4796 number_arguments-2,(const char **) arguments+2,exception);
4797 for (j=0; j < number_arguments; j++)
4798 arguments[j]=DestroyString(arguments[j]);
4799 arguments=(char **) RelinquishMagickMemory(arguments);
4800 break;
4801 }
4802 break;
4803 }
4804 case 'r':
4805 {
4806 if (LocaleCompare("reverse",argv[0]+1) == 0)
4807 {
4808 ReverseImageList(images);
4809 InheritException(exception,&(*images)->exception);
4810 break;
4811 }
4812 break;
4813 }
4814 case 's':
4815 {
4816 if (LocaleCompare("smush",argv[0]+1) == 0)
4817 {
4818 Image
4819 *smush_image;
4820
4821 ssize_t
4822 offset;
4823
4824 (void) SyncImagesSettings(image_info,*images);
4825 offset=(ssize_t) StringToLong(argv[1]);
4826 smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue :
4827 MagickFalse,offset,exception);
4828 if (smush_image == (Image *) NULL)
4829 {
4830 status=MagickFalse;
4831 break;
4832 }
4833 *images=DestroyImageList(*images);
4834 *images=smush_image;
4835 break;
4836 }
4837 if (LocaleCompare("swap",argv[0]+1) == 0)
4838 {
4839 Image
4840 *p,
4841 *q,
4842 *swap;
4843
4844 ssize_t
4845 swap_index;
4846
4847 index=(-1);
4848 swap_index=(-2);
4849 if (*argv[0] != '+')
4850 {
4851 GeometryInfo
4852 geometry_info;
4853
4854 MagickStatusType
4855 flags;
4856
4857 swap_index=(-1);
4858 flags=ParseGeometry(argv[1],&geometry_info);
4859 index=(ssize_t) geometry_info.rho;
4860 if ((flags & SigmaValue) != 0)
4861 swap_index=(ssize_t) geometry_info.sigma;
4862 }
4863 p=GetImageFromList(*images,index);
4864 q=GetImageFromList(*images,swap_index);
4865 if ((p == (Image *) NULL) || (q == (Image *) NULL))
4866 {
4867 (void) ThrowMagickException(exception,GetMagickModule(),
4868 OptionError,"NoSuchImage","`%s'",(*images)->filename);
4869 status=MagickFalse;
4870 break;
4871 }
4872 if (p == q)
4873 break;
4874 swap=CloneImage(p,0,0,MagickTrue,exception);
4875 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
4876 ReplaceImageInList(&q,swap);
4877 *images=GetFirstImageInList(q);
4878 break;
4879 }
4880 break;
4881 }
4882 case 'w':
4883 {
4884 if (LocaleCompare("write",argv[0]+1) == 0)
4885 {
4886 char
4887 key[MaxTextExtent];
4888
4889 Image
4890 *write_images;
4891
4892 ImageInfo
4893 *write_info;
4894
4895 (void) SyncImagesSettings(image_info,*images);
4896 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]);
4897 (void) DeleteImageRegistry(key);
4898 write_images=(*images);
4899 if (*argv[0] == '+')
4900 write_images=CloneImageList(*images,exception);
4901 write_info=CloneImageInfo(image_info);
4902 status&=WriteImages(write_info,write_images,argv[1],exception);
4903 write_info=DestroyImageInfo(write_info);
4904 if (*argv[0] == '+')
4905 write_images=DestroyImageList(write_images);
4906 break;
4907 }
4908 break;
4909 }
4910 default:
4911 break;
4912 }
4913 quantize_info=DestroyQuantizeInfo(quantize_info);
4914
anthonya89dd172011-10-04 13:29:35 +00004915 status=(MagickStatusType) ((*image)->exception.severity ==
4916 UndefinedException ? 1 : 0);
anthony805a2d42011-09-25 08:25:12 +00004917 return(status != 0 ? MagickTrue : MagickFalse);
4918}
cristy0a0ca4f2011-09-28 01:15:28 +00004919#endif