blob: 8bd5a3aa9f4ebd8e78b64e53c5b41168f81249a0 [file] [log] [blame]
anthony805a2d42011-09-25 08:25:12 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% OOO PPPP EEEE RRRR AA TTTTTT III OOO N N %
7% O O P P E R R A A TT I O O NN N %
8% O O PPPP EEE RRRR AAAA TT I O O N N N %
9% O O P E R R A A TT I O O N NN %
10% OOO P EEEE R RR A A TT III OOO N N %
11% %
12% %
13% MagickWand Module Methods %
14% %
15% Software Design %
16% John Cristy %
cristy0a0ca4f2011-09-28 01:15:28 +000017% September 2011 %
anthony805a2d42011-09-25 08:25:12 +000018% %
19% %
20% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% Apply the given options (settings, and simple, or sequence operations) to
37% the given image(s) according to the current "image_info" and "draw_info"
38% settings.
39%
40% The final goal is to allow the execution in a strict one option at a time
41% manner that is needed for 'pipelining and file scripting' of options in
42% IMv7.
43%
44% Anthony Thyssen, Sept 2011
45*/
cristyc689f1f2011-10-05 21:13:24 +000046#if 0
anthony805a2d42011-09-25 08:25:12 +000047
48/*
49 Include declarations.
50*/
51#include "MagickWand/studio.h"
52#include "MagickWand/MagickWand.h"
53#include "MagickWand/mogrify-private.h"
54#include "MagickCore/monitor-private.h"
55#include "MagickCore/thread-private.h"
56#include "MagickCore/string-private.h"
57
58/*
59 Define declarations.
60*/
61#define UndefinedCompressionQuality 0UL
62/*
63 Constant declaration. (temporary exports)
64*/
65static const char
66 BackgroundColor[] = "#fff", /* white */
67 BorderColor[] = "#dfdfdf", /* gray */
68 MatteColor[] = "#bdbdbd"; /* gray */
69
70/*
71** Function to report on the progress of image operations
72*/
73static MagickBooleanType MonitorProgress(const char *text,
74 const MagickOffsetType offset,const MagickSizeType extent,
75 void *wand_unused(client_data))
76{
77 char
78 message[MaxTextExtent],
79 tag[MaxTextExtent];
80
81 const char
82 *locale_message;
83
84 register char
85 *p;
86
87 if (extent < 2)
88 return(MagickTrue);
89 (void) CopyMagickMemory(tag,text,MaxTextExtent);
90 p=strrchr(tag,'/');
91 if (p != (char *) NULL)
92 *p='\0';
93 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
94 locale_message=GetLocaleMessage(message);
95 if (locale_message == message)
96 locale_message=tag;
97 if (p == (char *) NULL)
98 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
99 locale_message,(long) offset,(unsigned long) extent,(long)
100 (100L*offset/(extent-1)));
101 else
102 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
103 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
104 (100L*offset/(extent-1)));
105 if (offset == (MagickOffsetType) (extent-1))
106 (void) FormatLocaleFile(stderr,"\n");
107 (void) fflush(stderr);
108 return(MagickTrue);
109}
110
111/*
112** GetImageCache() will read an image into a image cache if not already
113** present then return the image that is in the cache under that filename.
114*/
115static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
116 ExceptionInfo *exception)
117{
118 char
119 key[MaxTextExtent];
120
121 ExceptionInfo
122 *sans_exception;
123
124 Image
125 *image;
126
127 ImageInfo
128 *read_info;
129
130 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
131 sans_exception=AcquireExceptionInfo();
132 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
133 sans_exception=DestroyExceptionInfo(sans_exception);
134 if (image != (Image *) NULL)
135 return(image);
136 read_info=CloneImageInfo(image_info);
137 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
138 image=ReadImage(read_info,exception);
139 read_info=DestroyImageInfo(read_info);
140 if (image != (Image *) NULL)
141 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
142 return(image);
143}
144
145/*
anthonya89dd172011-10-04 13:29:35 +0000146 SparseColorOption() parse the complex -sparse-color argument into an
147 an array of floating point values than call SparseColorImage().
148 Argument is a complex mix of floating-point pixel coodinates, and color
149 specifications (or direct floating point numbers). The number of floats
150 needed to represent a color varies depending on teh current channel
151 setting.
anthony805a2d42011-09-25 08:25:12 +0000152*/
153static Image *SparseColorOption(const Image *image,
154 const SparseColorMethod method,const char *arguments,
155 const MagickBooleanType color_from_image,ExceptionInfo *exception)
156{
157 char
158 token[MaxTextExtent];
159
160 const char
161 *p;
162
163 double
164 *sparse_arguments;
165
166 Image
167 *sparse_image;
168
169 PixelInfo
170 color;
171
172 MagickBooleanType
173 error;
174
175 register size_t
176 x;
177
178 size_t
179 number_arguments,
180 number_colors;
181
182 assert(image != (Image *) NULL);
183 assert(image->signature == MagickSignature);
184 if (image->debug != MagickFalse)
185 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
186 assert(exception != (ExceptionInfo *) NULL);
187 assert(exception->signature == MagickSignature);
188 /*
189 Limit channels according to image - and add up number of color channel.
190 */
191 number_colors=0;
192 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
193 number_colors++;
194 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
195 number_colors++;
196 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
197 number_colors++;
198 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
199 (image->colorspace == CMYKColorspace))
200 number_colors++;
201 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
202 (image->matte != MagickFalse))
203 number_colors++;
204
205 /*
206 Read string, to determine number of arguments needed,
207 */
208 p=arguments;
209 x=0;
210 while( *p != '\0' )
211 {
212 GetMagickToken(p,&p,token);
213 if ( token[0] == ',' ) continue;
214 if ( isalpha((int) token[0]) || token[0] == '#' ) {
215 if ( color_from_image ) {
216 (void) ThrowMagickException(exception,GetMagickModule(),
217 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
218 "Color arg given, when colors are coming from image");
219 return( (Image *)NULL);
220 }
221 x += number_colors; /* color argument */
222 }
223 else {
224 x++; /* floating point argument */
225 }
226 }
227 error=MagickTrue;
228 if ( color_from_image ) {
229 /* just the control points are being given */
230 error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse;
231 number_arguments=(x/2)*(2+number_colors);
232 }
233 else {
234 /* control points and color values */
235 error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
236 number_arguments=x;
237 }
238 if ( error ) {
239 (void) ThrowMagickException(exception,GetMagickModule(),
240 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
241 "Invalid number of Arguments");
242 return( (Image *)NULL);
243 }
244
245 /* Allocate and fill in the floating point arguments */
246 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
247 sizeof(*sparse_arguments));
248 if (sparse_arguments == (double *) NULL) {
249 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
250 "MemoryAllocationFailed","%s","SparseColorOption");
251 return( (Image *)NULL);
252 }
253 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
254 sizeof(*sparse_arguments));
255 p=arguments;
256 x=0;
257 while( *p != '\0' && x < number_arguments ) {
258 /* X coordinate */
259 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
260 if ( token[0] == '\0' ) break;
261 if ( isalpha((int) token[0]) || token[0] == '#' ) {
262 (void) ThrowMagickException(exception,GetMagickModule(),
263 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
264 "Color found, instead of X-coord");
265 error = MagickTrue;
266 break;
267 }
268 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
269 /* Y coordinate */
270 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
271 if ( token[0] == '\0' ) break;
272 if ( isalpha((int) token[0]) || token[0] == '#' ) {
273 (void) ThrowMagickException(exception,GetMagickModule(),
274 OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
275 "Color found, instead of Y-coord");
276 error = MagickTrue;
277 break;
278 }
279 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
280 /* color values for this control point */
281#if 0
282 if ( (color_from_image ) {
283 /* get color from image */
284 /* HOW??? */
285 }
286 else
287#endif
288 {
289 /* color name or function given in string argument */
290 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
291 if ( token[0] == '\0' ) break;
292 if ( isalpha((int) token[0]) || token[0] == '#' ) {
293 /* Color string given */
cristy269c9412011-10-13 23:41:15 +0000294 (void) QueryColorCompliance(token,AllCompliance,&color,
anthonya89dd172011-10-04 13:29:35 +0000295 exception);
anthony805a2d42011-09-25 08:25:12 +0000296 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
297 sparse_arguments[x++] = QuantumScale*color.red;
298 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
299 sparse_arguments[x++] = QuantumScale*color.green;
300 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
301 sparse_arguments[x++] = QuantumScale*color.blue;
302 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
303 (image->colorspace == CMYKColorspace))
304 sparse_arguments[x++] = QuantumScale*color.black;
305 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
306 (image->matte != MagickFalse))
307 sparse_arguments[x++] = QuantumScale*color.alpha;
308 }
309 else {
310 /* Colors given as a set of floating point values - experimental */
311 /* NB: token contains the first floating point value to use! */
312 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
313 {
314 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
315 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
316 break;
317 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
318 token[0] = ','; /* used this token - get another */
319 }
320 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
321 {
322 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
323 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
324 break;
325 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
326 token[0] = ','; /* used this token - get another */
327 }
328 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
329 {
330 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
331 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
332 break;
333 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
334 token[0] = ','; /* used this token - get another */
335 }
336 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
337 (image->colorspace == CMYKColorspace))
338 {
339 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
340 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
341 break;
342 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
343 token[0] = ','; /* used this token - get another */
344 }
345 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
346 (image->matte != MagickFalse))
347 {
348 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
349 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
350 break;
351 sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
352 token[0] = ','; /* used this token - get another */
353 }
354 }
355 }
356 }
357 if ( number_arguments != x && !error ) {
358 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
359 "InvalidArgument","`%s': %s","sparse-color","Argument Parsing Error");
360 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
361 return( (Image *)NULL);
362 }
363 if ( error )
364 return( (Image *)NULL);
365
366 /* Call the Interpolation function with the parsed arguments */
367 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
368 exception);
369 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
370 return( sparse_image );
371}
372
373/*
374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375% %
376% %
377% %
anthony1afdc7a2011-10-05 11:54:28 +0000378+ A p p l y S e t t i n g O p t i o n %
anthony805a2d42011-09-25 08:25:12 +0000379% %
380% %
381% %
382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
383%
anthony1afdc7a2011-10-05 11:54:28 +0000384% ApplySettingOption() saves the given single settings option into a CLI wand
385% holding the image_info, draw_info, quantize_info structures that is later
386% used for reading, processing, and writing images.
anthony805a2d42011-09-25 08:25:12 +0000387%
anthony1afdc7a2011-10-05 11:54:28 +0000388% No image in the wand is actually modified (setting options only)
anthony805a2d42011-09-25 08:25:12 +0000389%
anthony1afdc7a2011-10-05 11:54:28 +0000390% The format of the ApplySettingOption method is:
391%
392% MagickBooleanType ApplySettingOption(MagickWand *wand,
anthony805a2d42011-09-25 08:25:12 +0000393% const int argc, const char **argv,ExceptionInfo *exception)
394%
395% A description of each parameter follows:
396%
anthony1afdc7a2011-10-05 11:54:28 +0000397% o wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +0000398%
399% o argc: Specifies a pointer to an integer describing the number of
400% elements in the argument vector.
401%
402% o argv: Specifies a pointer to a text array containing the command line
403% arguments.
404%
405% o exception: return any errors or warnings in this structure.
406%
407*/
anthony74b1cfc2011-10-06 12:44:16 +0000408WandExport MagickBooleanType ApplySettingsOption(ImageInfo *image_info,
cristy0a0ca4f2011-09-28 01:15:28 +0000409 const int argc,const char **argv,ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000410{
411 GeometryInfo
412 geometry_info;
413
anthony1afdc7a2011-10-05 11:54:28 +0000414 ImageInfo
415 *image_info;
416
417 DrawInfo
anthony74b1cfc2011-10-06 12:44:16 +0000418 *draw_info;
419
420 const char
421 *option;
anthony1afdc7a2011-10-05 11:54:28 +0000422
423 assert(wand != (MagickWand *) NULL);
424 assert(wand->signature == WandSignature);
425 assert(wand->draw_info != (DrawInfo *) NULL); /* ensure it is a CLI wand */
426 assert(wand->quantize_info == (QuantizeInfo *) NULL);
427 if (wand->debug != MagickFalse)
428 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
anthony805a2d42011-09-25 08:25:12 +0000429 if (argc < 0)
430 return(MagickTrue);
anthony1afdc7a2011-10-05 11:54:28 +0000431
anthony74b1cfc2011-10-06 12:44:16 +0000432 option=argv[0]+1;
anthony1afdc7a2011-10-05 11:54:28 +0000433 image_info=wand->image_info;
434 draw_info=wand->_info;
435
anthony74b1cfc2011-10-06 12:44:16 +0000436#define IfSetOption ((*argv[0])=='-')
437
438 switch (*option)
anthony805a2d42011-09-25 08:25:12 +0000439 {
440 case 'a':
441 {
anthony74b1cfc2011-10-06 12:44:16 +0000442 if (LocaleCompare("adjoin",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000443 {
anthony74b1cfc2011-10-06 12:44:16 +0000444 image_info->adjoin = IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000445 break;
446 }
anthony74b1cfc2011-10-06 12:44:16 +0000447 if (LocaleCompare("affine",option) == 0)
anthony1afdc7a2011-10-05 11:54:28 +0000448 {
anthony74b1cfc2011-10-06 12:44:16 +0000449 if (IfSetOption)
anthony1afdc7a2011-10-05 11:54:28 +0000450 (void) ParseAffineGeometry(argv[1],draw_info->affine,
451 exception);
anthony74b1cfc2011-10-06 12:44:16 +0000452 else
453 GetAffineMatrix(draw_info->affine);
anthony1afdc7a2011-10-05 11:54:28 +0000454 break;
455 }
anthony74b1cfc2011-10-06 12:44:16 +0000456 if (LocaleCompare("antialias",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000457 {
anthony1afdc7a2011-10-05 11:54:28 +0000458 image_info->antialias =
459 draw_info->stroke_antialias =
460 draw_info->text_antialias =
anthony74b1cfc2011-10-06 12:44:16 +0000461 IfSetOption ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000462 break;
463 }
anthony74b1cfc2011-10-06 12:44:16 +0000464 if (LocaleCompare("authenticate",option) == 0)
anthony5f867ae2011-10-09 10:28:34 +0000465 {
anthony74b1cfc2011-10-06 12:44:16 +0000466 (void) SetImageOption(image_info,option,
anthony6dc09cd2011-10-12 08:56:49 +0000467 IfSetOption ? argv[1] : (const char*)NULL);
anthony805a2d42011-09-25 08:25:12 +0000468 break;
469 }
470 break;
471 }
472 case 'b':
473 {
anthony74b1cfc2011-10-06 12:44:16 +0000474 if (LocaleCompare("background",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000475 {
anthony74b1cfc2011-10-06 12:44:16 +0000476 /* FUTURE: both image_info attribute & ImageOption in use!
477 Note that +background, means fall-back to image attribute
478 so ImageOption is deleted, not set to a default.
479 */
480 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000481 {
anthony74b1cfc2011-10-06 12:44:16 +0000482 (void) DeleteImageOption(image_info,option);
anthony1afdc7a2011-10-05 11:54:28 +0000483 (void) QueryColorCompliance(BackgroundColor,AllCompliance,
anthony74b1cfc2011-10-06 12:44:16 +0000484 image_info->background_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000485 break;
486 }
anthony74b1cfc2011-10-06 12:44:16 +0000487 (void) SetImageOption(image_info,option,argv[1]);
anthony1afdc7a2011-10-05 11:54:28 +0000488 (void) QueryColorCompliance(argv[1],AllCompliance,
anthony74b1cfc2011-10-06 12:44:16 +0000489 image_info->background_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000490 break;
491 }
anthony74b1cfc2011-10-06 12:44:16 +0000492 if (LocaleCompare("bias",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000493 {
anthony74b1cfc2011-10-06 12:44:16 +0000494 /* FUTURE: bias OBSOLETED, replaced by "convolve:bias"
495 as it is actually rarely used except in direct convolve
496 Usage outside direct convolve is actally non-sensible!
497 */
498 (void) SetImageOption(image_info,option,
499 IfSetOption ? argv[1] : "0");
anthony805a2d42011-09-25 08:25:12 +0000500 break;
501 }
anthony74b1cfc2011-10-06 12:44:16 +0000502 if (LocaleCompare("black-point-compensation",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000503 {
anthony74b1cfc2011-10-06 12:44:16 +0000504 (void) SetImageOption(image_info,option,
505 IfSetOption ? "true" : "false" );
anthony805a2d42011-09-25 08:25:12 +0000506 break;
507 }
anthony74b1cfc2011-10-06 12:44:16 +0000508 if (LocaleCompare("blue-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000509 {
anthony74b1cfc2011-10-06 12:44:16 +0000510 (void) SetImageOption(image_info,option,
511 IfSetOption ? argv[1] : "0" );
anthony805a2d42011-09-25 08:25:12 +0000512 break;
513 }
anthony74b1cfc2011-10-06 12:44:16 +0000514 if (LocaleCompare("bordercolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000515 {
anthony74b1cfc2011-10-06 12:44:16 +0000516 /* FUTURE: both image_info attribute & ImageOption in use! */
517 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000518 {
anthony74b1cfc2011-10-06 12:44:16 +0000519 (void) SetImageOption(image_info,option,argv[1]);
520 (void) QueryColorCompliance(argv[1],AllCompliece,
521 &image_info->border_color,exception);
522 (void) QueryColorCompliance(argv[1],AllCompliance,
523 &draw_info->border_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000524 break;
525 }
anthony74b1cfc2011-10-06 12:44:16 +0000526 (void) DeleteImageOption(image_info,option);
527 (void) QueryColorCompliance(BorderColor,AllCompliance,
528 &image_info->border_color,exception);
529 (void) QueryColorCompliance(BorderColor,AllCompliance,
530 &draw_info->border_color,exception);
anthony805a2d42011-09-25 08:25:12 +0000531 break;
532 }
anthony74b1cfc2011-10-06 12:44:16 +0000533 if (LocaleCompare("box",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000534 {
anthony74b1cfc2011-10-06 12:44:16 +0000535 const char
536 *value = IfSetOption ? argv[1] : "none";
537 (void) SetImageOption(image_info,option,value);
538 (void) QueryColorCompliance(value,AllCompliance,
539 &draw_info->undercolor,exception);
anthony805a2d42011-09-25 08:25:12 +0000540 break;
541 }
542 break;
543 }
544 case 'c':
545 {
anthony74b1cfc2011-10-06 12:44:16 +0000546 if (LocaleCompare("cache",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000547 {
548 MagickSizeType
549 limit;
550
551 limit=MagickResourceInfinity;
552 if (LocaleCompare("unlimited",argv[1]) != 0)
553 limit=(MagickSizeType) SiPrefixToDouble(argv[1],100.0);
554 (void) SetMagickResourceLimit(MemoryResource,limit);
555 (void) SetMagickResourceLimit(MapResource,2*limit);
556 break;
557 }
anthony74b1cfc2011-10-06 12:44:16 +0000558 if (LocaleCompare("caption",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000559 {
anthony74b1cfc2011-10-06 12:44:16 +0000560 (void) SetImageOption(image_info,option,
anthony6dc09cd2011-10-12 08:56:49 +0000561 IfSetOption ? argv[1] : (const char*)NULL);
anthony805a2d42011-09-25 08:25:12 +0000562 break;
563 }
anthony74b1cfc2011-10-06 12:44:16 +0000564 if (LocaleCompare("channel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000565 {
anthony74b1cfc2011-10-06 12:44:16 +0000566 image_info->channel=(ChannelType) (
567 IfSetOption ? ParseChannelOption(argv[1]) : DefaultChannels );
cristy947cb4c2011-10-20 18:41:46 +0000568 /* This is also a SimpleImageOperator */
anthony805a2d42011-09-25 08:25:12 +0000569 break;
570 }
anthony74b1cfc2011-10-06 12:44:16 +0000571 if (LocaleCompare("colorspace",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000572 {
anthony965524b2011-10-07 12:34:14 +0000573 /* This is also a SimpleImageOperator */
anthonyd2cdc862011-10-07 14:07:17 +0000574 /* Undefined colorspace means don't modify images */
anthony965524b2011-10-07 12:34:14 +0000575 image_info->colorspace=UndefinedColorspace;
anthonyd2cdc862011-10-07 14:07:17 +0000576 if (IfSetOption)
577 image_info->colorspace=(ColorspaceType) ParseCommandOption(
578 MagickColorspaceOptions,MagickFalse,argv[1])
anthony805a2d42011-09-25 08:25:12 +0000579 break;
580 }
anthony74b1cfc2011-10-06 12:44:16 +0000581 if (LocaleCompare("comment",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000582 {
anthony965524b2011-10-07 12:34:14 +0000583 (void) SetImageOption(image_info,option,
anthony6dc09cd2011-10-12 08:56:49 +0000584 IfSetOption ? argv[1] : (const char*)NULL);
anthony805a2d42011-09-25 08:25:12 +0000585 break;
586 }
anthony74b1cfc2011-10-06 12:44:16 +0000587 if (LocaleCompare("compose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000588 {
cristy947cb4c2011-10-20 18:41:46 +0000589 /* FUTURE: What should be used? image_info or ImageOption ???
590 The former is more efficent, but Crisy prefers the latter!
anthony965524b2011-10-07 12:34:14 +0000591 */
anthony5f867ae2011-10-09 10:28:34 +0000592 (void) SetImageOption(image_info,option,
anthony6dc09cd2011-10-12 08:56:49 +0000593 IfSetOption ? argv[1] : (const char*)NULL);
anthony965524b2011-10-07 12:34:14 +0000594 image_info->compose=(CompositeOperator) ParseCommandOption(
anthony5f867ae2011-10-09 10:28:34 +0000595 MagickComposeOptions,MagickFalse,
596 IfSetOption ? argv[1] : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000597 break;
598 }
anthony74b1cfc2011-10-06 12:44:16 +0000599 if (LocaleCompare("compress",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000600 {
anthony5f867ae2011-10-09 10:28:34 +0000601 /* FUTURE: What should be used? image_info or ImageOption ???
602 The former is more efficent, but Crisy prefers the latter!
603
604 The coders appears to use image_info, not Image_Option
605 however the image attribute (for save) is set from the
606 ImageOption!
607 */
608 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000609 {
anthony5f867ae2011-10-09 10:28:34 +0000610 image_info->compression=(CompressionType) ParseCommandOption(
611 MagickCompressOptions,MagickFalse,argv[1]);
612 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000613 break;
614 }
anthony5f867ae2011-10-09 10:28:34 +0000615 image_info->compression=UndefinedCompression;
616 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +0000617 break;
618 }
619 break;
620 }
621 case 'd':
622 {
anthony74b1cfc2011-10-06 12:44:16 +0000623 if (LocaleCompare("debug",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000624 {
anthony5f867ae2011-10-09 10:28:34 +0000625 if (IfSetOption)
626 (void) SetLogEventMask(IfSetOption?argv[1]:"none");
627 image_info->debug=IsEventLogging(); /* extract logging*/
628 wand->debug=IsEventLogging();
anthony805a2d42011-09-25 08:25:12 +0000629 break;
630 }
anthony74b1cfc2011-10-06 12:44:16 +0000631 if (LocaleCompare("define",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000632 {
anthony5f867ae2011-10-09 10:28:34 +0000633 /* FUTURE both -set and -define sets ImageOption
634 But differs in that -set tried to set image properity (attribute)
635 */
anthony805a2d42011-09-25 08:25:12 +0000636 if (LocaleNCompare(argv[1],"registry:",9) == 0)
637 {
anthony5f867ae2011-10-09 10:28:34 +0000638 if (IfSetOption)
639 (void) DefineImageRegistry(StringRegistryType,argv[1]+9,
640 exception);
641 else
cristyd15e6592011-10-15 00:13:06 +0000642 (void) DefineImageOption(image_info,argv[1],exception);
anthony805a2d42011-09-25 08:25:12 +0000643 break;
644 }
anthony5f867ae2011-10-09 10:28:34 +0000645 if (IfSetOption)
cristyd15e6592011-10-15 00:13:06 +0000646 (void) DefineImageOption(image_info,argv[1],exception);
anthony5f867ae2011-10-09 10:28:34 +0000647 else
cristyd15e6592011-10-15 00:13:06 +0000648 (void) DeleteImageOption(image_info,argv[1],exception);
anthony805a2d42011-09-25 08:25:12 +0000649 break;
650 }
anthony74b1cfc2011-10-06 12:44:16 +0000651 if (LocaleCompare("delay",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000652 {
cristy947cb4c2011-10-20 18:41:46 +0000653 /* transfered to new images only via AcquireImage()
654 -set delay must be used to set attributes directly.
anthony5f867ae2011-10-09 10:28:34 +0000655 */
656 (void) SetImageOption(image_info,option,
657 IfSetOption ? argv[1] : "0");
anthony805a2d42011-09-25 08:25:12 +0000658 break;
659 }
anthony74b1cfc2011-10-06 12:44:16 +0000660 if (LocaleCompare("density",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000661 {
cristy947cb4c2011-10-20 18:41:46 +0000662 /* FUTURE: At this time everyone is using image_info string
663 The Image Option is not being used.
664 */
665 if (IsSetOption)
anthony805a2d42011-09-25 08:25:12 +0000666 {
anthony5f867ae2011-10-09 10:28:34 +0000667 (void) CloneString(&image_info->density,argv[1]);
668 (void) CloneString(&draw_info->density,argv[1]);
669 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000670 break;
671 }
anthony5f867ae2011-10-09 10:28:34 +0000672 if (image_info->density != (char *) NULL)
673 image_info->density=DestroyString(image_info->density);
674 if (draw_info->density != (char *) NULL)
675 draw_info->density=DestroyString(draw_info->density);
676 (void) SetImageOption(image_info,option,"72");
anthony805a2d42011-09-25 08:25:12 +0000677 break;
678 }
anthony74b1cfc2011-10-06 12:44:16 +0000679 if (LocaleCompare("depth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000680 {
anthony5f867ae2011-10-09 10:28:34 +0000681 /* This is also a SimpleImageOperator! */
682 image_info->depth=IsSetOption?StringToUnsignedLong(argv[1])
683 :MAGICKCORE_QUANTUM_DEPTH;
anthony805a2d42011-09-25 08:25:12 +0000684 break;
685 }
anthony74b1cfc2011-10-06 12:44:16 +0000686 if (LocaleCompare("direction",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000687 {
anthony6dc09cd2011-10-12 08:56:49 +0000688 /* Image Option is only used to set draw_info */
anthony5f867ae2011-10-09 10:28:34 +0000689 (void) SetImageOption(image_info,option,
690 IfSetOption ? argv[1] : "undefined");
691 draw_info->direction=(DirectionType) ParseCommandOption(
692 MagickDirectionOptions,MagickFalse,
693 IfSetOption ? argv[1] : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000694 break;
695 }
anthony74b1cfc2011-10-06 12:44:16 +0000696 if (LocaleCompare("display",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000697 {
anthony5f867ae2011-10-09 10:28:34 +0000698 if (IfSetOption)
699 (void) CloneString(&image_info->server_name,argv[1]);
700 else
701 if (image_info->server_name != (char *) NULL)
702 image_info->server_name=DestroyString(image_info->server_name);
anthony805a2d42011-09-25 08:25:12 +0000703 break;
704 }
anthony74b1cfc2011-10-06 12:44:16 +0000705 if (LocaleCompare("dispose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000706 {
anthony5f867ae2011-10-09 10:28:34 +0000707 (void) SetImageOption(image_info,option,
708 IfSetOption ? argv[1] : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000709 break;
710 }
anthony74b1cfc2011-10-06 12:44:16 +0000711 if (LocaleCompare("dither",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000712 {
anthony5f867ae2011-10-09 10:28:34 +0000713 /* FUTURE: Merge boolean image_info->dither with Dither type */
714 (void) SetImageOption(image_info,option,
715 IfSetOption ? argv[1] : "none");
716 image_info->dither = quantize_info->dither =
anthony6dc09cd2011-10-12 08:56:49 +0000717 IfSetOption ? MagickTrue : MagickFalse;
anthony5f867ae2011-10-09 10:28:34 +0000718 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
anthony6dc09cd2011-10-12 08:56:49 +0000719 MagickDitherOptions,MagickFalse,
720 IfSetOption ? argv[1] : "none");
anthony5f867ae2011-10-09 10:28:34 +0000721 if (quantize_info->dither_method == NoDitherMethod)
anthony6dc09cd2011-10-12 08:56:49 +0000722 image_info->dither = quantize_info->dither = MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000723 break;
724 }
725 break;
726 }
727 case 'e':
728 {
anthony74b1cfc2011-10-06 12:44:16 +0000729 if (LocaleCompare("encoding",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000730 {
anthony6dc09cd2011-10-12 08:56:49 +0000731 (void) CloneString(&draw_info->encoding,
732 IfSetOption ? argv[1] : "undefined");
733 (void) SetImageOption(image_info,option,&draw_info->encoding);
anthony805a2d42011-09-25 08:25:12 +0000734 break;
735 }
anthony74b1cfc2011-10-06 12:44:16 +0000736 if (LocaleCompare("endian",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000737 {
anthony6dc09cd2011-10-12 08:56:49 +0000738 const char
739 value;
740
741 value=IfSetOption?argv[1]:"undefined";
742 (void) SetImageOption(image_info,option,value);
anthony805a2d42011-09-25 08:25:12 +0000743 image_info->endian=(EndianType) ParseCommandOption(
anthony6dc09cd2011-10-12 08:56:49 +0000744 MagickEndianOptions,MagickFalse,value);
anthony805a2d42011-09-25 08:25:12 +0000745 break;
746 }
anthony74b1cfc2011-10-06 12:44:16 +0000747 if (LocaleCompare("extract",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000748 {
anthony6dc09cd2011-10-12 08:56:49 +0000749 (void) CloneString(&image_info->extract,
750 IfSetOption?argv[1]:(const char *) NULL);
anthony805a2d42011-09-25 08:25:12 +0000751 break;
752 }
753 break;
754 }
755 case 'f':
756 {
anthony6dc09cd2011-10-12 08:56:49 +0000757 if (LocaleCompare("family",argv[0]+1) == 0)
758 {
759 (void) CloneString(&draw_info->family,
760 IfSetOption ? argv[1] : (const char *) NULL);
761 break;
762 }
anthony74b1cfc2011-10-06 12:44:16 +0000763 if (LocaleCompare("fill",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000764 {
anthony6dc09cd2011-10-12 08:56:49 +0000765 const char
766 value;
767
768 ExceptionInfo
769 *sans;
770
771 value = IfSetOption ? argv[1] : "none";
772 (void) SetImageOption(image_info,option,value);
773
774 sans=AcquireExceptionInfo();
anthony6dc09cd2011-10-12 08:56:49 +0000775 status=QueryColorCompliance(value,AllCompliance,&draw_info->fill,sans);
776 sans=DestroyExceptionInfo(sans);
777
778 if (draw_info->fill_pattern != (Image *) NULL)
779 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
780 if (status == MagickFalse)
781 draw_info->fill_pattern=GetImageCache(image_info,value,
782 exception);
anthony805a2d42011-09-25 08:25:12 +0000783 break;
784 }
anthony74b1cfc2011-10-06 12:44:16 +0000785 if (LocaleCompare("filter",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000786 {
anthony6dc09cd2011-10-12 08:56:49 +0000787 (void) SetImageOption(image_info,option,
788 IfSetOption ? argv[1] : "undefined");
anthony805a2d42011-09-25 08:25:12 +0000789 break;
790 }
cristy947cb4c2011-10-20 18:41:46 +0000791 if (LocaleCompare("font",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000792 {
anthony6dc09cd2011-10-12 08:56:49 +0000793 (void) CloneString(&draw_info->font,
794 IfSetOption ? argv[1] : (const char *) NULL);
795 (void) CloneString(&image_info->font,draw_info->font);
anthony805a2d42011-09-25 08:25:12 +0000796 break;
797 }
anthony74b1cfc2011-10-06 12:44:16 +0000798 if (LocaleCompare("format",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000799 {
cristy947cb4c2011-10-20 18:41:46 +0000800 /* FUTURE: why the ping test, the user could set ping after this! */
anthony805a2d42011-09-25 08:25:12 +0000801 register const char
802 *q;
803
804 for (q=strchr(argv[1],'%'); q != (char *) NULL; q=strchr(q+1,'%'))
805 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
806 image_info->ping=MagickFalse;
cristy947cb4c2011-10-20 18:41:46 +0000807 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000808 break;
809 }
anthony74b1cfc2011-10-06 12:44:16 +0000810 if (LocaleCompare("fuzz",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000811 {
anthony6613bf32011-10-15 07:24:44 +0000812 /* FUTURE: image_info and ImageOption!
813 Option used to set image fuzz! unless blank canvas (from color)
cristy947cb4c2011-10-20 18:41:46 +0000814 image attribute used for color compare operations
815 Can't find anything using image_info->fuzz (except cloning)!
anthony6613bf32011-10-15 07:24:44 +0000816 */
817 if (IfSetOption)
cristy947cb4c2011-10-20 18:41:46 +0000818 {
819 image_info->fuzz=SiPrefixToDouble(argv[1],(double) QuantumRange+1.0);
820 (void) SetImageOption(image_info,option,argv[1]);
821 break;
822 }
823 image_info->fuzz=0.0;
824 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +0000825 break;
826 }
827 break;
828 }
829 case 'g':
830 {
anthony74b1cfc2011-10-06 12:44:16 +0000831 if (LocaleCompare("gravity",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000832 {
cristy947cb4c2011-10-20 18:41:46 +0000833 if (*argv[0] == '+')
834 {
835 (void) SetImageOption(image_info,option,"undefined");
836 draw_info->gravity=UndefinedGravity;
837 break;
838 }
839 (void) SetImageOption(image_info,option,argv[1]);
anthony6dc09cd2011-10-12 08:56:49 +0000840 draw_info->gravity=(GravityType) ParseCommandOption(
cristy947cb4c2011-10-20 18:41:46 +0000841 MagickGravityOptions,MagickFalse,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000842 break;
843 }
anthony74b1cfc2011-10-06 12:44:16 +0000844 if (LocaleCompare("green-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000845 {
cristy947cb4c2011-10-20 18:41:46 +0000846 if (*argv[0] == '+')
847 {
848 (void) SetImageOption(image_info,option,"0.0");
849 break;
850 }
851 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000852 break;
853 }
854 break;
855 }
856 case 'i':
857 {
anthony74b1cfc2011-10-06 12:44:16 +0000858 if (LocaleCompare("intent",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000859 {
cristy947cb4c2011-10-20 18:41:46 +0000860 if (*argv[0] == '+')
861 {
862 (void) SetImageOption(image_info,option,"undefined");
863 break;
864 }
865 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000866 break;
867 }
anthony74b1cfc2011-10-06 12:44:16 +0000868 if (LocaleCompare("interlace",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000869 {
cristy947cb4c2011-10-20 18:41:46 +0000870 if (*argv[0] == '+')
871 {
872 image_info->interlace=UndefinedInterlace;
873 (void) SetImageOption(image_info,option,"undefined");
874 break;
875 }
anthony805a2d42011-09-25 08:25:12 +0000876 image_info->interlace=(InterlaceType) ParseCommandOption(
cristy947cb4c2011-10-20 18:41:46 +0000877 MagickInterlaceOptions,MagickFalse,argv[1]);
878 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000879 break;
880 }
anthony74b1cfc2011-10-06 12:44:16 +0000881 if (LocaleCompare("interline-spacing",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000882 {
cristy947cb4c2011-10-20 18:41:46 +0000883 if (*argv[0] == '+')
884 {
885 (void) SetImageOption(image_info,option,"undefined");
886 break;
887 }
888 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000889 break;
890 }
anthony74b1cfc2011-10-06 12:44:16 +0000891 if (LocaleCompare("interpolate",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000892 {
cristy947cb4c2011-10-20 18:41:46 +0000893 if (*argv[0] == '+')
894 {
895 (void) SetImageOption(image_info,option,"undefined");
896 break;
897 }
898 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000899 break;
900 }
cristy947cb4c2011-10-20 18:41:46 +0000901 if (LocaleCompare("interword-spacing",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000902 {
cristy947cb4c2011-10-20 18:41:46 +0000903 if (*argv[0] == '+')
904 {
905 (void) SetImageOption(image_info,option,"undefined");
906 break;
907 }
908 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000909 break;
910 }
911 break;
912 }
913 case 'k':
914 {
anthony74b1cfc2011-10-06 12:44:16 +0000915 if (LocaleCompare("kerning",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000916 {
cristy947cb4c2011-10-20 18:41:46 +0000917 if (*argv[0] == '+')
918 {
919 (void) SetImageOption(image_info,option,"undefined");
920 break;
921 }
922 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000923 break;
924 }
925 break;
926 }
927 case 'l':
928 {
anthony74b1cfc2011-10-06 12:44:16 +0000929 if (LocaleCompare("label",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000930 {
cristy947cb4c2011-10-20 18:41:46 +0000931 if (*argv[0] == '+')
932 {
933 (void) DeleteImageOption(image_info,option);
934 break;
935 }
936 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +0000937 break;
938 }
anthony74b1cfc2011-10-06 12:44:16 +0000939 if (LocaleCompare("limit",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000940 {
941 MagickSizeType
942 limit;
943
944 ResourceType
945 type;
946
cristy947cb4c2011-10-20 18:41:46 +0000947 if (*argv[0] == '+')
anthony805a2d42011-09-25 08:25:12 +0000948 break;
949 type=(ResourceType) ParseCommandOption(MagickResourceOptions,
950 MagickFalse,argv[1]);
951 limit=MagickResourceInfinity;
952 if (LocaleCompare("unlimited",argv[2]) != 0)
953 limit=(MagickSizeType) SiPrefixToDouble(argv[2],100.0);
954 (void) SetMagickResourceLimit(type,limit);
955 break;
956 }
anthony74b1cfc2011-10-06 12:44:16 +0000957 if (LocaleCompare("list",option) == 0)
anthony805a2d42011-09-25 08:25:12 +0000958 {
959 ssize_t
960 list;
961
cristy947cb4c2011-10-20 18:41:46 +0000962 /*
963 Display configuration list.
964 */
anthony805a2d42011-09-25 08:25:12 +0000965 list=ParseCommandOption(MagickListOptions,MagickFalse,argv[1]);
966 switch (list)
967 {
968 case MagickCoderOptions:
969 {
970 (void) ListCoderInfo((FILE *) NULL,exception);
971 break;
972 }
973 case MagickColorOptions:
974 {
975 (void) ListColorInfo((FILE *) NULL,exception);
976 break;
977 }
978 case MagickConfigureOptions:
979 {
980 (void) ListConfigureInfo((FILE *) NULL,exception);
981 break;
982 }
983 case MagickDelegateOptions:
984 {
985 (void) ListDelegateInfo((FILE *) NULL,exception);
986 break;
987 }
988 case MagickFontOptions:
989 {
990 (void) ListTypeInfo((FILE *) NULL,exception);
991 break;
992 }
993 case MagickFormatOptions:
994 {
995 (void) ListMagickInfo((FILE *) NULL,exception);
996 break;
997 }
998 case MagickLocaleOptions:
999 {
1000 (void) ListLocaleInfo((FILE *) NULL,exception);
1001 break;
1002 }
1003 case MagickLogOptions:
1004 {
1005 (void) ListLogInfo((FILE *) NULL,exception);
1006 break;
1007 }
1008 case MagickMagicOptions:
1009 {
1010 (void) ListMagicInfo((FILE *) NULL,exception);
1011 break;
1012 }
1013 case MagickMimeOptions:
1014 {
1015 (void) ListMimeInfo((FILE *) NULL,exception);
1016 break;
1017 }
1018 case MagickModuleOptions:
1019 {
1020 (void) ListModuleInfo((FILE *) NULL,exception);
1021 break;
1022 }
1023 case MagickPolicyOptions:
1024 {
1025 (void) ListPolicyInfo((FILE *) NULL,exception);
1026 break;
1027 }
1028 case MagickResourceOptions:
1029 {
1030 (void) ListMagickResourceInfo((FILE *) NULL,exception);
1031 break;
1032 }
1033 case MagickThresholdOptions:
1034 {
1035 (void) ListThresholdMaps((FILE *) NULL,exception);
1036 break;
1037 }
1038 default:
1039 {
1040 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
1041 exception);
1042 break;
1043 }
1044 }
1045 break;
1046 }
anthony74b1cfc2011-10-06 12:44:16 +00001047 if (LocaleCompare("log",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001048 {
cristy947cb4c2011-10-20 18:41:46 +00001049 if (*argv[0] == '+')
1050 break;
1051 (void) SetLogFormat(argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001052 break;
1053 }
anthony74b1cfc2011-10-06 12:44:16 +00001054 if (LocaleCompare("loop",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001055 {
cristy947cb4c2011-10-20 18:41:46 +00001056 if (*argv[0] == '+')
1057 {
1058 (void) SetImageOption(image_info,option,"0");
1059 break;
1060 }
1061 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001062 break;
1063 }
1064 break;
1065 }
1066 case 'm':
1067 {
cristy947cb4c2011-10-20 18:41:46 +00001068 if (LocaleCompare("matte",option) == 0)
1069 {
1070 if (*argv[0] == '+')
1071 {
1072 (void) SetImageOption(image_info,option,"false");
1073 break;
1074 }
1075 (void) SetImageOption(image_info,option,"true");
1076 break;
1077 }
anthony74b1cfc2011-10-06 12:44:16 +00001078 if (LocaleCompare("mattecolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001079 {
cristy947cb4c2011-10-20 18:41:46 +00001080 if (*argv[0] == '+')
1081 {
1082 (void) SetImageOption(image_info,option,argv[1]);
1083 (void) QueryColorCompliance(MatteColor,AllCompliance,
1084 &image_info->matte_color,exception);
1085 break;
1086 }
anthony74b1cfc2011-10-06 12:44:16 +00001087 (void) SetImageOption(image_info,option,argv[1]);
cristy947cb4c2011-10-20 18:41:46 +00001088 (void) QueryColorCompliance(argv[1],AllCompliance,&image_info->matte_color,
1089 exception);
anthony805a2d42011-09-25 08:25:12 +00001090 break;
1091 }
anthony74b1cfc2011-10-06 12:44:16 +00001092 if (LocaleCompare("monitor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001093 {
1094 (void) SetImageInfoProgressMonitor(image_info,MonitorProgress,
1095 (void *) NULL);
1096 break;
1097 }
anthony74b1cfc2011-10-06 12:44:16 +00001098 if (LocaleCompare("monochrome",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001099 {
cristy947cb4c2011-10-20 18:41:46 +00001100 image_info->monochrome=(*argv[0] == '-') ? MagickTrue : MagickFalse;
anthony805a2d42011-09-25 08:25:12 +00001101 break;
1102 }
1103 break;
1104 }
1105 case 'o':
1106 {
anthony74b1cfc2011-10-06 12:44:16 +00001107 if (LocaleCompare("orient",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001108 {
cristy947cb4c2011-10-20 18:41:46 +00001109 if (*argv[0] == '+')
1110 {
1111 image_info->orientation=UndefinedOrientation;
1112 (void) SetImageOption(image_info,option,"undefined");
1113 break;
1114 }
1115 image_info->orientation=(OrientationType) ParseCommandOption(
1116 MagickOrientationOptions,MagickFalse,argv[1]);
1117 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001118 break;
1119 }
1120 }
1121 case 'p':
1122 {
anthony74b1cfc2011-10-06 12:44:16 +00001123 if (LocaleCompare("page",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001124 {
1125 char
1126 *canonical_page,
1127 page[MaxTextExtent];
1128
1129 const char
1130 *image_option;
1131
1132 MagickStatusType
1133 flags;
1134
1135 RectangleInfo
1136 geometry;
1137
cristy947cb4c2011-10-20 18:41:46 +00001138 if (*argv[0] == '+')
anthony805a2d42011-09-25 08:25:12 +00001139 {
anthony74b1cfc2011-10-06 12:44:16 +00001140 (void) DeleteImageOption(image_info,option);
anthony805a2d42011-09-25 08:25:12 +00001141 (void) CloneString(&image_info->page,(char *) NULL);
1142 break;
1143 }
1144 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
1145 image_option=GetImageOption(image_info,"page");
1146 if (image_option != (const char *) NULL)
1147 flags=ParseAbsoluteGeometry(image_option,&geometry);
1148 canonical_page=GetPageGeometry(argv[1]);
1149 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1150 canonical_page=DestroyString(canonical_page);
1151 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1152 (unsigned long) geometry.width,(unsigned long) geometry.height);
1153 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1154 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1155 (unsigned long) geometry.width,(unsigned long) geometry.height,
1156 (long) geometry.x,(long) geometry.y);
anthony74b1cfc2011-10-06 12:44:16 +00001157 (void) SetImageOption(image_info,option,page);
anthony805a2d42011-09-25 08:25:12 +00001158 (void) CloneString(&image_info->page,page);
1159 break;
1160 }
cristy947cb4c2011-10-20 18:41:46 +00001161 if (LocaleCompare("pen",option) == 0)
1162 {
1163 if (*argv[0] == '+')
1164 {
1165 (void) SetImageOption(image_info,option,"none");
1166 break;
1167 }
1168 (void) SetImageOption(image_info,option,argv[1]);
1169 break;
1170 }
anthony74b1cfc2011-10-06 12:44:16 +00001171 if (LocaleCompare("ping",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001172 {
1173 image_info->ping=(*argv[0] == '-') ? MagickTrue : MagickFalse;
1174 break;
1175 }
anthony74b1cfc2011-10-06 12:44:16 +00001176 if (LocaleCompare("pointsize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001177 {
cristy947cb4c2011-10-20 18:41:46 +00001178 if (*argv[0] == '+')
1179 geometry_info.rho=0.0;
1180 else
1181 (void) ParseGeometry(argv[1],&geometry_info);
1182 image_info->pointsize=geometry_info.rho;
anthony805a2d42011-09-25 08:25:12 +00001183 break;
1184 }
anthony74b1cfc2011-10-06 12:44:16 +00001185 if (LocaleCompare("precision",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001186 {
1187 (void) SetMagickPrecision(StringToInteger(argv[1]));
1188 break;
1189 }
anthony74b1cfc2011-10-06 12:44:16 +00001190 if (LocaleCompare("preview",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001191 {
cristy947cb4c2011-10-20 18:41:46 +00001192 /*
1193 Preview image.
1194 */
1195 if (*argv[0] == '+')
1196 {
1197 image_info->preview_type=UndefinedPreview;
1198 break;
1199 }
1200 image_info->preview_type=(PreviewType) ParseCommandOption(
1201 MagickPreviewOptions,MagickFalse,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001202 break;
1203 }
1204 break;
1205 }
1206 case 'q':
1207 {
anthony74b1cfc2011-10-06 12:44:16 +00001208 if (LocaleCompare("quality",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001209 {
cristy947cb4c2011-10-20 18:41:46 +00001210 /*
1211 Set image compression quality.
1212 */
1213 if (*argv[0] == '+')
anthony805a2d42011-09-25 08:25:12 +00001214 {
cristy947cb4c2011-10-20 18:41:46 +00001215 image_info->quality=UndefinedCompressionQuality;
1216 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001217 break;
1218 }
cristy947cb4c2011-10-20 18:41:46 +00001219 image_info->quality=StringToUnsignedLong(argv[1]);
1220 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001221 break;
1222 }
anthony74b1cfc2011-10-06 12:44:16 +00001223 if (LocaleCompare("quiet",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001224 {
1225 static WarningHandler
1226 warning_handler = (WarningHandler) NULL;
1227
1228 if (*argv[0] == '+')
1229 {
cristy947cb4c2011-10-20 18:41:46 +00001230 /*
1231 Restore error or warning messages.
1232 */
anthony805a2d42011-09-25 08:25:12 +00001233 warning_handler=SetWarningHandler(warning_handler);
1234 break;
1235 }
cristy947cb4c2011-10-20 18:41:46 +00001236 /*
1237 Suppress error or warning messages.
1238 */
anthony805a2d42011-09-25 08:25:12 +00001239 warning_handler=SetWarningHandler((WarningHandler) NULL);
1240 break;
1241 }
1242 break;
1243 }
1244 case 'r':
1245 {
anthony74b1cfc2011-10-06 12:44:16 +00001246 if (LocaleCompare("red-primary",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001247 {
cristy947cb4c2011-10-20 18:41:46 +00001248 if (*argv[0] == '+')
1249 {
1250 (void) SetImageOption(image_info,option,"0.0");
1251 break;
1252 }
1253 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001254 break;
1255 }
1256 break;
1257 }
1258 case 's':
1259 {
anthony74b1cfc2011-10-06 12:44:16 +00001260 if (LocaleCompare("sampling-factor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001261 {
1262 /*
1263 Set image sampling factor.
1264 */
1265 if (*argv[0] == '+')
1266 {
1267 if (image_info->sampling_factor != (char *) NULL)
1268 image_info->sampling_factor=DestroyString(
1269 image_info->sampling_factor);
1270 break;
1271 }
1272 (void) CloneString(&image_info->sampling_factor,argv[1]);
1273 break;
1274 }
anthony74b1cfc2011-10-06 12:44:16 +00001275 if (LocaleCompare("scene",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001276 {
1277 /*
1278 Set image scene.
1279 */
1280 if (*argv[0] == '+')
1281 {
1282 image_info->scene=0;
anthony74b1cfc2011-10-06 12:44:16 +00001283 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001284 break;
1285 }
1286 image_info->scene=StringToUnsignedLong(argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001287 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001288 break;
1289 }
anthony74b1cfc2011-10-06 12:44:16 +00001290 if (LocaleCompare("seed",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001291 {
1292 size_t
1293 seed;
1294
1295 if (*argv[0] == '+')
1296 {
1297 seed=(size_t) time((time_t *) NULL);
1298 SeedPseudoRandomGenerator(seed);
1299 break;
1300 }
1301 seed=StringToUnsignedLong(argv[1]);
1302 SeedPseudoRandomGenerator(seed);
1303 break;
1304 }
anthony74b1cfc2011-10-06 12:44:16 +00001305 if (LocaleCompare("size",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001306 {
anthony74b1cfc2011-10-06 12:44:16 +00001307 /* FUTURE: convert to ImageOption
1308 Look at special handling for "size" in SetImageOption()
1309 */
anthony805a2d42011-09-25 08:25:12 +00001310 if (*argv[0] == '+')
1311 {
1312 if (image_info->size != (char *) NULL)
1313 image_info->size=DestroyString(image_info->size);
1314 break;
1315 }
1316 (void) CloneString(&image_info->size,argv[1]);
1317 break;
1318 }
anthony74b1cfc2011-10-06 12:44:16 +00001319 if (LocaleCompare("stroke",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001320 {
1321 if (*argv[0] == '+')
1322 {
anthony74b1cfc2011-10-06 12:44:16 +00001323 (void) SetImageOption(image_info,option,"none");
anthony805a2d42011-09-25 08:25:12 +00001324 break;
1325 }
anthony74b1cfc2011-10-06 12:44:16 +00001326 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001327 break;
1328 }
anthony74b1cfc2011-10-06 12:44:16 +00001329 if (LocaleCompare("strokewidth",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001330 {
1331 if (*argv[0] == '+')
1332 {
anthony74b1cfc2011-10-06 12:44:16 +00001333 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001334 break;
1335 }
anthony74b1cfc2011-10-06 12:44:16 +00001336 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001337 break;
1338 }
anthony74b1cfc2011-10-06 12:44:16 +00001339 if (LocaleCompare("synchronize",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001340 {
1341 if (*argv[0] == '+')
1342 {
1343 image_info->synchronize=MagickFalse;
1344 break;
1345 }
1346 image_info->synchronize=MagickTrue;
1347 break;
1348 }
1349 break;
1350 }
1351 case 't':
1352 {
anthony74b1cfc2011-10-06 12:44:16 +00001353 if (LocaleCompare("taint",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001354 {
1355 if (*argv[0] == '+')
1356 {
anthony74b1cfc2011-10-06 12:44:16 +00001357 (void) SetImageOption(image_info,option,"false");
anthony805a2d42011-09-25 08:25:12 +00001358 break;
1359 }
anthony74b1cfc2011-10-06 12:44:16 +00001360 (void) SetImageOption(image_info,option,"true");
anthony805a2d42011-09-25 08:25:12 +00001361 break;
1362 }
anthony74b1cfc2011-10-06 12:44:16 +00001363 if (LocaleCompare("texture",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001364 {
1365 if (*argv[0] == '+')
1366 {
1367 if (image_info->texture != (char *) NULL)
1368 image_info->texture=DestroyString(image_info->texture);
1369 break;
1370 }
1371 (void) CloneString(&image_info->texture,argv[1]);
1372 break;
1373 }
anthony74b1cfc2011-10-06 12:44:16 +00001374 if (LocaleCompare("tile-offset",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001375 {
1376 if (*argv[0] == '+')
1377 {
anthony74b1cfc2011-10-06 12:44:16 +00001378 (void) SetImageOption(image_info,option,"0");
anthony805a2d42011-09-25 08:25:12 +00001379 break;
1380 }
anthony74b1cfc2011-10-06 12:44:16 +00001381 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001382 break;
1383 }
anthony74b1cfc2011-10-06 12:44:16 +00001384 if (LocaleCompare("transparent-color",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001385 {
1386 if (*argv[0] == '+')
1387 {
anthony1afdc7a2011-10-05 11:54:28 +00001388 (void) QueryColorCompliance("none",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00001389 &image_info->transparent_color,exception);
anthony74b1cfc2011-10-06 12:44:16 +00001390 (void) SetImageOption(image_info,option,"none");
anthony805a2d42011-09-25 08:25:12 +00001391 break;
1392 }
anthony1afdc7a2011-10-05 11:54:28 +00001393 (void) QueryColorCompliance("none",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00001394 &image_info->transparent_color,exception);
anthony74b1cfc2011-10-06 12:44:16 +00001395 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001396 break;
1397 }
anthony74b1cfc2011-10-06 12:44:16 +00001398 if (LocaleCompare("type",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001399 {
1400 if (*argv[0] == '+')
1401 {
1402 image_info->type=UndefinedType;
anthony74b1cfc2011-10-06 12:44:16 +00001403 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +00001404 break;
1405 }
1406 image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
1407 MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001408 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001409 break;
1410 }
1411 break;
1412 }
1413 case 'u':
1414 {
anthony74b1cfc2011-10-06 12:44:16 +00001415 if (LocaleCompare("undercolor",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001416 {
1417 if (*argv[0] == '+')
1418 {
anthony74b1cfc2011-10-06 12:44:16 +00001419 (void) DeleteImageOption(image_info,option);
anthony805a2d42011-09-25 08:25:12 +00001420 break;
1421 }
anthony74b1cfc2011-10-06 12:44:16 +00001422 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001423 break;
1424 }
anthony74b1cfc2011-10-06 12:44:16 +00001425 if (LocaleCompare("units",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001426 {
1427 if (*argv[0] == '+')
1428 {
1429 image_info->units=UndefinedResolution;
anthony74b1cfc2011-10-06 12:44:16 +00001430 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +00001431 break;
1432 }
1433 image_info->units=(ResolutionType) ParseCommandOption(
1434 MagickResolutionOptions,MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001435 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001436 break;
1437 }
1438 break;
1439 }
1440 case 'v':
1441 {
anthony74b1cfc2011-10-06 12:44:16 +00001442 if (LocaleCompare("verbose",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001443 {
1444 if (*argv[0] == '+')
1445 {
1446 image_info->verbose=MagickFalse;
1447 break;
1448 }
1449 image_info->verbose=MagickTrue;
1450 image_info->ping=MagickFalse;
1451 break;
1452 }
anthony74b1cfc2011-10-06 12:44:16 +00001453 if (LocaleCompare("view",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001454 {
1455 if (*argv[0] == '+')
1456 {
1457 if (image_info->view != (char *) NULL)
1458 image_info->view=DestroyString(image_info->view);
1459 break;
1460 }
1461 (void) CloneString(&image_info->view,argv[1]);
1462 break;
1463 }
anthony74b1cfc2011-10-06 12:44:16 +00001464 if (LocaleCompare("virtual-pixel",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001465 {
1466 if (*argv[0] == '+')
1467 {
1468 image_info->virtual_pixel_method=UndefinedVirtualPixelMethod;
anthony74b1cfc2011-10-06 12:44:16 +00001469 (void) SetImageOption(image_info,option,"undefined");
anthony805a2d42011-09-25 08:25:12 +00001470 break;
1471 }
1472 image_info->virtual_pixel_method=(VirtualPixelMethod)
1473 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,argv[1]);
anthony74b1cfc2011-10-06 12:44:16 +00001474 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001475 break;
1476 }
1477 break;
1478 }
1479 case 'w':
1480 {
anthony74b1cfc2011-10-06 12:44:16 +00001481 if (LocaleCompare("white-point",option) == 0)
anthony805a2d42011-09-25 08:25:12 +00001482 {
1483 if (*argv[0] == '+')
1484 {
anthony74b1cfc2011-10-06 12:44:16 +00001485 (void) SetImageOption(image_info,option,"0.0");
anthony805a2d42011-09-25 08:25:12 +00001486 break;
1487 }
anthony74b1cfc2011-10-06 12:44:16 +00001488 (void) SetImageOption(image_info,option,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00001489 break;
1490 }
1491 break;
1492 }
1493 default:
1494 break;
1495 }
1496 return(MagickTrue);
1497}
1498
1499/*
1500%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1501% %
1502% %
1503% %
anthony74b1cfc2011-10-06 12:44:16 +00001504+ A p p l y I m a g e O p e r a t o r %
anthony805a2d42011-09-25 08:25:12 +00001505% %
1506% %
1507% %
1508%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1509%
anthony74b1cfc2011-10-06 12:44:16 +00001510% ApplyImageOperator() apply one simple image operation to just the current
1511% image.
anthony805a2d42011-09-25 08:25:12 +00001512%
1513% The image in the list may be modified in three different ways...
1514%
1515% * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1516% * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1517% * replace by a list of images (-separate and -crop only!)
1518%
1519% In each case the result is returned into the list, and the pointer to the
1520% modified image (last image added if replaced by a list of images) is
1521% returned. As the image pointed to may be replaced, the first image in the
1522% list may also change. GetFirstImageInList() should be used by caller if
1523% they wish return the Image pointer to the first image in list.
1524%
anthony74b1cfc2011-10-06 12:44:16 +00001525% The format of the ApplyImageOperator method is:
anthony805a2d42011-09-25 08:25:12 +00001526%
anthony74b1cfc2011-10-06 12:44:16 +00001527% MagickBooleanType ApplyImageOperator(MagickWand *wand,
1528% const int argc,const char **argv)
anthony805a2d42011-09-25 08:25:12 +00001529%
1530% A description of each parameter follows:
1531%
anthony74b1cfc2011-10-06 12:44:16 +00001532% o wand: The CLI wand holding all the settings and pointer to image
anthony805a2d42011-09-25 08:25:12 +00001533%
1534% o argc: Specifies a pointer to an integer describing the number of
1535% elements in the argument vector.
1536%
1537% o argv: Specifies a pointer to a text array containing the command line
1538% arguments.
1539%
anthony805a2d42011-09-25 08:25:12 +00001540% o exception: return any errors or warnings in this structure.
1541%
1542*/
anthony74b1cfc2011-10-06 12:44:16 +00001543MagickExport MagickBooleanType ApplyImageOperator(MagickWand *wand,
1544 const int wand_unused(argc), const char **argv, ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +00001545{
1546 Image *
1547 new_image;
1548
1549 ChannelType
1550 channel;
1551
anthony5f867ae2011-10-09 10:28:34 +00001552 ComposeOperation
1553 compose;
1554
anthony805a2d42011-09-25 08:25:12 +00001555 const char
1556 *format;
1557
1558 DrawInfo
1559 *draw_info;
1560
1561 GeometryInfo
1562 geometry_info;
1563
1564 RectangleInfo
1565 geometry;
1566
1567 MagickStatusType
1568 status;
1569
1570 PixelInfo
1571 fill;
1572
1573 MagickStatusType
1574 flags;
1575
1576 QuantizeInfo
1577 *quantize_info;
1578
1579 assert(image_info != (const ImageInfo *) NULL);
1580 assert(image_info->signature == MagickSignature);
1581 assert(image != (Image **) NULL);
1582 assert((*image)->signature == MagickSignature);
1583 if ((*image)->debug != MagickFalse)
1584 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
anthonya89dd172011-10-04 13:29:35 +00001585 if (argc < 0)
1586 return(MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00001587 draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
1588 quantize_info=AcquireQuantizeInfo(image_info);
1589 SetGeometryInfo(&geometry_info);
1590 GetPixelInfo(*image,&fill);
1591 SetPixelInfoPacket(*image,&(*image)->background_color,&fill);
1592 channel=image_info->channel;
1593 format=GetImageOption(image_info,"format");
1594
1595 new_image = (Image *)NULL;
1596
cristy947cb4c2011-10-20 18:41:46 +00001597 switch (*(argv[0]+1))
anthony805a2d42011-09-25 08:25:12 +00001598 {
1599 case 'a':
1600 {
cristy947cb4c2011-10-20 18:41:46 +00001601 if (LocaleCompare("adaptive-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001602 {
anthony805a2d42011-09-25 08:25:12 +00001603 (void) SyncImageSettings(image_info,*image);
1604 flags=ParseGeometry(argv[1],&geometry_info);
1605 if ((flags & SigmaValue) == 0)
1606 geometry_info.sigma=1.0;
1607 if ((flags & XiValue) == 0)
1608 geometry_info.xi=0.0;
1609 new_image=AdaptiveBlurImage(*image,geometry_info.rho,
1610 geometry_info.sigma,geometry_info.xi,exception);
1611 break;
1612 }
cristy947cb4c2011-10-20 18:41:46 +00001613 if (LocaleCompare("adaptive-resize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001614 {
anthony1afdc7a2011-10-05 11:54:28 +00001615 /* FUTURE: this is really a "interpolate-resize" operator
1616 "adaptive-resize" uses a fixed "Mesh" interpolation
anthony805a2d42011-09-25 08:25:12 +00001617 */
1618 (void) SyncImageSettings(image_info,*image);
1619 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
1620 new_image=AdaptiveResizeImage(*image,geometry.width,
anthonya89dd172011-10-04 13:29:35 +00001621 geometry.height,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00001622 break;
1623 }
cristy947cb4c2011-10-20 18:41:46 +00001624 if (LocaleCompare("adaptive-sharpen",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001625 {
1626 /*
1627 Adaptive sharpen image.
1628 */
1629 (void) SyncImageSettings(image_info,*image);
1630 flags=ParseGeometry(argv[1],&geometry_info);
1631 if ((flags & SigmaValue) == 0)
1632 geometry_info.sigma=1.0;
1633 if ((flags & XiValue) == 0)
1634 geometry_info.xi=0.0;
1635 new_image=AdaptiveSharpenImage(*image,geometry_info.rho,
1636 geometry_info.sigma,geometry_info.xi,exception);
1637 break;
1638 }
cristy947cb4c2011-10-20 18:41:46 +00001639 if (LocaleCompare("alpha",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001640 {
1641 AlphaChannelType
1642 alpha_type;
1643
1644 (void) SyncImageSettings(image_info,*image);
1645 alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
1646 MagickFalse,argv[1]);
1647 (void) SetImageAlphaChannel(*image,alpha_type,exception);
1648 break;
1649 }
cristy947cb4c2011-10-20 18:41:46 +00001650 if (LocaleCompare("annotate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001651 {
1652 char
1653 *text,
1654 geometry[MaxTextExtent];
1655
anthony805a2d42011-09-25 08:25:12 +00001656 (void) SyncImageSettings(image_info,*image);
1657 SetGeometryInfo(&geometry_info);
1658 flags=ParseGeometry(argv[1],&geometry_info);
1659 if ((flags & SigmaValue) == 0)
1660 geometry_info.sigma=geometry_info.rho;
1661 text=InterpretImageProperties(image_info,*image,argv[2],
1662 exception);
1663 if (text == (char *) NULL)
1664 break;
1665 (void) CloneString(&draw_info->text,text);
1666 text=DestroyString(text);
1667 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1668 geometry_info.xi,geometry_info.psi);
1669 (void) CloneString(&draw_info->geometry,geometry);
1670 draw_info->affine.sx=cos(DegreesToRadians(
1671 fmod(geometry_info.rho,360.0)));
1672 draw_info->affine.rx=sin(DegreesToRadians(
1673 fmod(geometry_info.rho,360.0)));
1674 draw_info->affine.ry=(-sin(DegreesToRadians(
1675 fmod(geometry_info.sigma,360.0))));
1676 draw_info->affine.sy=cos(DegreesToRadians(
1677 fmod(geometry_info.sigma,360.0)));
1678 (void) AnnotateImage(*image,draw_info,exception);
1679 break;
1680 }
cristy947cb4c2011-10-20 18:41:46 +00001681 if (LocaleCompare("auto-gamma",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001682 {
1683 /*
1684 Auto Adjust Gamma of image based on its mean
1685 */
1686 (void) SyncImageSettings(image_info,*image);
1687 (void) AutoGammaImage(*image,exception);
1688 break;
1689 }
cristy947cb4c2011-10-20 18:41:46 +00001690 if (LocaleCompare("auto-level",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001691 {
1692 /*
1693 Perfectly Normalize (max/min stretch) the image
1694 */
1695 (void) SyncImageSettings(image_info,*image);
1696 (void) AutoLevelImage(*image,exception);
1697 break;
1698 }
cristy947cb4c2011-10-20 18:41:46 +00001699 if (LocaleCompare("auto-orient",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001700 {
1701 (void) SyncImageSettings(image_info,*image);
1702 switch ((*image)->orientation)
1703 {
1704 case TopRightOrientation:
1705 {
1706 new_image=FlopImage(*image,exception);
1707 break;
1708 }
1709 case BottomRightOrientation:
1710 {
1711 new_image=RotateImage(*image,180.0,exception);
1712 break;
1713 }
1714 case BottomLeftOrientation:
1715 {
1716 new_image=FlipImage(*image,exception);
1717 break;
1718 }
1719 case LeftTopOrientation:
1720 {
1721 new_image=TransposeImage(*image,exception);
1722 break;
1723 }
1724 case RightTopOrientation:
1725 {
1726 new_image=RotateImage(*image,90.0,exception);
1727 break;
1728 }
1729 case RightBottomOrientation:
1730 {
1731 new_image=TransverseImage(*image,exception);
1732 break;
1733 }
1734 case LeftBottomOrientation:
1735 {
1736 new_image=RotateImage(*image,270.0,exception);
1737 break;
1738 }
1739 default:
1740 break;
1741 }
1742 if (new_image != (Image *) NULL)
1743 new_image->orientation=TopLeftOrientation;
1744 break;
1745 }
1746 break;
1747 }
1748 case 'b':
1749 {
cristy947cb4c2011-10-20 18:41:46 +00001750 if (LocaleCompare("black-threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001751 {
anthony805a2d42011-09-25 08:25:12 +00001752 (void) SyncImageSettings(image_info,*image);
1753 (void) BlackThresholdImage(*image,argv[1],exception);
anthony805a2d42011-09-25 08:25:12 +00001754 break;
1755 }
cristy947cb4c2011-10-20 18:41:46 +00001756 if (LocaleCompare("blue-shift",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001757 {
anthony805a2d42011-09-25 08:25:12 +00001758 (void) SyncImageSettings(image_info,*image);
1759 geometry_info.rho=1.5;
1760 if (*argv[0] == '-')
1761 flags=ParseGeometry(argv[1],&geometry_info);
1762 new_image=BlueShiftImage(*image,geometry_info.rho,exception);
1763 break;
1764 }
cristy947cb4c2011-10-20 18:41:46 +00001765 if (LocaleCompare("blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001766 {
anthony74b1cfc2011-10-06 12:44:16 +00001767 /* FUTURE: use of "bias" in a blur is non-sensible */
anthony805a2d42011-09-25 08:25:12 +00001768 (void) SyncImageSettings(image_info,*image);
1769 flags=ParseGeometry(argv[1],&geometry_info);
1770 if ((flags & SigmaValue) == 0)
1771 geometry_info.sigma=1.0;
1772 if ((flags & XiValue) == 0)
1773 geometry_info.xi=0.0;
1774 new_image=BlurImage(*image,geometry_info.rho,
1775 geometry_info.sigma,geometry_info.xi,exception);
1776 break;
1777 }
cristy947cb4c2011-10-20 18:41:46 +00001778 if (LocaleCompare("border",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001779 {
anthony5f867ae2011-10-09 10:28:34 +00001780 ComposeOperator
1781 compose;
1782
1783 const char*
1784 const char*
1785 value;
1786
1787 value=GetImageOption(image_info,"compose");
1788 if (value != (const char *) NULL)
1789 compose=(CompositeOperator) ParseCommandOption(
1790 MagickComposeOptions,MagickFalse,value);
1791 else
1792 compose=OverCompositeOp; /* use Over not image->compose */
1793
anthony805a2d42011-09-25 08:25:12 +00001794 (void) SyncImageSettings(image_info,*image);
1795 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
1796 if ((flags & SigmaValue) == 0)
1797 geometry.height=geometry.width;
anthonya89dd172011-10-04 13:29:35 +00001798 new_image=BorderImage(*image,&geometry,compose,exception);
anthony805a2d42011-09-25 08:25:12 +00001799 break;
1800 }
cristy947cb4c2011-10-20 18:41:46 +00001801 if (LocaleCompare("brightness-contrast",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001802 {
1803 double
1804 brightness,
1805 contrast;
1806
1807 GeometryInfo
1808 geometry_info;
1809
1810 MagickStatusType
1811 flags;
1812
anthony805a2d42011-09-25 08:25:12 +00001813 (void) SyncImageSettings(image_info,*image);
1814 flags=ParseGeometry(argv[1],&geometry_info);
1815 brightness=geometry_info.rho;
1816 contrast=0.0;
1817 if ((flags & SigmaValue) != 0)
1818 contrast=geometry_info.sigma;
1819 (void) BrightnessContrastImage(*image,brightness,contrast,
1820 exception);
anthony805a2d42011-09-25 08:25:12 +00001821 break;
1822 }
1823 break;
1824 }
1825 case 'c':
1826 {
cristy947cb4c2011-10-20 18:41:46 +00001827 if (LocaleCompare("cdl",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001828 {
1829 char
1830 *color_correction_collection;
1831
1832 /*
1833 Color correct with a color decision list.
1834 */
1835 (void) SyncImageSettings(image_info,*image);
1836 color_correction_collection=FileToString(argv[1],~0,exception);
1837 if (color_correction_collection == (char *) NULL)
1838 break;
1839 (void) ColorDecisionListImage(*image,color_correction_collection,
1840 exception);
anthony805a2d42011-09-25 08:25:12 +00001841 break;
1842 }
cristy947cb4c2011-10-20 18:41:46 +00001843 if (LocaleCompare("channel",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001844 {
anthony74b1cfc2011-10-06 12:44:16 +00001845 /* The "channel" setting has already been set */
1846 SetPixelChannelMap(*image,image_info->channel);
anthony805a2d42011-09-25 08:25:12 +00001847 break;
1848 }
cristy947cb4c2011-10-20 18:41:46 +00001849 if (LocaleCompare("charcoal",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001850 {
anthony805a2d42011-09-25 08:25:12 +00001851 (void) SyncImageSettings(image_info,*image);
1852 flags=ParseGeometry(argv[1],&geometry_info);
1853 if ((flags & SigmaValue) == 0)
1854 geometry_info.sigma=1.0;
1855 if ((flags & XiValue) == 0)
1856 geometry_info.xi=1.0;
1857 new_image=CharcoalImage(*image,geometry_info.rho,
1858 geometry_info.sigma,geometry_info.xi,exception);
1859 break;
1860 }
cristy947cb4c2011-10-20 18:41:46 +00001861 if (LocaleCompare("chop",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001862 {
anthony805a2d42011-09-25 08:25:12 +00001863 (void) SyncImageSettings(image_info,*image);
1864 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
1865 new_image=ChopImage(*image,&geometry,exception);
1866 break;
1867 }
cristy947cb4c2011-10-20 18:41:46 +00001868 if (LocaleCompare("clamp",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001869 {
anthony805a2d42011-09-25 08:25:12 +00001870 (void) SyncImageSettings(image_info,*image);
cristy092d71c2011-10-14 18:01:29 +00001871 (void) ClampImage(*image,exception);
anthony805a2d42011-09-25 08:25:12 +00001872 break;
1873 }
cristy947cb4c2011-10-20 18:41:46 +00001874 if (LocaleCompare("clip",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001875 {
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 }
cristy947cb4c2011-10-20 18:41:46 +00001885 if (LocaleCompare("clip-mask",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001886 {
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);
anthony805a2d42011-09-25 08:25:12 +00001940 break;
1941 }
cristy947cb4c2011-10-20 18:41:46 +00001942 if (LocaleCompare("clip-path",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001943 {
1944 (void) SyncImageSettings(image_info,*image);
1945 (void) ClipImagePath(*image,argv[1],*argv[0] == '-' ? MagickTrue :
1946 MagickFalse,exception);
1947 break;
1948 }
cristy947cb4c2011-10-20 18:41:46 +00001949 if (LocaleCompare("colorize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001950 {
anthony805a2d42011-09-25 08:25:12 +00001951 (void) SyncImageSettings(image_info,*image);
1952 new_image=ColorizeImage(*image,argv[1],draw_info->fill,
1953 exception);
1954 break;
1955 }
cristy947cb4c2011-10-20 18:41:46 +00001956 if (LocaleCompare("color-matrix",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001957 {
1958 KernelInfo
1959 *kernel;
1960
1961 (void) SyncImageSettings(image_info,*image);
1962 kernel=AcquireKernelInfo(argv[1]);
1963 if (kernel == (KernelInfo *) NULL)
1964 break;
1965 new_image=ColorMatrixImage(*image,kernel,exception);
1966 kernel=DestroyKernelInfo(kernel);
1967 break;
1968 }
cristy947cb4c2011-10-20 18:41:46 +00001969 if (LocaleCompare("colors",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001970 {
anthony74b1cfc2011-10-06 12:44:16 +00001971 /* Reduce the number of colors in the image. */
anthony805a2d42011-09-25 08:25:12 +00001972 (void) SyncImageSettings(image_info,*image);
1973 quantize_info->number_colors=StringToUnsignedLong(argv[1]);
1974 if (quantize_info->number_colors == 0)
1975 break;
1976 if (((*image)->storage_class == DirectClass) ||
1977 (*image)->colors > quantize_info->number_colors)
1978 (void) QuantizeImage(quantize_info,*image,exception);
1979 else
1980 (void) CompressImageColormap(*image,exception);
1981 break;
1982 }
cristy947cb4c2011-10-20 18:41:46 +00001983 if (LocaleCompare("colorspace",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001984 {
anthonyd2cdc862011-10-07 14:07:17 +00001985 /* This is a Image Setting, which should already been set */
1986 /* FUTURE: default colorspace should be sRGB!
1987 Unless some type of 'linear colorspace' mode is set.
1988 Note that +colorspace sets "undefined" or no effect on
1989 new images, but forces images already in memory back to RGB!
1990 */
anthony805a2d42011-09-25 08:25:12 +00001991 (void) SyncImageSettings(image_info,*image);
anthonyd2cdc862011-10-07 14:07:17 +00001992 (void) TransformImageColorspace(*image,
anthony6613bf32011-10-15 07:24:44 +00001993 IfSetOption ? image_info->colorspace : RGBColorspace,
1994 exception);
anthony805a2d42011-09-25 08:25:12 +00001995 break;
1996 }
cristy947cb4c2011-10-20 18:41:46 +00001997 if (LocaleCompare("contrast",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001998 {
1999 (void) SyncImageSettings(image_info,*image);
2000 (void) ContrastImage(*image,(*argv[0] == '-') ? MagickTrue :
2001 MagickFalse,exception);
2002 break;
2003 }
cristy947cb4c2011-10-20 18:41:46 +00002004 if (LocaleCompare("contrast-stretch",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002005 {
2006 double
2007 black_point,
2008 white_point;
2009
2010 MagickStatusType
2011 flags;
2012
2013 /*
2014 Contrast stretch image.
2015 */
2016 (void) SyncImageSettings(image_info,*image);
2017 flags=ParseGeometry(argv[1],&geometry_info);
2018 black_point=geometry_info.rho;
2019 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2020 black_point;
2021 if ((flags & PercentValue) != 0)
2022 {
2023 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2024 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2025 }
2026 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2027 white_point;
2028 (void) ContrastStretchImage(*image,black_point,white_point,
2029 exception);
anthony805a2d42011-09-25 08:25:12 +00002030 break;
2031 }
cristy947cb4c2011-10-20 18:41:46 +00002032 if (LocaleCompare("convolve",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002033 {
2034 KernelInfo
2035 *kernel_info;
2036
2037 (void) SyncImageSettings(image_info,*image);
2038 kernel_info=AcquireKernelInfo(argv[1]);
2039 if (kernel_info == (KernelInfo *) NULL)
2040 break;
2041 kernel_info->bias=(*image)->bias;
2042 new_image=ConvolveImage(*image,kernel_info,exception);
2043 kernel_info=DestroyKernelInfo(kernel_info);
2044 break;
2045 }
cristy947cb4c2011-10-20 18:41:46 +00002046 if (LocaleCompare("crop",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002047 {
2048 /*
2049 Crop a image to a smaller size
2050 */
2051 (void) SyncImageSettings(image_info,*image);
2052 new_image=CropImageToTiles(*image,argv[1],exception);
2053 break;
2054 }
cristy947cb4c2011-10-20 18:41:46 +00002055 if (LocaleCompare("cycle",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002056 {
2057 /*
2058 Cycle an image colormap.
2059 */
2060 (void) SyncImageSettings(image_info,*image);
2061 (void) CycleColormapImage(*image,(ssize_t) StringToLong(argv[1]),
2062 exception);
2063 break;
2064 }
2065 break;
2066 }
2067 case 'd':
2068 {
cristy947cb4c2011-10-20 18:41:46 +00002069 if (LocaleCompare("decipher",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002070 {
2071 StringInfo
2072 *passkey;
2073
2074 /*
2075 Decipher pixels.
2076 */
2077 (void) SyncImageSettings(image_info,*image);
2078 passkey=FileToStringInfo(argv[1],~0,exception);
2079 if (passkey != (StringInfo *) NULL)
2080 {
2081 (void) PasskeyDecipherImage(*image,passkey,exception);
2082 passkey=DestroyStringInfo(passkey);
2083 }
2084 break;
2085 }
cristy947cb4c2011-10-20 18:41:46 +00002086 if (LocaleCompare("depth",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002087 {
anthony5f867ae2011-10-09 10:28:34 +00002088 /* the image_info->depth setting has already bee set
2089 * We just need to apply it to all images in current sequence */
anthony805a2d42011-09-25 08:25:12 +00002090 (void) SyncImageSettings(image_info,*image);
anthony5f867ae2011-10-09 10:28:34 +00002091 (void) SetImageDepth(*image,image_info->depth);
anthony805a2d42011-09-25 08:25:12 +00002092 break;
2093 }
cristy947cb4c2011-10-20 18:41:46 +00002094 if (LocaleCompare("deskew",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002095 {
2096 double
2097 threshold;
2098
2099 /*
2100 Straighten the image.
2101 */
2102 (void) SyncImageSettings(image_info,*image);
2103 if (*argv[0] == '+')
2104 threshold=40.0*QuantumRange/100.0;
2105 else
2106 threshold=SiPrefixToDouble(argv[1],QuantumRange);
2107 new_image=DeskewImage(*image,threshold,exception);
2108 break;
2109 }
cristy947cb4c2011-10-20 18:41:46 +00002110 if (LocaleCompare("despeckle",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002111 {
2112 /*
2113 Reduce the speckles within an image.
2114 */
2115 (void) SyncImageSettings(image_info,*image);
2116 new_image=DespeckleImage(*image,exception);
2117 break;
2118 }
cristy947cb4c2011-10-20 18:41:46 +00002119 if (LocaleCompare("display",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002120 {
2121 (void) CloneString(&draw_info->server_name,argv[1]);
2122 break;
2123 }
cristy947cb4c2011-10-20 18:41:46 +00002124 if (LocaleCompare("distort",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002125 {
2126 char
2127 *args,
2128 token[MaxTextExtent];
2129
2130 const char
2131 *p;
2132
2133 DistortImageMethod
2134 method;
2135
2136 double
2137 *arguments;
2138
2139 register ssize_t
2140 x;
2141
2142 size_t
2143 number_arguments;
2144
2145 /*
2146 Distort image.
2147 */
2148 (void) SyncImageSettings(image_info,*image);
2149 method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
2150 MagickFalse,argv[1]);
2151 if ( method == ResizeDistortion )
2152 {
2153 /* Special Case - Argument is actually a resize geometry!
2154 ** Convert that to an appropriate distortion argument array.
2155 */
2156 double
2157 resize_args[2];
2158 (void) ParseRegionGeometry(*image,argv[2],&geometry,
2159 exception);
2160 resize_args[0]=(double)geometry.width;
2161 resize_args[1]=(double)geometry.height;
2162 new_image=DistortImage(*image,method,(size_t)2,
2163 resize_args,MagickTrue,exception);
2164 break;
2165 }
2166 args=InterpretImageProperties(image_info,*image,argv[2],
2167 exception);
2168 if (args == (char *) NULL)
2169 break;
2170 p=(char *) args;
2171 for (x=0; *p != '\0'; x++)
2172 {
2173 GetMagickToken(p,&p,token);
2174 if (*token == ',')
2175 GetMagickToken(p,&p,token);
2176 }
2177 number_arguments=(size_t) x;
2178 arguments=(double *) AcquireQuantumMemory(number_arguments,
2179 sizeof(*arguments));
2180 if (arguments == (double *) NULL)
2181 ThrowWandFatalException(ResourceLimitFatalError,
2182 "MemoryAllocationFailed",(*image)->filename);
2183 (void) ResetMagickMemory(arguments,0,number_arguments*
2184 sizeof(*arguments));
2185 p=(char *) args;
2186 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2187 {
2188 GetMagickToken(p,&p,token);
2189 if (*token == ',')
2190 GetMagickToken(p,&p,token);
2191 arguments[x]=InterpretLocaleValue(token,(char **) NULL);
2192 }
2193 args=DestroyString(args);
2194 new_image=DistortImage(*image,method,number_arguments,arguments,
2195 (*argv[0] == '+') ? MagickTrue : MagickFalse,exception);
2196 arguments=(double *) RelinquishMagickMemory(arguments);
2197 break;
2198 }
cristy947cb4c2011-10-20 18:41:46 +00002199 if (LocaleCompare("draw",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002200 {
anthony805a2d42011-09-25 08:25:12 +00002201 (void) SyncImageSettings(image_info,*image);
2202 (void) CloneString(&draw_info->primitive,argv[1]);
2203 (void) DrawImage(*image,draw_info,exception);
2204 break;
2205 }
2206 break;
2207 }
2208 case 'e':
2209 {
cristy947cb4c2011-10-20 18:41:46 +00002210 if (LocaleCompare("edge",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002211 {
anthony805a2d42011-09-25 08:25:12 +00002212 (void) SyncImageSettings(image_info,*image);
2213 flags=ParseGeometry(argv[1],&geometry_info);
2214 if ((flags & SigmaValue) == 0)
2215 geometry_info.sigma=1.0;
2216 new_image=EdgeImage(*image,geometry_info.rho,
2217 geometry_info.sigma,exception);
2218 break;
2219 }
cristy947cb4c2011-10-20 18:41:46 +00002220 if (LocaleCompare("emboss",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002221 {
anthony805a2d42011-09-25 08:25:12 +00002222 (void) SyncImageSettings(image_info,*image);
2223 flags=ParseGeometry(argv[1],&geometry_info);
2224 if ((flags & SigmaValue) == 0)
2225 geometry_info.sigma=1.0;
2226 new_image=EmbossImage(*image,geometry_info.rho,
2227 geometry_info.sigma,exception);
2228 break;
2229 }
cristy947cb4c2011-10-20 18:41:46 +00002230 if (LocaleCompare("encipher",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002231 {
2232 StringInfo
2233 *passkey;
2234
anthony805a2d42011-09-25 08:25:12 +00002235 (void) SyncImageSettings(image_info,*image);
2236 passkey=FileToStringInfo(argv[1],~0,exception);
2237 if (passkey != (StringInfo *) NULL)
2238 {
2239 (void) PasskeyEncipherImage(*image,passkey,exception);
2240 passkey=DestroyStringInfo(passkey);
2241 }
2242 break;
2243 }
cristy947cb4c2011-10-20 18:41:46 +00002244 if (LocaleCompare("enhance",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002245 {
anthony805a2d42011-09-25 08:25:12 +00002246 (void) SyncImageSettings(image_info,*image);
2247 new_image=EnhanceImage(*image,exception);
2248 break;
2249 }
cristy947cb4c2011-10-20 18:41:46 +00002250 if (LocaleCompare("equalize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002251 {
anthony805a2d42011-09-25 08:25:12 +00002252 (void) SyncImageSettings(image_info,*image);
2253 (void) EqualizeImage(*image,exception);
2254 break;
2255 }
cristy947cb4c2011-10-20 18:41:46 +00002256 if (LocaleCompare("evaluate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002257 {
2258 double
2259 constant;
2260
2261 MagickEvaluateOperator
2262 op;
2263
2264 (void) SyncImageSettings(image_info,*image);
2265 op=(MagickEvaluateOperator) ParseCommandOption(
2266 MagickEvaluateOptions,MagickFalse,argv[1]);
2267 constant=SiPrefixToDouble(argv[2],QuantumRange);
2268 (void) EvaluateImage(*image,op,constant,exception);
2269 break;
2270 }
cristy947cb4c2011-10-20 18:41:46 +00002271 if (LocaleCompare("extent",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002272 {
anthony805a2d42011-09-25 08:25:12 +00002273 (void) SyncImageSettings(image_info,*image);
2274 flags=ParseGravityGeometry(*image,argv[1],&geometry,exception);
2275 if (geometry.width == 0)
2276 geometry.width=(*image)->columns;
2277 if (geometry.height == 0)
2278 geometry.height=(*image)->rows;
2279 new_image=ExtentImage(*image,&geometry,exception);
2280 break;
2281 }
2282 break;
2283 }
2284 case 'f':
2285 {
cristy947cb4c2011-10-20 18:41:46 +00002286 if (LocaleCompare("features",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002287 {
cristy947cb4c2011-10-20 18:41:46 +00002288 /* FUTURE: Assign Artifact all images */
anthony6dc09cd2011-10-12 08:56:49 +00002289 (void) SetImageArtifact(*image,"identify:features",
2290 IfSetOption ? argv[1] : (const char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002291 break;
2292 }
cristy947cb4c2011-10-20 18:41:46 +00002293 if (LocaleCompare("flip",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002294 {
cristy947cb4c2011-10-20 18:41:46 +00002295 /*
2296 Flip image scanlines.
2297 */
anthony805a2d42011-09-25 08:25:12 +00002298 (void) SyncImageSettings(image_info,*image);
2299 new_image=FlipImage(*image,exception);
2300 break;
2301 }
cristy947cb4c2011-10-20 18:41:46 +00002302 if (LocaleCompare("flop",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002303 {
cristy947cb4c2011-10-20 18:41:46 +00002304 /*
2305 Flop image scanlines.
2306 */
anthony805a2d42011-09-25 08:25:12 +00002307 (void) SyncImageSettings(image_info,*image);
2308 new_image=FlopImage(*image,exception);
2309 break;
2310 }
cristy947cb4c2011-10-20 18:41:46 +00002311 if (LocaleCompare("floodfill",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002312 {
2313 PixelInfo
2314 target;
2315
cristy947cb4c2011-10-20 18:41:46 +00002316 /*
2317 Floodfill image.
2318 */
anthony805a2d42011-09-25 08:25:12 +00002319 (void) SyncImageSettings(image_info,*image);
2320 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
cristy269c9412011-10-13 23:41:15 +00002321 (void) QueryColorCompliance(argv[2],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00002322 exception);
anthony805a2d42011-09-25 08:25:12 +00002323 (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
2324 geometry.y,*argv[0] == '-' ? MagickFalse : MagickTrue,exception);
2325 break;
2326 }
cristy947cb4c2011-10-20 18:41:46 +00002327 /* FUTURE: should be from ImageOption "format"
2328 if (LocaleCompare("format",argv[0]+1) == 0)
2329 {
2330 format=argv[1];
2331 break;
2332 }
2333 */
2334 if (LocaleCompare("frame",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002335 {
2336 FrameInfo
2337 frame_info;
2338
cristy947cb4c2011-10-20 18:41:46 +00002339 /*
2340 Surround image with an ornamental border.
2341 */
anthony805a2d42011-09-25 08:25:12 +00002342 (void) SyncImageSettings(image_info,*image);
2343 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
2344 frame_info.width=geometry.width;
2345 frame_info.height=geometry.height;
2346 if ((flags & HeightValue) == 0)
2347 frame_info.height=geometry.width;
2348 frame_info.outer_bevel=geometry.x;
2349 frame_info.inner_bevel=geometry.y;
2350 frame_info.x=(ssize_t) frame_info.width;
2351 frame_info.y=(ssize_t) frame_info.height;
2352 frame_info.width=(*image)->columns+2*frame_info.width;
2353 frame_info.height=(*image)->rows+2*frame_info.height;
anthony5f867ae2011-10-09 10:28:34 +00002354 new_image=FrameImage(*image,&frame_info,COMPOSE,exception);
anthony805a2d42011-09-25 08:25:12 +00002355 break;
2356 }
cristy947cb4c2011-10-20 18:41:46 +00002357 if (LocaleCompare("function",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002358 {
2359 char
2360 *arguments,
2361 token[MaxTextExtent];
2362
2363 const char
2364 *p;
2365
2366 double
2367 *parameters;
2368
2369 MagickFunction
2370 function;
2371
2372 register ssize_t
2373 x;
2374
2375 size_t
2376 number_parameters;
2377
cristy947cb4c2011-10-20 18:41:46 +00002378 /*
2379 Function Modify Image Values
2380 */
anthony805a2d42011-09-25 08:25:12 +00002381 (void) SyncImageSettings(image_info,*image);
2382 function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
2383 MagickFalse,argv[1]);
2384 arguments=InterpretImageProperties(image_info,*image,argv[2],
2385 exception);
2386 if (arguments == (char *) NULL)
2387 break;
2388 p=(char *) arguments;
2389 for (x=0; *p != '\0'; x++)
2390 {
2391 GetMagickToken(p,&p,token);
2392 if (*token == ',')
2393 GetMagickToken(p,&p,token);
2394 }
2395 number_parameters=(size_t) x;
2396 parameters=(double *) AcquireQuantumMemory(number_parameters,
2397 sizeof(*parameters));
2398 if (parameters == (double *) NULL)
2399 ThrowWandFatalException(ResourceLimitFatalError,
2400 "MemoryAllocationFailed",(*image)->filename);
2401 (void) ResetMagickMemory(parameters,0,number_parameters*
2402 sizeof(*parameters));
2403 p=(char *) arguments;
2404 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
2405 {
2406 GetMagickToken(p,&p,token);
2407 if (*token == ',')
2408 GetMagickToken(p,&p,token);
2409 parameters[x]=InterpretLocaleValue(token,(char **) NULL);
2410 }
2411 arguments=DestroyString(arguments);
2412 (void) FunctionImage(*image,function,number_parameters,parameters,
2413 exception);
2414 parameters=(double *) RelinquishMagickMemory(parameters);
2415 break;
2416 }
2417 break;
2418 }
2419 case 'g':
2420 {
cristy947cb4c2011-10-20 18:41:46 +00002421 if (LocaleCompare("gamma",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002422 {
anthony805a2d42011-09-25 08:25:12 +00002423 (void) SyncImageSettings(image_info,*image);
2424 if (*argv[0] == '+')
2425 (*image)->gamma=InterpretLocaleValue(argv[1],(char **) NULL);
2426 else
2427 (void) GammaImage(*image,InterpretLocaleValue(argv[1],
2428 (char **) NULL),exception);
2429 break;
2430 }
cristy947cb4c2011-10-20 18:41:46 +00002431 if ((LocaleCompare("gaussian-blur",argv[0]+1) == 0) ||
2432 (LocaleCompare("gaussian",argv[0]+1) == 0))
anthony805a2d42011-09-25 08:25:12 +00002433 {
anthony805a2d42011-09-25 08:25:12 +00002434 (void) SyncImageSettings(image_info,*image);
2435 flags=ParseGeometry(argv[1],&geometry_info);
2436 if ((flags & SigmaValue) == 0)
2437 geometry_info.sigma=1.0;
2438 if ((flags & XiValue) == 0)
2439 geometry_info.xi=0.0;
2440 new_image=GaussianBlurImage(*image,geometry_info.rho,
2441 geometry_info.sigma,geometry_info.xi,exception);
2442 break;
2443 }
cristy947cb4c2011-10-20 18:41:46 +00002444 if (LocaleCompare("geometry",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002445 {
2446 /*
anthony6613bf32011-10-15 07:24:44 +00002447 Record Image offset for composition,
2448 Resize last image. -- FUTURE depreciate this aspect
anthony805a2d42011-09-25 08:25:12 +00002449 */
2450 (void) SyncImageSettings(image_info,*image);
2451 if (*argv[0] == '+')
2452 {
2453 if ((*image)->geometry != (char *) NULL)
2454 (*image)->geometry=DestroyString((*image)->geometry);
2455 break;
2456 }
2457 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2458 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2459 (void) CloneString(&(*image)->geometry,argv[1]);
2460 else
2461 new_image=ResizeImage(*image,geometry.width,geometry.height,
2462 (*image)->filter,(*image)->blur,exception);
2463 break;
2464 }
anthony805a2d42011-09-25 08:25:12 +00002465 break;
2466 }
2467 case 'h':
2468 {
cristy947cb4c2011-10-20 18:41:46 +00002469 if (LocaleCompare("highlight-color",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002470 {
cristy947cb4c2011-10-20 18:41:46 +00002471 (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00002472 break;
2473 }
2474 break;
2475 }
2476 case 'i':
2477 {
cristy947cb4c2011-10-20 18:41:46 +00002478 if (LocaleCompare("identify",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002479 {
2480 char
2481 *text;
2482
2483 (void) SyncImageSettings(image_info,*image);
2484 if (format == (char *) NULL)
2485 {
2486 (void) IdentifyImage(*image,stdout,image_info->verbose,
2487 exception);
2488 break;
2489 }
2490 text=InterpretImageProperties(image_info,*image,format,
2491 exception);
2492 if (text == (char *) NULL)
2493 break;
2494 (void) fputs(text,stdout);
2495 (void) fputc('\n',stdout);
2496 text=DestroyString(text);
2497 break;
2498 }
cristy947cb4c2011-10-20 18:41:46 +00002499 if (LocaleCompare("implode",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002500 {
cristy947cb4c2011-10-20 18:41:46 +00002501 /*
2502 Implode image.
2503 */
anthony805a2d42011-09-25 08:25:12 +00002504 (void) SyncImageSettings(image_info,*image);
2505 (void) ParseGeometry(argv[1],&geometry_info);
anthonya89dd172011-10-04 13:29:35 +00002506 new_image=ImplodeImage(*image,geometry_info.rho,
2507 interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00002508 break;
2509 }
cristy947cb4c2011-10-20 18:41:46 +00002510 if (LocaleCompare("interline-spacing",argv[0]+1) == 0)
2511 {
2512 if (*argv[0] == '+')
2513 (void) ParseGeometry("0",&geometry_info);
2514 else
2515 (void) ParseGeometry(argv[1],&geometry_info);
2516 draw_info->interline_spacing=geometry_info.rho;
2517 break;
2518 }
2519 if (LocaleCompare("interpolate",argv[0]+1) == 0)
2520 {
2521 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
2522 MagickInterpolateOptions,MagickFalse,argv[1]);
2523 break;
2524 }
2525 if (LocaleCompare("interword-spacing",argv[0]+1) == 0)
2526 {
2527 if (*argv[0] == '+')
2528 (void) ParseGeometry("0",&geometry_info);
2529 else
2530 (void) ParseGeometry(argv[1],&geometry_info);
2531 draw_info->interword_spacing=geometry_info.rho;
2532 break;
2533 }
2534 break;
2535 }
2536 case 'k':
2537 {
2538 if (LocaleCompare("kerning",argv[0]+1) == 0)
2539 {
2540 if (*argv[0] == '+')
2541 (void) ParseGeometry("0",&geometry_info);
2542 else
2543 (void) ParseGeometry(argv[1],&geometry_info);
2544 draw_info->kerning=geometry_info.rho;
2545 break;
2546 }
anthony805a2d42011-09-25 08:25:12 +00002547 break;
2548 }
2549 case 'l':
2550 {
cristy947cb4c2011-10-20 18:41:46 +00002551 if (LocaleCompare("lat",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002552 {
2553 /*
2554 Local adaptive threshold image.
2555 */
2556 (void) SyncImageSettings(image_info,*image);
2557 flags=ParseGeometry(argv[1],&geometry_info);
2558 if ((flags & PercentValue) != 0)
2559 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2560 new_image=AdaptiveThresholdImage(*image,(size_t)
2561 geometry_info.rho,(size_t) geometry_info.sigma,(double)
2562 geometry_info.xi,exception);
2563 break;
2564 }
cristy947cb4c2011-10-20 18:41:46 +00002565 if (LocaleCompare("level",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002566 {
2567 MagickRealType
2568 black_point,
2569 gamma,
2570 white_point;
2571
2572 MagickStatusType
2573 flags;
2574
cristy947cb4c2011-10-20 18:41:46 +00002575 /*
2576 Parse levels.
2577 */
anthony805a2d42011-09-25 08:25:12 +00002578 (void) SyncImageSettings(image_info,*image);
2579 flags=ParseGeometry(argv[1],&geometry_info);
2580 black_point=geometry_info.rho;
2581 white_point=(MagickRealType) QuantumRange;
2582 if ((flags & SigmaValue) != 0)
2583 white_point=geometry_info.sigma;
2584 gamma=1.0;
2585 if ((flags & XiValue) != 0)
2586 gamma=geometry_info.xi;
2587 if ((flags & PercentValue) != 0)
2588 {
2589 black_point*=(MagickRealType) (QuantumRange/100.0);
2590 white_point*=(MagickRealType) (QuantumRange/100.0);
2591 }
2592 if ((flags & SigmaValue) == 0)
2593 white_point=(MagickRealType) QuantumRange-black_point;
2594 if ((*argv[0] == '+') || ((flags & AspectValue) != 0))
2595 (void) LevelizeImage(*image,black_point,white_point,gamma,
2596 exception);
2597 else
2598 (void) LevelImage(*image,black_point,white_point,gamma,
2599 exception);
anthony805a2d42011-09-25 08:25:12 +00002600 break;
2601 }
cristy947cb4c2011-10-20 18:41:46 +00002602 if (LocaleCompare("level-colors",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002603 {
2604 char
2605 token[MaxTextExtent];
2606
2607 const char
2608 *p;
2609
2610 PixelInfo
2611 black_point,
2612 white_point;
2613
2614 p=(const char *) argv[1];
2615 GetMagickToken(p,&p,token); /* get black point color */
2616 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002617 (void) QueryColorCompliance(token,AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002618 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002619 else
cristy269c9412011-10-13 23:41:15 +00002620 (void) QueryColorCompliance("#000000",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002621 &black_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002622 if (isalpha((int) token[0]) || (token[0] == '#'))
2623 GetMagickToken(p,&p,token);
2624 if (*token == '\0')
2625 white_point=black_point; /* set everything to that color */
2626 else
2627 {
2628 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2629 GetMagickToken(p,&p,token); /* Get white point color. */
2630 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002631 (void) QueryColorCompliance(token,AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002632 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002633 else
cristy269c9412011-10-13 23:41:15 +00002634 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthonya89dd172011-10-04 13:29:35 +00002635 &white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002636 }
2637 (void) LevelImageColors(*image,&black_point,&white_point,
2638 *argv[0] == '+' ? MagickTrue : MagickFalse,exception);
2639 break;
2640 }
cristy947cb4c2011-10-20 18:41:46 +00002641 if (LocaleCompare("linear-stretch",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002642 {
2643 double
2644 black_point,
2645 white_point;
2646
2647 MagickStatusType
2648 flags;
2649
2650 (void) SyncImageSettings(image_info,*image);
2651 flags=ParseGeometry(argv[1],&geometry_info);
2652 black_point=geometry_info.rho;
2653 white_point=(MagickRealType) (*image)->columns*(*image)->rows;
2654 if ((flags & SigmaValue) != 0)
2655 white_point=geometry_info.sigma;
2656 if ((flags & PercentValue) != 0)
2657 {
2658 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2659 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2660 }
2661 if ((flags & SigmaValue) == 0)
2662 white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2663 black_point;
2664 (void) LinearStretchImage(*image,black_point,white_point,exception);
anthony805a2d42011-09-25 08:25:12 +00002665 break;
2666 }
cristy947cb4c2011-10-20 18:41:46 +00002667 if (LocaleCompare("linewidth",argv[0]+1) == 0)
2668 {
2669 draw_info->stroke_width=InterpretLocaleValue(argv[1],
2670 (char **) NULL);
2671 break;
2672 }
2673 if (LocaleCompare("liquid-rescale",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002674 {
2675 /*
2676 Liquid rescale image.
2677 */
2678 (void) SyncImageSettings(image_info,*image);
2679 flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2680 if ((flags & XValue) == 0)
2681 geometry.x=1;
2682 if ((flags & YValue) == 0)
2683 geometry.y=0;
2684 new_image=LiquidRescaleImage(*image,geometry.width,
2685 geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
2686 break;
2687 }
cristy947cb4c2011-10-20 18:41:46 +00002688 if (LocaleCompare("lowlight-color",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002689 {
cristy947cb4c2011-10-20 18:41:46 +00002690 (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00002691 break;
2692 }
2693 break;
2694 }
2695 case 'm':
2696 {
cristy947cb4c2011-10-20 18:41:46 +00002697 if (LocaleCompare("map",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002698 {
2699 Image
2700 *remap_image;
2701
cristy947cb4c2011-10-20 18:41:46 +00002702 /*
2703 Transform image colors to match this set of colors.
2704 */
anthony805a2d42011-09-25 08:25:12 +00002705 (void) SyncImageSettings(image_info,*image);
2706 if (*argv[0] == '+')
2707 break;
2708 remap_image=GetImageCache(image_info,argv[1],exception);
2709 if (remap_image == (Image *) NULL)
2710 break;
2711 (void) RemapImage(quantize_info,*image,remap_image,exception);
2712 remap_image=DestroyImage(remap_image);
2713 break;
2714 }
cristy947cb4c2011-10-20 18:41:46 +00002715 if (LocaleCompare("mask",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002716 {
2717 Image
2718 *mask;
2719
2720 (void) SyncImageSettings(image_info,*image);
2721 if (*argv[0] == '+')
2722 {
cristy947cb4c2011-10-20 18:41:46 +00002723 /*
2724 Remove a mask.
2725 */
anthony805a2d42011-09-25 08:25:12 +00002726 (void) SetImageMask(*image,(Image *) NULL,exception);
2727 break;
2728 }
cristy947cb4c2011-10-20 18:41:46 +00002729 /*
2730 Set the image mask.
2731 */
anthony805a2d42011-09-25 08:25:12 +00002732 mask=GetImageCache(image_info,argv[1],exception);
2733 if (mask == (Image *) NULL)
2734 break;
2735 (void) SetImageMask(*image,mask,exception);
2736 mask=DestroyImage(mask);
2737 break;
2738 }
cristy947cb4c2011-10-20 18:41:46 +00002739 if (LocaleCompare("matte",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002740 {
cristy947cb4c2011-10-20 18:41:46 +00002741 (void) SetImageAlphaChannel(*image,(*argv[0] == '-') ?
2742 SetAlphaChannel : DeactivateAlphaChannel,exception);
anthony805a2d42011-09-25 08:25:12 +00002743 break;
2744 }
cristy947cb4c2011-10-20 18:41:46 +00002745 if (LocaleCompare("median",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002746 {
cristy947cb4c2011-10-20 18:41:46 +00002747 /*
2748 Median filter image.
2749 */
anthony805a2d42011-09-25 08:25:12 +00002750 (void) SyncImageSettings(image_info,*image);
2751 flags=ParseGeometry(argv[1],&geometry_info);
2752 if ((flags & SigmaValue) == 0)
2753 geometry_info.sigma=geometry_info.rho;
2754 new_image=StatisticImage(*image,MedianStatistic,(size_t)
2755 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2756 break;
2757 }
cristy947cb4c2011-10-20 18:41:46 +00002758 if (LocaleCompare("mode",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002759 {
2760 /*
cristy947cb4c2011-10-20 18:41:46 +00002761 Mode image.
anthony805a2d42011-09-25 08:25:12 +00002762 */
2763 (void) SyncImageSettings(image_info,*image);
2764 flags=ParseGeometry(argv[1],&geometry_info);
2765 if ((flags & SigmaValue) == 0)
2766 geometry_info.sigma=geometry_info.rho;
2767 new_image=StatisticImage(*image,ModeStatistic,(size_t)
2768 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2769 break;
2770 }
cristy947cb4c2011-10-20 18:41:46 +00002771 if (LocaleCompare("modulate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002772 {
2773 (void) SyncImageSettings(image_info,*image);
2774 (void) ModulateImage(*image,argv[1],exception);
2775 break;
2776 }
cristy947cb4c2011-10-20 18:41:46 +00002777 if (LocaleCompare("monitor",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002778 {
2779 if (*argv[0] == '+')
2780 {
2781 (void) SetImageProgressMonitor(*image,
2782 (MagickProgressMonitor) NULL,(void *) NULL);
2783 break;
2784 }
2785 (void) SetImageProgressMonitor(*image,MonitorProgress,
2786 (void *) NULL);
2787 break;
2788 }
cristy947cb4c2011-10-20 18:41:46 +00002789 if (LocaleCompare("monochrome",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002790 {
2791 (void) SyncImageSettings(image_info,*image);
2792 (void) SetImageType(*image,BilevelType,exception);
2793 break;
2794 }
cristy947cb4c2011-10-20 18:41:46 +00002795 if (LocaleCompare("morphology",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002796 {
2797 char
2798 token[MaxTextExtent];
2799
2800 const char
2801 *p;
2802
2803 KernelInfo
2804 *kernel;
2805
2806 MorphologyMethod
2807 method;
2808
2809 ssize_t
2810 iterations;
2811
2812 /*
2813 Morphological Image Operation
2814 */
2815 (void) SyncImageSettings(image_info,*image);
2816 p=argv[1];
2817 GetMagickToken(p,&p,token);
2818 method=(MorphologyMethod) ParseCommandOption(
2819 MagickMorphologyOptions,MagickFalse,token);
2820 iterations=1L;
2821 GetMagickToken(p,&p,token);
2822 if ((*p == ':') || (*p == ','))
2823 GetMagickToken(p,&p,token);
2824 if ((*p != '\0'))
2825 iterations=(ssize_t) StringToLong(p);
2826 kernel=AcquireKernelInfo(argv[2]);
2827 if (kernel == (KernelInfo *) NULL)
2828 {
2829 (void) ThrowMagickException(exception,GetMagickModule(),
2830 OptionError,"UnabletoParseKernel","morphology");
2831 status=MagickFalse;
2832 break;
2833 }
2834 new_image=MorphologyImage(*image,method,iterations,kernel,
2835 exception);
2836 kernel=DestroyKernelInfo(kernel);
2837 break;
2838 }
cristy947cb4c2011-10-20 18:41:46 +00002839 if (LocaleCompare("motion-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002840 {
cristy947cb4c2011-10-20 18:41:46 +00002841 /*
2842 Motion blur image.
2843 */
anthony805a2d42011-09-25 08:25:12 +00002844 (void) SyncImageSettings(image_info,*image);
2845 flags=ParseGeometry(argv[1],&geometry_info);
2846 if ((flags & SigmaValue) == 0)
2847 geometry_info.sigma=1.0;
2848 new_image=MotionBlurImage(*image,geometry_info.rho,
2849 geometry_info.sigma,geometry_info.xi,geometry_info.psi,
2850 exception);
2851 break;
2852 }
2853 break;
2854 }
2855 case 'n':
2856 {
cristy947cb4c2011-10-20 18:41:46 +00002857 if (LocaleCompare("negate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002858 {
2859 (void) SyncImageSettings(image_info,*image);
2860 (void) NegateImage(*image,*argv[0] == '+' ? MagickTrue :
2861 MagickFalse,exception);
2862 break;
2863 }
cristy947cb4c2011-10-20 18:41:46 +00002864 if (LocaleCompare("noise",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002865 {
2866 (void) SyncImageSettings(image_info,*image);
2867 if (*argv[0] == '-')
2868 {
2869 flags=ParseGeometry(argv[1],&geometry_info);
2870 if ((flags & SigmaValue) == 0)
2871 geometry_info.sigma=geometry_info.rho;
2872 new_image=StatisticImage(*image,NonpeakStatistic,(size_t)
2873 geometry_info.rho,(size_t) geometry_info.sigma,exception);
2874 }
2875 else
2876 {
2877 NoiseType
2878 noise;
2879
2880 noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
2881 MagickFalse,argv[1]);
anthony5f867ae2011-10-09 10:28:34 +00002882 new_image=AddNoiseImage(*image,noise,exception);
anthony805a2d42011-09-25 08:25:12 +00002883 }
2884 break;
2885 }
cristy947cb4c2011-10-20 18:41:46 +00002886 if (LocaleCompare("normalize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002887 {
2888 (void) SyncImageSettings(image_info,*image);
2889 (void) NormalizeImage(*image,exception);
2890 break;
2891 }
2892 break;
2893 }
2894 case 'o':
2895 {
cristy947cb4c2011-10-20 18:41:46 +00002896 if (LocaleCompare("opaque",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002897 {
2898 PixelInfo
2899 target;
2900
2901 (void) SyncImageSettings(image_info,*image);
cristy269c9412011-10-13 23:41:15 +00002902 (void) QueryColorCompliance(argv[1],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00002903 exception);
anthony805a2d42011-09-25 08:25:12 +00002904 (void) OpaquePaintImage(*image,&target,&fill,*argv[0] == '-' ?
2905 MagickFalse : MagickTrue,exception);
2906 break;
2907 }
cristy947cb4c2011-10-20 18:41:46 +00002908 if (LocaleCompare("ordered-dither",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002909 {
2910 (void) SyncImageSettings(image_info,*image);
2911 (void) OrderedPosterizeImage(*image,argv[1],exception);
2912 break;
2913 }
2914 break;
2915 }
2916 case 'p':
2917 {
cristy947cb4c2011-10-20 18:41:46 +00002918 if (LocaleCompare("paint",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002919 {
2920 (void) SyncImageSettings(image_info,*image);
2921 (void) ParseGeometry(argv[1],&geometry_info);
2922 new_image=OilPaintImage(*image,geometry_info.rho,
2923 geometry_info.sigma,exception);
2924 break;
2925 }
cristy947cb4c2011-10-20 18:41:46 +00002926 if (LocaleCompare("pen",argv[0]+1) == 0)
2927 {
2928 if (*argv[0] == '+')
2929 {
2930 (void) QueryColorCompliance("none",AllCompliance,&draw_info->fill,
2931 exception);
2932 break;
2933 }
2934 (void) QueryColorCompliance(argv[1],AllCompliance,&draw_info->fill,
2935 exception);
2936 break;
2937 }
2938 if (LocaleCompare("pointsize",argv[0]+1) == 0)
2939 {
2940 if (*argv[0] == '+')
2941 (void) ParseGeometry("12",&geometry_info);
2942 else
2943 (void) ParseGeometry(argv[1],&geometry_info);
2944 draw_info->pointsize=geometry_info.rho;
2945 break;
2946 }
2947 if (LocaleCompare("polaroid",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002948 {
2949 double
2950 angle;
2951
2952 RandomInfo
2953 *random_info;
2954
cristy947cb4c2011-10-20 18:41:46 +00002955 /*
2956 Simulate a Polaroid picture.
2957 */
anthony805a2d42011-09-25 08:25:12 +00002958 (void) SyncImageSettings(image_info,*image);
2959 random_info=AcquireRandomInfo();
2960 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2961 random_info=DestroyRandomInfo(random_info);
2962 if (*argv[0] == '-')
2963 {
2964 SetGeometryInfo(&geometry_info);
2965 flags=ParseGeometry(argv[1],&geometry_info);
2966 angle=geometry_info.rho;
2967 }
2968 new_image=PolaroidImage(*image,draw_info,angle,
2969 interpolate_method,exception);
2970 break;
2971 }
cristy947cb4c2011-10-20 18:41:46 +00002972 if (LocaleCompare("posterize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002973 {
cristy947cb4c2011-10-20 18:41:46 +00002974 /*
2975 Posterize image.
2976 */
anthony805a2d42011-09-25 08:25:12 +00002977 (void) SyncImageSettings(image_info,*image);
2978 (void) PosterizeImage(*image,StringToUnsignedLong(argv[1]),
2979 quantize_info->dither,exception);
2980 break;
2981 }
cristy947cb4c2011-10-20 18:41:46 +00002982 if (LocaleCompare("preview",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002983 {
2984 PreviewType
cristy947cb4c2011-10-20 18:41:46 +00002985 preview_type;
anthony170fce92011-10-20 11:50:23 +00002986
cristy947cb4c2011-10-20 18:41:46 +00002987 /*
2988 Preview image.
2989 */
anthony170fce92011-10-20 11:50:23 +00002990 (void) SyncImageSettings(image_info,*image);
cristy947cb4c2011-10-20 18:41:46 +00002991 if (*argv[0] == '+')
2992 preview_type=UndefinedPreview;
2993 else
anthony805a2d42011-09-25 08:25:12 +00002994 preview_type=(PreviewType) ParseCommandOption(
2995 MagickPreviewOptions,MagickFalse,argv[1]);
2996 new_image=PreviewImage(*image,preview_type,exception);
2997 break;
2998 }
cristy947cb4c2011-10-20 18:41:46 +00002999 if (LocaleCompare("profile",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003000 {
3001 const char
3002 *name;
3003
3004 const StringInfo
3005 *profile;
3006
3007 Image
3008 *profile_image;
3009
3010 ImageInfo
3011 *profile_info;
3012
3013 (void) SyncImageSettings(image_info,*image);
cristy947cb4c2011-10-20 18:41:46 +00003014 if (*argv[0] == '+')
anthony805a2d42011-09-25 08:25:12 +00003015 {
cristy947cb4c2011-10-20 18:41:46 +00003016 /*
3017 Remove a profile from the image.
3018 */
anthony805a2d42011-09-25 08:25:12 +00003019 (void) ProfileImage(*image,argv[1],(const unsigned char *)
cristy092d71c2011-10-14 18:01:29 +00003020 NULL,0,exception);
anthony805a2d42011-09-25 08:25:12 +00003021 break;
3022 }
cristy947cb4c2011-10-20 18:41:46 +00003023 /*
3024 Associate a profile with the image.
3025 */
anthony805a2d42011-09-25 08:25:12 +00003026 profile_info=CloneImageInfo(image_info);
3027 profile=GetImageProfile(*image,"iptc");
3028 if (profile != (StringInfo *) NULL)
3029 profile_info->profile=(void *) CloneStringInfo(profile);
3030 profile_image=GetImageCache(profile_info,argv[1],exception);
3031 profile_info=DestroyImageInfo(profile_info);
3032 if (profile_image == (Image *) NULL)
3033 {
3034 StringInfo
3035 *profile;
3036
3037 profile_info=CloneImageInfo(image_info);
3038 (void) CopyMagickString(profile_info->filename,argv[1],
3039 MaxTextExtent);
3040 profile=FileToStringInfo(profile_info->filename,~0UL,exception);
3041 if (profile != (StringInfo *) NULL)
3042 {
3043 (void) ProfileImage(*image,profile_info->magick,
3044 GetStringInfoDatum(profile),(size_t)
cristy092d71c2011-10-14 18:01:29 +00003045 GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003046 profile=DestroyStringInfo(profile);
3047 }
3048 profile_info=DestroyImageInfo(profile_info);
3049 break;
3050 }
3051 ResetImageProfileIterator(profile_image);
3052 name=GetNextImageProfile(profile_image);
3053 while (name != (const char *) NULL)
3054 {
3055 profile=GetImageProfile(profile_image,name);
3056 if (profile != (StringInfo *) NULL)
3057 (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
cristy092d71c2011-10-14 18:01:29 +00003058 (size_t) GetStringInfoLength(profile),exception);
anthony805a2d42011-09-25 08:25:12 +00003059 name=GetNextImageProfile(profile_image);
3060 }
3061 profile_image=DestroyImage(profile_image);
3062 break;
3063 }
3064 break;
3065 }
cristy947cb4c2011-10-20 18:41:46 +00003066 case 'q':
3067 {
3068 if (LocaleCompare("quantize",argv[0]+1) == 0)
3069 {
3070 if (*argv[0] == '+')
3071 {
3072 quantize_info->colorspace=UndefinedColorspace;
3073 break;
3074 }
3075 quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
3076 MagickColorspaceOptions,MagickFalse,argv[1]);
3077 break;
3078 }
3079 break;
3080 }
anthony805a2d42011-09-25 08:25:12 +00003081 case 'r':
3082 {
cristy947cb4c2011-10-20 18:41:46 +00003083 if (LocaleCompare("radial-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003084 {
3085 /*
3086 Radial blur image.
3087 */
3088 (void) SyncImageSettings(image_info,*image);
3089 flags=ParseGeometry(argv[1],&geometry_info);
3090 new_image=RadialBlurImage(*image,geometry_info.rho,
3091 geometry_info.sigma,exception);
3092 break;
3093 }
cristy947cb4c2011-10-20 18:41:46 +00003094 if (LocaleCompare("raise",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003095 {
3096 /*
3097 Surround image with a raise of solid color.
3098 */
3099 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3100 if ((flags & SigmaValue) == 0)
3101 geometry.height=geometry.width;
3102 (void) RaiseImage(*image,&geometry,*argv[0] == '-' ? MagickTrue :
3103 MagickFalse,exception);
3104 break;
3105 }
cristy947cb4c2011-10-20 18:41:46 +00003106 if (LocaleCompare("random-threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003107 {
3108 /*
3109 Threshold image.
3110 */
3111 (void) SyncImageSettings(image_info,*image);
3112 (void) RandomThresholdImage(*image,argv[1],exception);
3113 break;
3114 }
cristy947cb4c2011-10-20 18:41:46 +00003115 if (LocaleCompare("recolor",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003116 {
3117 KernelInfo
3118 *kernel;
3119
3120 (void) SyncImageSettings(image_info,*image);
3121 kernel=AcquireKernelInfo(argv[1]);
3122 if (kernel == (KernelInfo *) NULL)
3123 break;
3124 new_image=ColorMatrixImage(*image,kernel,exception);
3125 kernel=DestroyKernelInfo(kernel);
3126 break;
3127 }
cristy947cb4c2011-10-20 18:41:46 +00003128 if (LocaleCompare("render",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003129 {
3130 (void) SyncImageSettings(image_info,*image);
3131 draw_info->render=(*argv[0] == '+') ? MagickTrue : MagickFalse;
3132 break;
3133 }
cristy947cb4c2011-10-20 18:41:46 +00003134 if (LocaleCompare("remap",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003135 {
3136 Image
3137 *remap_image;
3138
3139 /*
3140 Transform image colors to match this set of colors.
3141 */
3142 (void) SyncImageSettings(image_info,*image);
3143 if (*argv[0] == '+')
3144 break;
3145 remap_image=GetImageCache(image_info,argv[1],exception);
3146 if (remap_image == (Image *) NULL)
3147 break;
3148 (void) RemapImage(quantize_info,*image,remap_image,exception);
3149 remap_image=DestroyImage(remap_image);
3150 break;
3151 }
cristy947cb4c2011-10-20 18:41:46 +00003152 if (LocaleCompare("repage",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003153 {
3154 if (*argv[0] == '+')
3155 {
3156 (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
3157 break;
3158 }
3159 (void) ResetImagePage(*image,argv[1]);
anthony805a2d42011-09-25 08:25:12 +00003160 break;
3161 }
cristy947cb4c2011-10-20 18:41:46 +00003162 if (LocaleCompare("resample",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003163 {
3164 /*
3165 Resample image.
3166 */
3167 (void) SyncImageSettings(image_info,*image);
3168 flags=ParseGeometry(argv[1],&geometry_info);
3169 if ((flags & SigmaValue) == 0)
3170 geometry_info.sigma=geometry_info.rho;
3171 new_image=ResampleImage(*image,geometry_info.rho,
3172 geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
3173 break;
3174 }
cristy947cb4c2011-10-20 18:41:46 +00003175 if (LocaleCompare("resize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003176 {
3177 /*
3178 Resize image.
3179 */
3180 (void) SyncImageSettings(image_info,*image);
3181 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3182 new_image=ResizeImage(*image,geometry.width,geometry.height,
3183 (*image)->filter,(*image)->blur,exception);
3184 break;
3185 }
cristy947cb4c2011-10-20 18:41:46 +00003186 if (LocaleCompare("roll",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003187 {
3188 /*
3189 Roll image.
3190 */
3191 (void) SyncImageSettings(image_info,*image);
3192 (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
3193 new_image=RollImage(*image,geometry.x,geometry.y,exception);
3194 break;
3195 }
cristy947cb4c2011-10-20 18:41:46 +00003196 if (LocaleCompare("rotate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003197 {
3198 char
3199 *geometry;
3200
3201 /*
3202 Check for conditional image rotation.
3203 */
3204 (void) SyncImageSettings(image_info,*image);
3205 if (strchr(argv[1],'>') != (char *) NULL)
3206 if ((*image)->columns <= (*image)->rows)
3207 break;
3208 if (strchr(argv[1],'<') != (char *) NULL)
3209 if ((*image)->columns >= (*image)->rows)
3210 break;
3211 /*
3212 Rotate image.
3213 */
3214 geometry=ConstantString(argv[1]);
3215 (void) SubstituteString(&geometry,">","");
3216 (void) SubstituteString(&geometry,"<","");
3217 (void) ParseGeometry(geometry,&geometry_info);
3218 geometry=DestroyString(geometry);
3219 new_image=RotateImage(*image,geometry_info.rho,exception);
3220 break;
3221 }
3222 break;
3223 }
3224 case 's':
3225 {
cristy947cb4c2011-10-20 18:41:46 +00003226 if (LocaleCompare("sample",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003227 {
3228 /*
3229 Sample image with pixel replication.
3230 */
3231 (void) SyncImageSettings(image_info,*image);
3232 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3233 new_image=SampleImage(*image,geometry.width,geometry.height,
3234 exception);
3235 break;
3236 }
cristy947cb4c2011-10-20 18:41:46 +00003237 if (LocaleCompare("scale",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003238 {
3239 /*
3240 Resize image.
3241 */
3242 (void) SyncImageSettings(image_info,*image);
3243 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3244 new_image=ScaleImage(*image,geometry.width,geometry.height,
3245 exception);
3246 break;
3247 }
cristy947cb4c2011-10-20 18:41:46 +00003248 if (LocaleCompare("selective-blur",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003249 {
3250 /*
3251 Selectively blur pixels within a contrast threshold.
3252 */
3253 (void) SyncImageSettings(image_info,*image);
3254 flags=ParseGeometry(argv[1],&geometry_info);
3255 if ((flags & PercentValue) != 0)
3256 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3257 new_image=SelectiveBlurImage(*image,geometry_info.rho,
3258 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3259 break;
3260 }
cristy947cb4c2011-10-20 18:41:46 +00003261 if (LocaleCompare("separate",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003262 {
3263 /*
3264 Break channels into separate images.
3265 WARNING: This can generate multiple images!
3266 */
3267 (void) SyncImageSettings(image_info,*image);
3268 new_image=SeparateImages(*image,exception);
3269 break;
3270 }
cristy947cb4c2011-10-20 18:41:46 +00003271 if (LocaleCompare("sepia-tone",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003272 {
3273 double
3274 threshold;
3275
3276 /*
3277 Sepia-tone image.
3278 */
3279 (void) SyncImageSettings(image_info,*image);
3280 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3281 new_image=SepiaToneImage(*image,threshold,exception);
3282 break;
3283 }
cristy947cb4c2011-10-20 18:41:46 +00003284 if (LocaleCompare("segment",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003285 {
3286 /*
3287 Segment image.
3288 */
3289 (void) SyncImageSettings(image_info,*image);
3290 flags=ParseGeometry(argv[1],&geometry_info);
3291 if ((flags & SigmaValue) == 0)
3292 geometry_info.sigma=1.0;
3293 (void) SegmentImage(*image,(*image)->colorspace,
3294 image_info->verbose,geometry_info.rho,geometry_info.sigma,
3295 exception);
3296 break;
3297 }
cristy947cb4c2011-10-20 18:41:46 +00003298 if (LocaleCompare("set",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003299 {
3300 char
3301 *value;
3302
anthony805a2d42011-09-25 08:25:12 +00003303 if (*argv[0] == '+')
3304 {
3305 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3306 (void) DeleteImageRegistry(argv[1]+9);
3307 else
3308 if (LocaleNCompare(argv[1],"argv[0]:",7) == 0)
3309 {
3310 (void) DeleteImageOption(image_info,argv[1]+7);
3311 (void) DeleteImageArtifact(*image,argv[1]+7);
3312 }
3313 else
3314 (void) DeleteImageProperty(*image,argv[1]);
3315 break;
3316 }
3317 value=InterpretImageProperties(image_info,*image,argv[2],
3318 exception);
3319 if (value == (char *) NULL)
3320 break;
3321 if (LocaleNCompare(argv[1],"registry:",9) == 0)
3322 (void) SetImageRegistry(StringRegistryType,argv[1]+9,value,
3323 exception);
3324 else
anthonya89dd172011-10-04 13:29:35 +00003325 if (LocaleNCompare(argv[1],"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003326 {
3327 (void) SetImageOption(image_info,argv[1]+7,value);
anthony805a2d42011-09-25 08:25:12 +00003328 (void) SetImageArtifact(*image,argv[1]+7,value);
3329 }
3330 else
cristyd15e6592011-10-15 00:13:06 +00003331 (void) SetImageProperty(*image,argv[1],value,exception);
anthony805a2d42011-09-25 08:25:12 +00003332 value=DestroyString(value);
3333 break;
3334 }
cristy947cb4c2011-10-20 18:41:46 +00003335 if (LocaleCompare("shade",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003336 {
3337 /*
3338 Shade image.
3339 */
3340 (void) SyncImageSettings(image_info,*image);
3341 flags=ParseGeometry(argv[1],&geometry_info);
3342 if ((flags & SigmaValue) == 0)
3343 geometry_info.sigma=1.0;
3344 new_image=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue :
3345 MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
3346 break;
3347 }
cristy947cb4c2011-10-20 18:41:46 +00003348 if (LocaleCompare("shadow",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003349 {
3350 /*
3351 Shadow image.
3352 */
3353 (void) SyncImageSettings(image_info,*image);
3354 flags=ParseGeometry(argv[1],&geometry_info);
3355 if ((flags & SigmaValue) == 0)
3356 geometry_info.sigma=1.0;
3357 if ((flags & XiValue) == 0)
3358 geometry_info.xi=4.0;
3359 if ((flags & PsiValue) == 0)
3360 geometry_info.psi=4.0;
3361 new_image=ShadowImage(*image,geometry_info.rho,
3362 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3363 ceil(geometry_info.psi-0.5),exception);
3364 break;
3365 }
cristy947cb4c2011-10-20 18:41:46 +00003366 if (LocaleCompare("sharpen",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003367 {
3368 /*
3369 Sharpen image.
3370 */
3371 (void) SyncImageSettings(image_info,*image);
3372 flags=ParseGeometry(argv[1],&geometry_info);
3373 if ((flags & SigmaValue) == 0)
3374 geometry_info.sigma=1.0;
3375 if ((flags & XiValue) == 0)
3376 geometry_info.xi=0.0;
3377 new_image=SharpenImage(*image,geometry_info.rho,
3378 geometry_info.sigma,geometry_info.xi,exception);
3379 break;
3380 }
cristy947cb4c2011-10-20 18:41:46 +00003381 if (LocaleCompare("shave",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003382 {
3383 /*
3384 Shave the image edges.
3385 */
3386 (void) SyncImageSettings(image_info,*image);
3387 flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3388 new_image=ShaveImage(*image,&geometry,exception);
3389 break;
3390 }
cristy947cb4c2011-10-20 18:41:46 +00003391 if (LocaleCompare("shear",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003392 {
3393 /*
3394 Shear image.
3395 */
3396 (void) SyncImageSettings(image_info,*image);
3397 flags=ParseGeometry(argv[1],&geometry_info);
3398 if ((flags & SigmaValue) == 0)
3399 geometry_info.sigma=geometry_info.rho;
3400 new_image=ShearImage(*image,geometry_info.rho,
3401 geometry_info.sigma,exception);
3402 break;
3403 }
cristy947cb4c2011-10-20 18:41:46 +00003404 if (LocaleCompare("sigmoidal-contrast",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003405 {
3406 /*
3407 Sigmoidal non-linearity contrast control.
3408 */
3409 (void) SyncImageSettings(image_info,*image);
3410 flags=ParseGeometry(argv[1],&geometry_info);
3411 if ((flags & SigmaValue) == 0)
3412 geometry_info.sigma=(double) QuantumRange/2.0;
3413 if ((flags & PercentValue) != 0)
3414 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3415 100.0;
3416 (void) SigmoidalContrastImage(*image,(*argv[0] == '-') ?
3417 MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
3418 exception);
3419 break;
3420 }
cristy947cb4c2011-10-20 18:41:46 +00003421 if (LocaleCompare("sketch",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003422 {
3423 /*
3424 Sketch image.
3425 */
3426 (void) SyncImageSettings(image_info,*image);
3427 flags=ParseGeometry(argv[1],&geometry_info);
3428 if ((flags & SigmaValue) == 0)
3429 geometry_info.sigma=1.0;
3430 new_image=SketchImage(*image,geometry_info.rho,
3431 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3432 break;
3433 }
cristy947cb4c2011-10-20 18:41:46 +00003434 if (LocaleCompare("solarize",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003435 {
3436 double
3437 threshold;
3438
3439 (void) SyncImageSettings(image_info,*image);
3440 threshold=SiPrefixToDouble(argv[1],QuantumRange);
3441 (void) SolarizeImage(*image,threshold,exception);
3442 break;
3443 }
cristy947cb4c2011-10-20 18:41:46 +00003444 if (LocaleCompare("sparse-color",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003445 {
3446 SparseColorMethod
3447 method;
3448
3449 char
3450 *arguments;
3451
3452 /*
3453 Sparse Color Interpolated Gradient
3454 */
3455 (void) SyncImageSettings(image_info,*image);
3456 method=(SparseColorMethod) ParseCommandOption(
3457 MagickSparseColorOptions,MagickFalse,argv[1]);
3458 arguments=InterpretImageProperties(image_info,*image,argv[2],
3459 exception);
3460 if (arguments == (char *) NULL)
3461 break;
3462 new_image=SparseColorOption(*image,method,arguments,
3463 argv[0][0] == '+' ? MagickTrue : MagickFalse,exception);
3464 arguments=DestroyString(arguments);
3465 break;
3466 }
cristy947cb4c2011-10-20 18:41:46 +00003467 if (LocaleCompare("splice",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003468 {
3469 /*
3470 Splice a solid color into the image.
3471 */
3472 (void) SyncImageSettings(image_info,*image);
3473 (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
3474 new_image=SpliceImage(*image,&geometry,exception);
3475 break;
3476 }
cristy947cb4c2011-10-20 18:41:46 +00003477 if (LocaleCompare("spread",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003478 {
3479 /*
3480 Spread an image.
3481 */
3482 (void) SyncImageSettings(image_info,*image);
3483 (void) ParseGeometry(argv[1],&geometry_info);
3484 new_image=SpreadImage(*image,geometry_info.rho,
3485 interpolate_method,exception);
3486 break;
3487 }
cristy947cb4c2011-10-20 18:41:46 +00003488 if (LocaleCompare("statistic",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003489 {
3490 StatisticType
3491 type;
3492
3493 (void) SyncImageSettings(image_info,*image);
3494 type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
3495 MagickFalse,argv[1]);
3496 (void) ParseGeometry(argv[2],&geometry_info);
3497 new_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
3498 (size_t) geometry_info.sigma,exception);
3499 break;
3500 }
cristy947cb4c2011-10-20 18:41:46 +00003501 if (LocaleCompare("stretch",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003502 {
3503 if (*argv[0] == '+')
3504 {
3505 draw_info->stretch=UndefinedStretch;
3506 break;
3507 }
3508 draw_info->stretch=(StretchType) ParseCommandOption(
3509 MagickStretchOptions,MagickFalse,argv[1]);
3510 break;
3511 }
cristy947cb4c2011-10-20 18:41:46 +00003512 if (LocaleCompare("strip",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003513 {
3514 /*
3515 Strip image of profiles and comments.
3516 */
3517 (void) SyncImageSettings(image_info,*image);
anthony6613bf32011-10-15 07:24:44 +00003518 (void) StripImage(*image,exception);
anthony805a2d42011-09-25 08:25:12 +00003519 break;
3520 }
cristy947cb4c2011-10-20 18:41:46 +00003521 if (LocaleCompare("stroke",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003522 {
3523 ExceptionInfo
3524 *sans;
3525
3526 if (*argv[0] == '+')
3527 {
anthony1afdc7a2011-10-05 11:54:28 +00003528 (void) QueryColorCompliance("none",AllCompliance,&draw_info->stroke,
anthonya89dd172011-10-04 13:29:35 +00003529 exception);
anthony805a2d42011-09-25 08:25:12 +00003530 if (draw_info->stroke_pattern != (Image *) NULL)
3531 draw_info->stroke_pattern=DestroyImage(
3532 draw_info->stroke_pattern);
3533 break;
3534 }
3535 sans=AcquireExceptionInfo();
anthony1afdc7a2011-10-05 11:54:28 +00003536 status=QueryColorCompliance(argv[1],AllCompliance,&draw_info->stroke,sans);
anthony805a2d42011-09-25 08:25:12 +00003537 sans=DestroyExceptionInfo(sans);
3538 if (status == MagickFalse)
3539 draw_info->stroke_pattern=GetImageCache(image_info,argv[1],
3540 exception);
3541 break;
3542 }
cristy947cb4c2011-10-20 18:41:46 +00003543 if (LocaleCompare("strokewidth",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003544 {
3545 draw_info->stroke_width=InterpretLocaleValue(argv[1],
3546 (char **) NULL);
3547 break;
3548 }
cristy947cb4c2011-10-20 18:41:46 +00003549 if (LocaleCompare("style",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003550 {
3551 if (*argv[0] == '+')
3552 {
3553 draw_info->style=UndefinedStyle;
3554 break;
3555 }
3556 draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
3557 MagickFalse,argv[1]);
3558 break;
3559 }
cristy947cb4c2011-10-20 18:41:46 +00003560 if (LocaleCompare("swirl",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003561 {
3562 /*
3563 Swirl image.
3564 */
3565 (void) SyncImageSettings(image_info,*image);
3566 (void) ParseGeometry(argv[1],&geometry_info);
3567 new_image=SwirlImage(*image,geometry_info.rho,
3568 interpolate_method,exception);
3569 break;
3570 }
3571 break;
3572 }
3573 case 't':
3574 {
cristy947cb4c2011-10-20 18:41:46 +00003575 if (LocaleCompare("threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003576 {
3577 double
3578 threshold;
3579
3580 /*
3581 Threshold image.
3582 */
3583 (void) SyncImageSettings(image_info,*image);
3584 if (*argv[0] == '+')
3585 threshold=(double) QuantumRange/2;
3586 else
3587 threshold=SiPrefixToDouble(argv[1],QuantumRange);
anthony6613bf32011-10-15 07:24:44 +00003588 (void) BilevelImage(*image,threshold,exception);
anthony805a2d42011-09-25 08:25:12 +00003589 break;
3590 }
cristy947cb4c2011-10-20 18:41:46 +00003591 if (LocaleCompare("thumbnail",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003592 {
3593 /*
3594 Thumbnail image.
3595 */
3596 (void) SyncImageSettings(image_info,*image);
3597 (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3598 new_image=ThumbnailImage(*image,geometry.width,geometry.height,
3599 exception);
3600 break;
3601 }
cristy947cb4c2011-10-20 18:41:46 +00003602 if (LocaleCompare("tile",argv[0]+1) == 0)
3603 {
3604 if (*argv[0] == '+')
3605 {
3606 if (draw_info->fill_pattern != (Image *) NULL)
3607 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
3608 break;
3609 }
3610 draw_info->fill_pattern=GetImageCache(image_info,argv[1],
3611 exception);
3612 break;
3613 }
3614 if (LocaleCompare("tint",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003615 {
3616 /*
3617 Tint the image.
3618 */
3619 (void) SyncImageSettings(image_info,*image);
3620 new_image=TintImage(*image,argv[1],&fill,exception);
3621 break;
3622 }
cristy947cb4c2011-10-20 18:41:46 +00003623 if (LocaleCompare("transform",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003624 {
3625 /*
3626 Affine transform image.
3627 */
3628 (void) SyncImageSettings(image_info,*image);
3629 new_image=AffineTransformImage(*image,&draw_info->affine,
3630 exception);
3631 break;
3632 }
cristy947cb4c2011-10-20 18:41:46 +00003633 if (LocaleCompare("transparent",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003634 {
3635 PixelInfo
3636 target;
3637
3638 (void) SyncImageSettings(image_info,*image);
cristy269c9412011-10-13 23:41:15 +00003639 (void) QueryColorCompliance(argv[1],AllCompliance,&target,
anthonya89dd172011-10-04 13:29:35 +00003640 exception);
anthony805a2d42011-09-25 08:25:12 +00003641 (void) TransparentPaintImage(*image,&target,(Quantum)
3642 TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue,
cristy82d7af52011-10-16 16:26:41 +00003643 exception);
anthony805a2d42011-09-25 08:25:12 +00003644 break;
3645 }
cristy947cb4c2011-10-20 18:41:46 +00003646 if (LocaleCompare("transpose",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003647 {
3648 /*
3649 Transpose image scanlines.
3650 */
3651 (void) SyncImageSettings(image_info,*image);
3652 new_image=TransposeImage(*image,exception);
3653 break;
3654 }
cristy947cb4c2011-10-20 18:41:46 +00003655 if (LocaleCompare("transverse",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003656 {
3657 /*
3658 Transverse image scanlines.
3659 */
3660 (void) SyncImageSettings(image_info,*image);
3661 new_image=TransverseImage(*image,exception);
3662 break;
3663 }
cristy947cb4c2011-10-20 18:41:46 +00003664 if (LocaleCompare("treedepth",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003665 {
3666 quantize_info->tree_depth=StringToUnsignedLong(argv[1]);
3667 break;
3668 }
cristy947cb4c2011-10-20 18:41:46 +00003669 if (LocaleCompare("trim",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003670 {
3671 /*
3672 Trim image.
3673 */
3674 (void) SyncImageSettings(image_info,*image);
3675 new_image=TrimImage(*image,exception);
3676 break;
3677 }
cristy947cb4c2011-10-20 18:41:46 +00003678 if (LocaleCompare("type",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003679 {
3680 ImageType
3681 type;
3682
3683 (void) SyncImageSettings(image_info,*image);
3684 if (*argv[0] == '+')
3685 type=UndefinedType;
3686 else
3687 type=(ImageType) ParseCommandOption(MagickTypeOptions,MagickFalse,
3688 argv[1]);
3689 (*image)->type=UndefinedType;
3690 (void) SetImageType(*image,type,exception);
3691 break;
3692 }
3693 break;
3694 }
3695 case 'u':
3696 {
cristy947cb4c2011-10-20 18:41:46 +00003697 if (LocaleCompare("undercolor",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003698 {
anthony1afdc7a2011-10-05 11:54:28 +00003699 (void) QueryColorCompliance(argv[1],AllCompliance,&draw_info->undercolor,
anthony805a2d42011-09-25 08:25:12 +00003700 exception);
3701 break;
3702 }
cristy947cb4c2011-10-20 18:41:46 +00003703 if (LocaleCompare("unique",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003704 {
3705 if (*argv[0] == '+')
3706 {
3707 (void) DeleteImageArtifact(*image,"identify:unique-colors");
3708 break;
3709 }
3710 (void) SetImageArtifact(*image,"identify:unique-colors","true");
3711 (void) SetImageArtifact(*image,"verbose","true");
3712 break;
3713 }
cristy947cb4c2011-10-20 18:41:46 +00003714 if (LocaleCompare("unique-colors",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003715 {
3716 /*
3717 Unique image colors.
3718 */
3719 (void) SyncImageSettings(image_info,*image);
3720 new_image=UniqueImageColors(*image,exception);
3721 break;
3722 }
cristy947cb4c2011-10-20 18:41:46 +00003723 if (LocaleCompare("unsharp",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003724 {
3725 /*
3726 Unsharp mask image.
3727 */
3728 (void) SyncImageSettings(image_info,*image);
3729 flags=ParseGeometry(argv[1],&geometry_info);
3730 if ((flags & SigmaValue) == 0)
3731 geometry_info.sigma=1.0;
3732 if ((flags & XiValue) == 0)
3733 geometry_info.xi=1.0;
3734 if ((flags & PsiValue) == 0)
3735 geometry_info.psi=0.05;
3736 new_image=UnsharpMaskImage(*image,geometry_info.rho,
3737 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3738 break;
3739 }
3740 break;
3741 }
3742 case 'v':
3743 {
cristy947cb4c2011-10-20 18:41:46 +00003744 if (LocaleCompare("verbose",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003745 {
cristy947cb4c2011-10-20 18:41:46 +00003746 (void) SetImageArtifact(*image,argv[0]+1,
anthony805a2d42011-09-25 08:25:12 +00003747 *argv[0] == '+' ? "false" : "true");
3748 break;
3749 }
cristy947cb4c2011-10-20 18:41:46 +00003750 if (LocaleCompare("vignette",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003751 {
3752 /*
3753 Vignette image.
3754 */
3755 (void) SyncImageSettings(image_info,*image);
3756 flags=ParseGeometry(argv[1],&geometry_info);
3757 if ((flags & SigmaValue) == 0)
3758 geometry_info.sigma=1.0;
3759 if ((flags & XiValue) == 0)
3760 geometry_info.xi=0.1*(*image)->columns;
3761 if ((flags & PsiValue) == 0)
3762 geometry_info.psi=0.1*(*image)->rows;
3763 new_image=VignetteImage(*image,geometry_info.rho,
3764 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3765 ceil(geometry_info.psi-0.5),exception);
3766 break;
3767 }
cristy947cb4c2011-10-20 18:41:46 +00003768 if (LocaleCompare("virtual-pixel",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003769 {
3770 if (*argv[0] == '+')
3771 {
3772 (void) SetImageVirtualPixelMethod(*image,
3773 UndefinedVirtualPixelMethod);
3774 break;
3775 }
3776 (void) SetImageVirtualPixelMethod(*image,(VirtualPixelMethod)
3777 ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
3778 argv[1]));
3779 break;
3780 }
3781 break;
3782 }
3783 case 'w':
3784 {
cristy947cb4c2011-10-20 18:41:46 +00003785 if (LocaleCompare("wave",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003786 {
3787 /*
3788 Wave image.
3789 */
3790 (void) SyncImageSettings(image_info,*image);
3791 flags=ParseGeometry(argv[1],&geometry_info);
3792 if ((flags & SigmaValue) == 0)
3793 geometry_info.sigma=1.0;
3794 new_image=WaveImage(*image,geometry_info.rho,
anthonya89dd172011-10-04 13:29:35 +00003795 geometry_info.sigma,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003796 break;
3797 }
cristy947cb4c2011-10-20 18:41:46 +00003798 if (LocaleCompare("weight",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003799 {
3800 draw_info->weight=StringToUnsignedLong(argv[1]);
3801 if (LocaleCompare(argv[1],"all") == 0)
3802 draw_info->weight=0;
3803 if (LocaleCompare(argv[1],"bold") == 0)
3804 draw_info->weight=700;
3805 if (LocaleCompare(argv[1],"bolder") == 0)
3806 if (draw_info->weight <= 800)
3807 draw_info->weight+=100;
3808 if (LocaleCompare(argv[1],"lighter") == 0)
3809 if (draw_info->weight >= 100)
3810 draw_info->weight-=100;
3811 if (LocaleCompare(argv[1],"normal") == 0)
3812 draw_info->weight=400;
3813 break;
3814 }
cristy947cb4c2011-10-20 18:41:46 +00003815 if (LocaleCompare("white-threshold",argv[0]+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003816 {
cristy947cb4c2011-10-20 18:41:46 +00003817 /*
3818 White threshold image.
3819 */
anthony805a2d42011-09-25 08:25:12 +00003820 (void) SyncImageSettings(image_info,*image);
3821 (void) WhiteThresholdImage(*image,argv[1],exception);
anthony805a2d42011-09-25 08:25:12 +00003822 break;
3823 }
3824 break;
3825 }
3826 default:
3827 break;
3828 }
3829 /*
3830 Replace current image with any image that was generated
3831 */
3832 if (new_image != (Image *) NULL)
3833 ReplaceImageInListReturnLast(image,new_image);
3834
3835 /*
3836 Free resources.
3837 */
3838 quantize_info=DestroyQuantizeInfo(quantize_info);
3839 draw_info=DestroyDrawInfo(draw_info);
cristy82d7af52011-10-16 16:26:41 +00003840 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthonya89dd172011-10-04 13:29:35 +00003841 return(status == 0 ? MagickFalse : MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003842}
3843
3844/*
3845%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3846% %
3847% %
3848% %
3849+ S e q u e n c e O p e r a t i o n I m a g e s %
3850% %
3851% %
3852% %
3853%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3854%
3855% SequenceOperationImages() applies a single operation that apply to the
3856% entire image list (e.g. -append, -layers, -coalesce, etc.).
3857%
3858% The format of the MogrifyImage method is:
3859%
3860% MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3861% const int argc, const char **argv,Image **images,
3862% ExceptionInfo *exception)
3863%
3864% A description of each parameter follows:
3865%
3866% o image_info: the image info..
3867%
3868% o argc: Specifies a pointer to an integer describing the number of
3869% elements in the argument vector.
3870%
3871% o argv: Specifies a pointer to a text array containing the command line
3872% arguments.
3873%
3874% o images: pointer to pointer of the first image in image list.
3875%
3876% o exception: return any errors or warnings in this structure.
3877%
3878*/
3879WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
3880 const int argc,const char **argv,Image **images,ExceptionInfo *exception)
3881{
3882
3883 MagickStatusType
3884 status;
3885
3886 QuantizeInfo
3887 *quantize_info;
3888
3889 assert(image_info != (ImageInfo *) NULL);
3890 assert(image_info->signature == MagickSignature);
3891 assert(images != (Image **) NULL);
3892 assert((*images)->previous == (Image *) NULL);
3893 assert((*images)->signature == MagickSignature);
3894 if ((*images)->debug != MagickFalse)
3895 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3896 (*images)->filename);
anthonya89dd172011-10-04 13:29:35 +00003897 if ((argc <= 0) || (*argv == (char *) NULL))
3898 return(MagickTrue);
anthony805a2d42011-09-25 08:25:12 +00003899 status=MagickTrue;
3900
3901 switch (*(argv[0]+1))
3902 {
3903 case 'a':
3904 {
3905 if (LocaleCompare("affinity",argv[0]+1) == 0)
3906 {
3907 (void) SyncImagesSettings(image_info,*images);
3908 if (*argv[0] == '+')
3909 {
3910 (void) RemapImages(quantize_info,*images,(Image *) NULL,
3911 exception);
3912 break;
3913 }
3914 break;
3915 }
3916 if (LocaleCompare("append",argv[0]+1) == 0)
3917 {
3918 Image
3919 *append_image;
3920
3921 (void) SyncImagesSettings(image_info,*images);
3922 append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue :
3923 MagickFalse,exception);
3924 if (append_image == (Image *) NULL)
3925 {
3926 status=MagickFalse;
3927 break;
3928 }
3929 *images=DestroyImageList(*images);
3930 *images=append_image;
3931 break;
3932 }
3933 if (LocaleCompare("average",argv[0]+1) == 0)
3934 {
3935 Image
3936 *average_image;
3937
3938 /*
3939 Average an image sequence (deprecated).
3940 */
3941 (void) SyncImagesSettings(image_info,*images);
3942 average_image=EvaluateImages(*images,MeanEvaluateOperator,
3943 exception);
3944 if (average_image == (Image *) NULL)
3945 {
3946 status=MagickFalse;
3947 break;
3948 }
3949 *images=DestroyImageList(*images);
3950 *images=average_image;
3951 break;
3952 }
3953 break;
3954 }
3955 case 'c':
3956 {
3957 if (LocaleCompare("channel",argv[0]+1) == 0)
3958 {
3959 ChannelType
3960 channel;
3961
3962 if (*argv[0] == '+')
3963 {
3964 channel=DefaultChannels;
3965 break;
3966 }
3967 channel=(ChannelType) ParseChannelOption(argv[1]);
3968 SetPixelChannelMap(*images,channel);
3969 break;
3970 }
3971 if (LocaleCompare("clut",argv[0]+1) == 0)
3972 {
3973 Image
3974 *clut_image,
3975 *image;
3976
3977 (void) SyncImagesSettings(image_info,*images);
3978 image=RemoveFirstImageFromList(images);
3979 clut_image=RemoveFirstImageFromList(images);
3980 if (clut_image == (Image *) NULL)
3981 {
3982 status=MagickFalse;
3983 break;
3984 }
anthonya89dd172011-10-04 13:29:35 +00003985 (void) ClutImage(image,clut_image,interpolate_method,exception);
anthony805a2d42011-09-25 08:25:12 +00003986 clut_image=DestroyImage(clut_image);
3987 *images=DestroyImageList(*images);
3988 *images=image;
3989 break;
3990 }
3991 if (LocaleCompare("coalesce",argv[0]+1) == 0)
3992 {
3993 Image
3994 *coalesce_image;
3995
3996 (void) SyncImagesSettings(image_info,*images);
3997 coalesce_image=CoalesceImages(*images,exception);
3998 if (coalesce_image == (Image *) NULL)
3999 {
4000 status=MagickFalse;
4001 break;
4002 }
4003 *images=DestroyImageList(*images);
4004 *images=coalesce_image;
4005 break;
4006 }
4007 if (LocaleCompare("combine",argv[0]+1) == 0)
4008 {
4009 Image
4010 *combine_image;
4011
4012 (void) SyncImagesSettings(image_info,*images);
4013 combine_image=CombineImages(*images,exception);
4014 if (combine_image == (Image *) NULL)
4015 {
4016 status=MagickFalse;
4017 break;
4018 }
4019 *images=DestroyImageList(*images);
4020 *images=combine_image;
4021 break;
4022 }
4023 if (LocaleCompare("composite",argv[0]+1) == 0)
4024 {
4025 Image
4026 *mask_image,
4027 *composite_image,
4028 *image;
4029
4030 RectangleInfo
4031 geometry;
4032
anthony5f867ae2011-10-09 10:28:34 +00004033 ComposeOperator
4034 compose;
4035
4036 const char*
4037 value;
4038
4039 value=GetImageOption(image_info,"compose");
4040 if (value != (const char *) NULL)
4041 compose=(CompositeOperator) ParseCommandOption(
4042 MagickComposeOptions,MagickFalse,value);
4043 else
4044 compose=OverCompositeOp; /* use Over not image->compose */
4045
4046 const char*
4047 value=GetImageOption(image_info,"compose");
4048
4049 if (value != (const char *) NULL)
4050 compose=(CompositeOperator) ParseCommandOption(
4051 MagickComposeOptions,MagickFalse,value);
4052 else
4053 compose=OverCompositeOp; /* use Over not image->compose */
4054
4055
anthony805a2d42011-09-25 08:25:12 +00004056 (void) SyncImagesSettings(image_info,*images);
4057 image=RemoveFirstImageFromList(images);
4058 composite_image=RemoveFirstImageFromList(images);
4059 if (composite_image == (Image *) NULL)
4060 {
4061 status=MagickFalse;
4062 break;
4063 }
4064 (void) TransformImage(&composite_image,(char *) NULL,
anthony6613bf32011-10-15 07:24:44 +00004065 composite_image->geometry,exception);
anthony805a2d42011-09-25 08:25:12 +00004066 SetGeometry(composite_image,&geometry);
4067 (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
4068 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
4069 &geometry);
4070 mask_image=RemoveFirstImageFromList(images);
4071 if (mask_image != (Image *) NULL)
4072 {
anthony5f867ae2011-10-09 10:28:34 +00004073 if ((compose == DisplaceCompositeOp) ||
4074 (compose == DistortCompositeOp))
anthony805a2d42011-09-25 08:25:12 +00004075 {
4076 /*
4077 Merge Y displacement into X displacement image.
4078 */
4079 (void) CompositeImage(composite_image,CopyGreenCompositeOp,
anthony6613bf32011-10-15 07:24:44 +00004080 mask_image,0,0,exception);
anthony805a2d42011-09-25 08:25:12 +00004081 mask_image=DestroyImage(mask_image);
4082 }
4083 else
4084 {
4085 /*
4086 Set a blending mask for the composition.
4087 Posible error, what if image->mask already set.
4088 */
4089 image->mask=mask_image;
4090 (void) NegateImage(image->mask,MagickFalse,exception);
4091 }
4092 }
anthony5f867ae2011-10-09 10:28:34 +00004093 (void) CompositeImage(image,compose,composite_image,
anthony6613bf32011-10-15 07:24:44 +00004094 geometry.x,geometry.y,exception);
anthony805a2d42011-09-25 08:25:12 +00004095 if (mask_image != (Image *) NULL)
4096 mask_image=image->mask=DestroyImage(image->mask);
4097 composite_image=DestroyImage(composite_image);
anthony805a2d42011-09-25 08:25:12 +00004098 *images=DestroyImageList(*images);
4099 *images=image;
4100 break;
4101 }
4102 break;
4103 }
4104 case 'd':
4105 {
4106 if (LocaleCompare("deconstruct",argv[0]+1) == 0)
4107 {
4108 Image
4109 *deconstruct_image;
4110
4111 (void) SyncImagesSettings(image_info,*images);
4112 deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
4113 exception);
4114 if (deconstruct_image == (Image *) NULL)
4115 {
4116 status=MagickFalse;
4117 break;
4118 }
4119 *images=DestroyImageList(*images);
4120 *images=deconstruct_image;
4121 break;
4122 }
4123 if (LocaleCompare("delete",argv[0]+1) == 0)
4124 {
4125 if (*argv[0] == '+')
4126 DeleteImages(images,"-1",exception);
4127 else
4128 DeleteImages(images,argv[1],exception);
4129 break;
4130 }
4131 if (LocaleCompare("dither",argv[0]+1) == 0)
4132 {
4133 if (*argv[0] == '+')
4134 {
4135 quantize_info->dither=MagickFalse;
4136 break;
4137 }
4138 quantize_info->dither=MagickTrue;
4139 quantize_info->dither_method=(DitherMethod) ParseCommandOption(
4140 MagickDitherOptions,MagickFalse,argv[1]);
4141 break;
4142 }
4143 if (LocaleCompare("duplicate",argv[0]+1) == 0)
4144 {
4145 Image
4146 *duplicate_images;
4147
4148 if (*argv[0] == '+')
4149 duplicate_images=DuplicateImages(*images,1,"-1",exception);
4150 else
4151 {
4152 const char
4153 *p;
4154
4155 size_t
4156 number_duplicates;
4157
4158 number_duplicates=(size_t) StringToLong(argv[1]);
4159 p=strchr(argv[1],',');
4160 if (p == (const char *) NULL)
4161 duplicate_images=DuplicateImages(*images,number_duplicates,
4162 "-1",exception);
4163 else
4164 duplicate_images=DuplicateImages(*images,number_duplicates,p,
4165 exception);
4166 }
4167 AppendImageToList(images, duplicate_images);
4168 (void) SyncImagesSettings(image_info,*images);
4169 break;
4170 }
4171 break;
4172 }
4173 case 'e':
4174 {
4175 if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0)
4176 {
4177 Image
4178 *evaluate_image;
4179
4180 MagickEvaluateOperator
4181 op;
4182
4183 (void) SyncImageSettings(image_info,*images);
4184 op=(MagickEvaluateOperator) ParseCommandOption(
4185 MagickEvaluateOptions,MagickFalse,argv[1]);
4186 evaluate_image=EvaluateImages(*images,op,exception);
4187 if (evaluate_image == (Image *) NULL)
4188 {
4189 status=MagickFalse;
4190 break;
4191 }
4192 *images=DestroyImageList(*images);
4193 *images=evaluate_image;
4194 break;
4195 }
4196 break;
4197 }
4198 case 'f':
4199 {
4200 if (LocaleCompare("fft",argv[0]+1) == 0)
4201 {
4202 Image
4203 *fourier_image;
4204
4205 /*
4206 Implements the discrete Fourier transform (DFT).
4207 */
4208 (void) SyncImageSettings(image_info,*images);
4209 fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ?
4210 MagickTrue : MagickFalse,exception);
4211 if (fourier_image == (Image *) NULL)
4212 break;
4213 *images=DestroyImage(*images);
4214 *images=fourier_image;
4215 break;
4216 }
4217 if (LocaleCompare("flatten",argv[0]+1) == 0)
4218 {
4219 Image
4220 *flatten_image;
4221
4222 (void) SyncImagesSettings(image_info,*images);
4223 flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
4224 if (flatten_image == (Image *) NULL)
4225 break;
4226 *images=DestroyImageList(*images);
4227 *images=flatten_image;
4228 break;
4229 }
4230 if (LocaleCompare("fx",argv[0]+1) == 0)
4231 {
4232 Image
4233 *fx_image;
4234
4235 (void) SyncImagesSettings(image_info,*images);
4236 fx_image=FxImage(*images,argv[1],exception);
4237 if (fx_image == (Image *) NULL)
4238 {
4239 status=MagickFalse;
4240 break;
4241 }
4242 *images=DestroyImageList(*images);
4243 *images=fx_image;
4244 break;
4245 }
4246 break;
4247 }
4248 case 'h':
4249 {
4250 if (LocaleCompare("hald-clut",argv[0]+1) == 0)
4251 {
4252 Image
4253 *hald_image,
4254 *image;
4255
4256 (void) SyncImagesSettings(image_info,*images);
4257 image=RemoveFirstImageFromList(images);
4258 hald_image=RemoveFirstImageFromList(images);
4259 if (hald_image == (Image *) NULL)
4260 {
4261 status=MagickFalse;
4262 break;
4263 }
4264 (void) HaldClutImage(image,hald_image,exception);
4265 hald_image=DestroyImage(hald_image);
4266 if (*images != (Image *) NULL)
4267 *images=DestroyImageList(*images);
4268 *images=image;
4269 break;
4270 }
4271 break;
4272 }
4273 case 'i':
4274 {
4275 if (LocaleCompare("ift",argv[0]+1) == 0)
4276 {
4277 Image
4278 *fourier_image,
4279 *magnitude_image,
4280 *phase_image;
4281
4282 /*
4283 Implements the inverse fourier discrete Fourier transform (DFT).
4284 */
4285 (void) SyncImagesSettings(image_info,*images);
4286 magnitude_image=RemoveFirstImageFromList(images);
4287 phase_image=RemoveFirstImageFromList(images);
4288 if (phase_image == (Image *) NULL)
4289 {
4290 status=MagickFalse;
4291 break;
4292 }
4293 fourier_image=InverseFourierTransformImage(magnitude_image,
4294 phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception);
4295 if (fourier_image == (Image *) NULL)
4296 break;
4297 if (*images != (Image *) NULL)
4298 *images=DestroyImage(*images);
4299 *images=fourier_image;
4300 break;
4301 }
4302 if (LocaleCompare("insert",argv[0]+1) == 0)
4303 {
4304 Image
4305 *p,
4306 *q;
4307
4308 index=0;
4309 if (*argv[0] != '+')
4310 index=(ssize_t) StringToLong(argv[1]);
4311 p=RemoveLastImageFromList(images);
4312 if (p == (Image *) NULL)
4313 {
4314 (void) ThrowMagickException(exception,GetMagickModule(),
4315 OptionError,"NoSuchImage","`%s'",argv[1]);
4316 status=MagickFalse;
4317 break;
4318 }
4319 q=p;
4320 if (index == 0)
4321 PrependImageToList(images,q);
4322 else
4323 if (index == (ssize_t) GetImageListLength(*images))
4324 AppendImageToList(images,q);
4325 else
4326 {
4327 q=GetImageFromList(*images,index-1);
4328 if (q == (Image *) NULL)
4329 {
4330 (void) ThrowMagickException(exception,GetMagickModule(),
4331 OptionError,"NoSuchImage","`%s'",argv[1]);
4332 status=MagickFalse;
4333 break;
4334 }
4335 InsertImageInList(&q,p);
4336 }
4337 *images=GetFirstImageInList(q);
4338 break;
4339 }
4340 if (LocaleCompare("interpolate",argv[0]+1) == 0)
4341 {
4342 interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
4343 MagickInterpolateOptions,MagickFalse,argv[1]);
4344 break;
4345 }
4346 break;
4347 }
4348 case 'l':
4349 {
4350 if (LocaleCompare("layers",argv[0]+1) == 0)
4351 {
4352 Image
4353 *layers;
4354
4355 ImageLayerMethod
4356 method;
4357
4358 (void) SyncImagesSettings(image_info,*images);
4359 layers=(Image *) NULL;
4360 method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
4361 MagickFalse,argv[1]);
4362 switch (method)
4363 {
4364 case CoalesceLayer:
4365 {
4366 layers=CoalesceImages(*images,exception);
4367 break;
4368 }
4369 case CompareAnyLayer:
4370 case CompareClearLayer:
4371 case CompareOverlayLayer:
4372 default:
4373 {
4374 layers=CompareImagesLayers(*images,method,exception);
4375 break;
4376 }
4377 case MergeLayer:
4378 case FlattenLayer:
4379 case MosaicLayer:
4380 case TrimBoundsLayer:
4381 {
4382 layers=MergeImageLayers(*images,method,exception);
4383 break;
4384 }
4385 case DisposeLayer:
4386 {
4387 layers=DisposeImages(*images,exception);
4388 break;
4389 }
4390 case OptimizeImageLayer:
4391 {
4392 layers=OptimizeImageLayers(*images,exception);
4393 break;
4394 }
4395 case OptimizePlusLayer:
4396 {
4397 layers=OptimizePlusImageLayers(*images,exception);
4398 break;
4399 }
4400 case OptimizeTransLayer:
4401 {
4402 OptimizeImageTransparency(*images,exception);
4403 break;
4404 }
4405 case RemoveDupsLayer:
4406 {
4407 RemoveDuplicateLayers(images,exception);
4408 break;
4409 }
4410 case RemoveZeroLayer:
4411 {
4412 RemoveZeroDelayLayers(images,exception);
4413 break;
4414 }
4415 case OptimizeLayer:
4416 {
4417 /*
4418 General Purpose, GIF Animation Optimizer.
4419 */
4420 layers=CoalesceImages(*images,exception);
4421 if (layers == (Image *) NULL)
4422 {
4423 status=MagickFalse;
4424 break;
4425 }
4426 *images=DestroyImageList(*images);
4427 *images=layers;
4428 layers=OptimizeImageLayers(*images,exception);
4429 if (layers == (Image *) NULL)
4430 {
4431 status=MagickFalse;
4432 break;
4433 }
4434 *images=DestroyImageList(*images);
4435 *images=layers;
4436 layers=(Image *) NULL;
4437 OptimizeImageTransparency(*images,exception);
4438 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4439 exception);
4440 break;
4441 }
4442 case CompositeLayer:
4443 {
anthony805a2d42011-09-25 08:25:12 +00004444 Image
4445 *source;
4446
4447 RectangleInfo
4448 geometry;
4449
anthony5f867ae2011-10-09 10:28:34 +00004450 ComposeOperator
4451 compose;
4452
4453 const char*
4454 value;
4455
4456 value=GetImageOption(image_info,"compose");
4457 if (value != (const char *) NULL)
4458 compose=(CompositeOperator) ParseCommandOption(
4459 MagickComposeOptions,MagickFalse,value);
4460 else
4461 compose=OverCompositeOp; /* use Over not image->compose */
4462
anthony805a2d42011-09-25 08:25:12 +00004463 /*
4464 Split image sequence at the first 'NULL:' image.
4465 */
4466 source=(*images);
4467 while (source != (Image *) NULL)
4468 {
4469 source=GetNextImageInList(source);
4470 if ((source != (Image *) NULL) &&
4471 (LocaleCompare(source->magick,"NULL") == 0))
4472 break;
4473 }
4474 if (source != (Image *) NULL)
4475 {
4476 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4477 (GetNextImageInList(source) == (Image *) NULL))
4478 source=(Image *) NULL;
4479 else
4480 {
4481 /*
4482 Separate the two lists, junk the null: image.
4483 */
4484 source=SplitImageList(source->previous);
4485 DeleteImageFromList(&source);
4486 }
4487 }
4488 if (source == (Image *) NULL)
4489 {
4490 (void) ThrowMagickException(exception,GetMagickModule(),
4491 OptionError,"MissingNullSeparator","layers Composite");
4492 status=MagickFalse;
4493 break;
4494 }
4495 /*
4496 Adjust offset with gravity and virtual canvas.
4497 */
4498 SetGeometry(*images,&geometry);
4499 (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
4500 geometry.width=source->page.width != 0 ?
4501 source->page.width : source->columns;
4502 geometry.height=source->page.height != 0 ?
4503 source->page.height : source->rows;
4504 GravityAdjustGeometry((*images)->page.width != 0 ?
4505 (*images)->page.width : (*images)->columns,
4506 (*images)->page.height != 0 ? (*images)->page.height :
4507 (*images)->rows,(*images)->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004508
4509 /*
4510 Compose the two image sequences together
4511 */
anthony805a2d42011-09-25 08:25:12 +00004512 CompositeLayers(*images,compose,source,geometry.x,geometry.y,
4513 exception);
4514 source=DestroyImageList(source);
4515 break;
4516 }
4517 }
4518 if (layers == (Image *) NULL)
4519 break;
anthony805a2d42011-09-25 08:25:12 +00004520 *images=DestroyImageList(*images);
4521 *images=layers;
4522 break;
4523 }
4524 break;
4525 }
4526 case 'm':
4527 {
4528 if (LocaleCompare("map",argv[0]+1) == 0)
4529 {
4530 (void) SyncImagesSettings(image_info,*images);
4531 if (*argv[0] == '+')
4532 {
4533 (void) RemapImages(quantize_info,*images,(Image *) NULL,
4534 exception);
4535 break;
4536 }
4537 break;
4538 }
4539 if (LocaleCompare("maximum",argv[0]+1) == 0)
4540 {
4541 Image
4542 *maximum_image;
4543
4544 /*
4545 Maximum image sequence (deprecated).
4546 */
4547 (void) SyncImagesSettings(image_info,*images);
4548 maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
4549 if (maximum_image == (Image *) NULL)
4550 {
4551 status=MagickFalse;
4552 break;
4553 }
4554 *images=DestroyImageList(*images);
4555 *images=maximum_image;
4556 break;
4557 }
4558 if (LocaleCompare("minimum",argv[0]+1) == 0)
4559 {
4560 Image
4561 *minimum_image;
4562
4563 /*
4564 Minimum image sequence (deprecated).
4565 */
4566 (void) SyncImagesSettings(image_info,*images);
4567 minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
4568 if (minimum_image == (Image *) NULL)
4569 {
4570 status=MagickFalse;
4571 break;
4572 }
4573 *images=DestroyImageList(*images);
4574 *images=minimum_image;
4575 break;
4576 }
4577 if (LocaleCompare("morph",argv[0]+1) == 0)
4578 {
4579 Image
4580 *morph_image;
4581
4582 (void) SyncImagesSettings(image_info,*images);
4583 morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]),
4584 exception);
4585 if (morph_image == (Image *) NULL)
4586 {
4587 status=MagickFalse;
4588 break;
4589 }
4590 *images=DestroyImageList(*images);
4591 *images=morph_image;
4592 break;
4593 }
4594 if (LocaleCompare("mosaic",argv[0]+1) == 0)
4595 {
4596 Image
4597 *mosaic_image;
4598
4599 (void) SyncImagesSettings(image_info,*images);
4600 mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
4601 if (mosaic_image == (Image *) NULL)
4602 {
4603 status=MagickFalse;
4604 break;
4605 }
4606 *images=DestroyImageList(*images);
4607 *images=mosaic_image;
4608 break;
4609 }
4610 break;
4611 }
4612 case 'p':
4613 {
4614 if (LocaleCompare("print",argv[0]+1) == 0)
4615 {
4616 char
4617 *string;
4618
4619 (void) SyncImagesSettings(image_info,*images);
4620 string=InterpretImageProperties(image_info,*images,argv[1],
4621 exception);
4622 if (string == (char *) NULL)
4623 break;
4624 (void) FormatLocaleFile(stdout,"%s",string);
4625 string=DestroyString(string);
4626 }
4627 if (LocaleCompare("process",argv[0]+1) == 0)
4628 {
4629 char
4630 **arguments;
4631
4632 int
4633 j,
4634 number_arguments;
4635
4636 (void) SyncImagesSettings(image_info,*images);
4637 arguments=StringToArgv(argv[1],&number_arguments);
4638 if (arguments == (char **) NULL)
4639 break;
4640 if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
4641 {
4642 char
4643 breaker,
4644 quote,
4645 *token;
4646
4647 const char
4648 *arguments;
4649
4650 int
4651 next,
4652 status;
4653
4654 size_t
4655 length;
4656
4657 TokenInfo
4658 *token_info;
4659
4660 /*
4661 Support old style syntax, filter="-option arg".
4662 */
4663 length=strlen(argv[1]);
4664 token=(char *) NULL;
4665 if (~length >= (MaxTextExtent-1))
4666 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4667 sizeof(*token));
4668 if (token == (char *) NULL)
4669 break;
4670 next=0;
4671 arguments=argv[1];
4672 token_info=AcquireTokenInfo();
4673 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4674 "\"",'\0',&breaker,&next,&quote);
4675 token_info=DestroyTokenInfo(token_info);
4676 if (status == 0)
4677 {
4678 const char
4679 *argv;
4680
4681 argv=(&(arguments[next]));
4682 (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
4683 exception);
4684 }
4685 token=DestroyString(token);
4686 break;
4687 }
4688 (void) SubstituteString(&arguments[1],"-","");
4689 (void) InvokeDynamicImageFilter(arguments[1],&(*images),
4690 number_arguments-2,(const char **) arguments+2,exception);
4691 for (j=0; j < number_arguments; j++)
4692 arguments[j]=DestroyString(arguments[j]);
4693 arguments=(char **) RelinquishMagickMemory(arguments);
4694 break;
4695 }
4696 break;
4697 }
4698 case 'r':
4699 {
4700 if (LocaleCompare("reverse",argv[0]+1) == 0)
4701 {
4702 ReverseImageList(images);
anthony805a2d42011-09-25 08:25:12 +00004703 break;
4704 }
4705 break;
4706 }
4707 case 's':
4708 {
4709 if (LocaleCompare("smush",argv[0]+1) == 0)
4710 {
4711 Image
4712 *smush_image;
4713
4714 ssize_t
4715 offset;
4716
4717 (void) SyncImagesSettings(image_info,*images);
4718 offset=(ssize_t) StringToLong(argv[1]);
4719 smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue :
4720 MagickFalse,offset,exception);
4721 if (smush_image == (Image *) NULL)
4722 {
4723 status=MagickFalse;
4724 break;
4725 }
4726 *images=DestroyImageList(*images);
4727 *images=smush_image;
4728 break;
4729 }
4730 if (LocaleCompare("swap",argv[0]+1) == 0)
4731 {
4732 Image
4733 *p,
4734 *q,
4735 *swap;
4736
4737 ssize_t
4738 swap_index;
4739
4740 index=(-1);
4741 swap_index=(-2);
4742 if (*argv[0] != '+')
4743 {
4744 GeometryInfo
4745 geometry_info;
4746
4747 MagickStatusType
4748 flags;
4749
4750 swap_index=(-1);
4751 flags=ParseGeometry(argv[1],&geometry_info);
4752 index=(ssize_t) geometry_info.rho;
4753 if ((flags & SigmaValue) != 0)
4754 swap_index=(ssize_t) geometry_info.sigma;
4755 }
4756 p=GetImageFromList(*images,index);
4757 q=GetImageFromList(*images,swap_index);
4758 if ((p == (Image *) NULL) || (q == (Image *) NULL))
4759 {
4760 (void) ThrowMagickException(exception,GetMagickModule(),
4761 OptionError,"NoSuchImage","`%s'",(*images)->filename);
4762 status=MagickFalse;
4763 break;
4764 }
4765 if (p == q)
4766 break;
4767 swap=CloneImage(p,0,0,MagickTrue,exception);
4768 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
4769 ReplaceImageInList(&q,swap);
4770 *images=GetFirstImageInList(q);
4771 break;
4772 }
4773 break;
4774 }
4775 case 'w':
4776 {
4777 if (LocaleCompare("write",argv[0]+1) == 0)
4778 {
4779 char
4780 key[MaxTextExtent];
4781
4782 Image
4783 *write_images;
4784
4785 ImageInfo
4786 *write_info;
4787
4788 (void) SyncImagesSettings(image_info,*images);
4789 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]);
4790 (void) DeleteImageRegistry(key);
4791 write_images=(*images);
4792 if (*argv[0] == '+')
4793 write_images=CloneImageList(*images,exception);
4794 write_info=CloneImageInfo(image_info);
4795 status&=WriteImages(write_info,write_images,argv[1],exception);
4796 write_info=DestroyImageInfo(write_info);
4797 if (*argv[0] == '+')
4798 write_images=DestroyImageList(write_images);
4799 break;
4800 }
4801 break;
4802 }
4803 default:
4804 break;
4805 }
4806 quantize_info=DestroyQuantizeInfo(quantize_info);
4807
cristy82d7af52011-10-16 16:26:41 +00004808 status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
anthony805a2d42011-09-25 08:25:12 +00004809 return(status != 0 ? MagickTrue : MagickFalse);
4810}
cristy0a0ca4f2011-09-28 01:15:28 +00004811#endif