]> granicus.if.org Git - imagemagick/blob - MagickWand/operation.c
(no commit message)
[imagemagick] / MagickWand / operation.c
1 /*
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                                  %
17 %                               September 2011                                %
18 %                                                                             %
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 */
46 #if 0
47 \f
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 \f
58 /*
59   Define declarations.
60 */
61 #define UndefinedCompressionQuality  0UL
62 /*
63   Constant declaration. (temporary exports)
64 */
65 static const char
66   BackgroundColor[] = "#fff",  /* white */
67   BorderColor[] = "#dfdfdf",  /* gray */
68   MatteColor[] = "#bdbdbd";  /* gray */
69 \f
70 /*
71 ** Function to report on the progress of image operations
72 */
73 static 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 */
115 static 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 /*
146 ** 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.
152 */
153 static 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 */
294         (void) QueryMagickColorCompliance(token,&color,exception);
295         if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
296           sparse_arguments[x++] = QuantumScale*color.red;
297         if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
298           sparse_arguments[x++] = QuantumScale*color.green;
299         if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
300           sparse_arguments[x++] = QuantumScale*color.blue;
301         if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
302             (image->colorspace == CMYKColorspace))
303           sparse_arguments[x++] = QuantumScale*color.black;
304         if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
305             (image->matte != MagickFalse))
306           sparse_arguments[x++] = QuantumScale*color.alpha;
307       }
308       else {
309         /* Colors given as a set of floating point values - experimental */
310         /* NB: token contains the first floating point value to use! */
311         if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
312           {
313           while ( token[0] == ',' ) GetMagickToken(p,&p,token);
314           if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
315             break;
316           sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
317           token[0] = ','; /* used this token - get another */
318         }
319         if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
320           {
321           while ( token[0] == ',' ) GetMagickToken(p,&p,token);
322           if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
323             break;
324           sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
325           token[0] = ','; /* used this token - get another */
326         }
327         if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
328           {
329           while ( token[0] == ',' ) GetMagickToken(p,&p,token);
330           if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
331             break;
332           sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
333           token[0] = ','; /* used this token - get another */
334         }
335         if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
336             (image->colorspace == CMYKColorspace))
337           {
338           while ( token[0] == ',' ) GetMagickToken(p,&p,token);
339           if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
340             break;
341           sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
342           token[0] = ','; /* used this token - get another */
343         }
344         if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
345             (image->matte != MagickFalse))
346           {
347           while ( token[0] == ',' ) GetMagickToken(p,&p,token);
348           if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
349             break;
350           sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
351           token[0] = ','; /* used this token - get another */
352         }
353       }
354     }
355   }
356   if ( number_arguments != x && !error ) {
357     (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
358       "InvalidArgument","`%s': %s","sparse-color","Argument Parsing Error");
359     sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
360     return( (Image *)NULL);
361   }
362   if ( error )
363     return( (Image *)NULL);
364
365   /* Call the Interpolation function with the parsed arguments */
366   sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
367     exception);
368   sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
369   return( sparse_image );
370 }
371 \f
372 /*
373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374 %                                                                             %
375 %                                                                             %
376 %                                                                             %
377 +     S e t t i n g s O p t i o n I n f o                                     %
378 %                                                                             %
379 %                                                                             %
380 %                                                                             %
381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382 %
383 %  SettingsOptionInfo() saves the given single settings argv[0] into a
384 %  ImageInfo structure for later use by various image processing operations.
385 %
386 %  The format of the SettingsOptionInfo method is:
387 %
388 %    MagickBooleanType SettingsOptionInfo(ImageInfo *image_info,
389 %        const int argc, const char **argv,ExceptionInfo *exception)
390 %
391 %  A description of each parameter follows:
392 %
393 %    o image_info: the image info..
394 %
395 %    o argc: Specifies a pointer to an integer describing the number of
396 %      elements in the argument vector.
397 %
398 %    o argv: Specifies a pointer to a text array containing the command line
399 %      arguments.
400 %
401 %    o exception: return any errors or warnings in this structure.
402 %
403 */
404 WandExport MagickBooleanType SettingsOptionInfo(ImageInfo *image_info,
405   const int argc,const char **argv,ExceptionInfo *exception)
406 {
407   GeometryInfo
408     geometry_info;
409
410   /*
411     Initialize method variables.
412   */
413   assert(image_info != (ImageInfo *) NULL);
414   assert(image_info->signature == MagickSignature);
415   if (image_info->debug != MagickFalse)
416     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
417       image_info->filename);
418   if (argc < 0)
419     return(MagickTrue);
420   /*
421     Set the image settings for one image.
422   */
423   switch (*(argv[0]+1))
424   {
425     case 'a':
426     {
427       if (LocaleCompare("adjoin",argv[0]+1) == 0)
428         {
429           image_info->adjoin=(*argv[0] == '-') ? MagickTrue : MagickFalse;
430           break;
431         }
432       if (LocaleCompare("antialias",argv[0]+1) == 0)
433         {
434           image_info->antialias=(*argv[0] == '-') ? MagickTrue : MagickFalse;
435           break;
436         }
437       if (LocaleCompare("attenuate",argv[0]+1) == 0)
438         {
439           if (*argv[0] == '+')
440             {
441               (void) DeleteImageOption(image_info,argv[0]+1);
442               break;
443             }
444           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
445           break;
446         }
447       if (LocaleCompare("authenticate",argv[0]+1) == 0)
448         {
449           if (*argv[0] == '+')
450             (void) CloneString(&image_info->authenticate,(char *) NULL);
451           else
452             (void) CloneString(&image_info->authenticate,argv[1]);
453           break;
454         }
455       break;
456     }
457     case 'b':
458     {
459       if (LocaleCompare("background",argv[0]+1) == 0)
460         {
461           if (*argv[0] == '+')
462             {
463               (void) DeleteImageOption(image_info,argv[0]+1);
464               (void) QueryColorCompliance(BackgroundColor,
465                 &image_info->background_color,exception);
466               break;
467             }
468           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
469           (void) QueryColorCompliance(argv[1],&image_info->background_color,
470             exception);
471           break;
472         }
473       if (LocaleCompare("bias",argv[0]+1) == 0)
474         {
475           if (*argv[0] == '+')
476             {
477               (void) SetImageOption(image_info,argv[0]+1,"0.0");
478               break;
479             }
480           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
481           break;
482         }
483       if (LocaleCompare("black-point-compensation",argv[0]+1) == 0)
484         {
485           if (*argv[0] == '+')
486             {
487               (void) SetImageOption(image_info,argv[0]+1,"false");
488               break;
489             }
490           (void) SetImageOption(image_info,argv[0]+1,"true");
491           break;
492         }
493       if (LocaleCompare("blue-primary",argv[0]+1) == 0)
494         {
495           if (*argv[0] == '+')
496             {
497               (void) SetImageOption(image_info,argv[0]+1,"0.0");
498               break;
499             }
500           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
501           break;
502         }
503       if (LocaleCompare("bordercolor",argv[0]+1) == 0)
504         {
505           if (*argv[0] == '+')
506             {
507               (void) DeleteImageOption(image_info,argv[0]+1);
508               (void) QueryColorCompliance(BorderColor,&image_info->border_color,
509                 exception);
510               break;
511             }
512           (void) QueryColorCompliance(argv[1],&image_info->border_color,
513             exception);
514           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
515           break;
516         }
517       if (LocaleCompare("box",argv[0]+1) == 0)
518         {
519           if (*argv[0] == '+')
520             {
521               (void) SetImageOption(image_info,"undercolor","none");
522               break;
523             }
524           (void) SetImageOption(image_info,"undercolor",argv[1]);
525           break;
526         }
527       break;
528     }
529     case 'c':
530     {
531       if (LocaleCompare("cache",argv[0]+1) == 0)
532         {
533           MagickSizeType
534             limit;
535
536           limit=MagickResourceInfinity;
537           if (LocaleCompare("unlimited",argv[1]) != 0)
538             limit=(MagickSizeType) SiPrefixToDouble(argv[1],100.0);
539           (void) SetMagickResourceLimit(MemoryResource,limit);
540           (void) SetMagickResourceLimit(MapResource,2*limit);
541           break;
542         }
543       if (LocaleCompare("caption",argv[0]+1) == 0)
544         {
545           if (*argv[0] == '+')
546             {
547               (void) DeleteImageOption(image_info,argv[0]+1);
548               break;
549             }
550           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
551           break;
552         }
553       if (LocaleCompare("channel",argv[0]+1) == 0)
554         {
555           if (*argv[0] == '+')
556             {
557               image_info->channel=DefaultChannels;
558               break;
559             }
560           image_info->channel=(ChannelType) ParseChannelOption(argv[1]);
561           break;
562         }
563       if (LocaleCompare("colors",argv[0]+1) == 0)
564         {
565           image_info->colors=StringToUnsignedLong(argv[1]);
566           break;
567         }
568       if (LocaleCompare("colorspace",argv[0]+1) == 0)
569         {
570           if (*argv[0] == '+')
571             {
572               image_info->colorspace=UndefinedColorspace;
573               (void) SetImageOption(image_info,argv[0]+1,"undefined");
574               break;
575             }
576           image_info->colorspace=(ColorspaceType) ParseCommandOption(
577             MagickColorspaceOptions,MagickFalse,argv[1]);
578           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
579           break;
580         }
581       if (LocaleCompare("comment",argv[0]+1) == 0)
582         {
583           if (*argv[0] == '+')
584             {
585               (void) DeleteImageOption(image_info,argv[0]+1);
586               break;
587             }
588           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
589           break;
590         }
591       if (LocaleCompare("compose",argv[0]+1) == 0)
592         {
593           if (*argv[0] == '+')
594             {
595               (void) SetImageOption(image_info,argv[0]+1,"undefined");
596               break;
597             }
598           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
599           break;
600         }
601       if (LocaleCompare("compress",argv[0]+1) == 0)
602         {
603           if (*argv[0] == '+')
604             {
605               image_info->compression=UndefinedCompression;
606               (void) SetImageOption(image_info,argv[0]+1,"undefined");
607               break;
608             }
609           image_info->compression=(CompressionType) ParseCommandOption(
610             MagickCompressOptions,MagickFalse,argv[1]);
611           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
612           break;
613         }
614       break;
615     }
616     case 'd':
617     {
618       if (LocaleCompare("debug",argv[0]+1) == 0)
619         {
620           if (*argv[0] == '+')
621             (void) SetLogEventMask("none");
622           else
623             (void) SetLogEventMask(argv[1]);
624           image_info->debug=IsEventLogging();
625           break;
626         }
627       if (LocaleCompare("define",argv[0]+1) == 0)
628         {
629           if (*argv[0] == '+')
630             {
631               if (LocaleNCompare(argv[1],"registry:",9) == 0)
632                 (void) DeleteImageRegistry(argv[1]+9);
633               else
634                 (void) DeleteImageOption(image_info,argv[1]);
635               break;
636             }
637           if (LocaleNCompare(argv[1],"registry:",9) == 0)
638             {
639               (void) DefineImageRegistry(StringRegistryType,argv[1]+9,
640                 exception);
641               break;
642             }
643           (void) DefineImageOption(image_info,argv[1]);
644           break;
645         }
646       if (LocaleCompare("delay",argv[0]+1) == 0)
647         {
648           if (*argv[0] == '+')
649             {
650               (void) SetImageOption(image_info,argv[0]+1,"0");
651               break;
652             }
653           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
654           break;
655         }
656       if (LocaleCompare("density",argv[0]+1) == 0)
657         {
658           /*
659             Set image density.
660           */
661           if (*argv[0] == '+')
662             {
663               if (image_info->density != (char *) NULL)
664                 image_info->density=DestroyString(image_info->density);
665               (void) SetImageOption(image_info,argv[0]+1,"72");
666               break;
667             }
668           (void) CloneString(&image_info->density,argv[1]);
669           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
670           break;
671         }
672       if (LocaleCompare("depth",argv[0]+1) == 0)
673         {
674           if (*argv[0] == '+')
675             {
676               image_info->depth=MAGICKCORE_QUANTUM_DEPTH;
677               break;
678             }
679           image_info->depth=StringToUnsignedLong(argv[1]);
680           break;
681         }
682       if (LocaleCompare("direction",argv[0]+1) == 0)
683         {
684           if (*argv[0] == '+')
685             {
686               (void) SetImageOption(image_info,argv[0]+1,"undefined");
687               break;
688             }
689           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
690           break;
691         }
692       if (LocaleCompare("display",argv[0]+1) == 0)
693         {
694           if (*argv[0] == '+')
695             {
696               if (image_info->server_name != (char *) NULL)
697                 image_info->server_name=DestroyString(
698                   image_info->server_name);
699               break;
700             }
701           (void) CloneString(&image_info->server_name,argv[1]);
702           break;
703         }
704       if (LocaleCompare("dispose",argv[0]+1) == 0)
705         {
706           if (*argv[0] == '+')
707             {
708               (void) SetImageOption(image_info,argv[0]+1,"undefined");
709               break;
710             }
711           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
712           break;
713         }
714       if (LocaleCompare("dither",argv[0]+1) == 0)
715         {
716           if (*argv[0] == '+')
717             {
718               image_info->dither=MagickFalse;
719               (void) SetImageOption(image_info,argv[0]+1,"none");
720               break;
721             }
722           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
723           image_info->dither=MagickTrue;
724           break;
725         }
726       break;
727     }
728     case 'e':
729     {
730       if (LocaleCompare("encoding",argv[0]+1) == 0)
731         {
732           if (*argv[0] == '+')
733             {
734               (void) SetImageOption(image_info,argv[0]+1,"undefined");
735               break;
736             }
737           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
738           break;
739         }
740       if (LocaleCompare("endian",argv[0]+1) == 0)
741         {
742           if (*argv[0] == '+')
743             {
744               image_info->endian=UndefinedEndian;
745               (void) SetImageOption(image_info,argv[0]+1,"undefined");
746               break;
747             }
748           image_info->endian=(EndianType) ParseCommandOption(
749             MagickEndianOptions,MagickFalse,argv[1]);
750           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
751           break;
752         }
753       if (LocaleCompare("extract",argv[0]+1) == 0)
754         {
755           /*
756             Set image extract geometry.
757           */
758           if (*argv[0] == '+')
759             {
760               if (image_info->extract != (char *) NULL)
761                 image_info->extract=DestroyString(image_info->extract);
762               break;
763             }
764           (void) CloneString(&image_info->extract,argv[1]);
765           break;
766         }
767       break;
768     }
769     case 'f':
770     {
771       if (LocaleCompare("fill",argv[0]+1) == 0)
772         {
773           if (*argv[0] == '+')
774             {
775               (void) SetImageOption(image_info,argv[0]+1,"none");
776               break;
777             }
778           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
779           break;
780         }
781       if (LocaleCompare("filter",argv[0]+1) == 0)
782         {
783           if (*argv[0] == '+')
784             {
785               (void) SetImageOption(image_info,argv[0]+1,"undefined");
786               break;
787             }
788           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
789           break;
790         }
791       if (LocaleCompare("font",argv[0]+1) == 0)
792         {
793           if (*argv[0] == '+')
794             {
795               if (image_info->font != (char *) NULL)
796                 image_info->font=DestroyString(image_info->font);
797               break;
798             }
799           (void) CloneString(&image_info->font,argv[1]);
800           break;
801         }
802       if (LocaleCompare("format",argv[0]+1) == 0)
803         {
804           register const char
805             *q;
806
807           for (q=strchr(argv[1],'%'); q != (char *) NULL; q=strchr(q+1,'%'))
808             if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
809               image_info->ping=MagickFalse;
810           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
811           break;
812         }
813       if (LocaleCompare("fuzz",argv[0]+1) == 0)
814         {
815           if (*argv[0] == '+')
816             {
817               image_info->fuzz=0.0;
818               (void) SetImageOption(image_info,argv[0]+1,"0");
819               break;
820             }
821           image_info->fuzz=SiPrefixToDouble(argv[1],(double) QuantumRange+
822             1.0);
823           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
824           break;
825         }
826       break;
827     }
828     case 'g':
829     {
830       if (LocaleCompare("gravity",argv[0]+1) == 0)
831         {
832           if (*argv[0] == '+')
833             {
834               (void) SetImageOption(image_info,argv[0]+1,"undefined");
835               break;
836             }
837           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
838           break;
839         }
840       if (LocaleCompare("green-primary",argv[0]+1) == 0)
841         {
842           if (*argv[0] == '+')
843             {
844               (void) SetImageOption(image_info,argv[0]+1,"0.0");
845               break;
846             }
847           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
848           break;
849         }
850       break;
851     }
852     case 'i':
853     {
854       if (LocaleCompare("intent",argv[0]+1) == 0)
855         {
856           if (*argv[0] == '+')
857             {
858               (void) SetImageOption(image_info,argv[0]+1,"undefined");
859               break;
860             }
861           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
862           break;
863         }
864       if (LocaleCompare("interlace",argv[0]+1) == 0)
865         {
866           if (*argv[0] == '+')
867             {
868               image_info->interlace=UndefinedInterlace;
869               (void) SetImageOption(image_info,argv[0]+1,"undefined");
870               break;
871             }
872           image_info->interlace=(InterlaceType) ParseCommandOption(
873             MagickInterlaceOptions,MagickFalse,argv[1]);
874           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
875           break;
876         }
877       if (LocaleCompare("interline-spacing",argv[0]+1) == 0)
878         {
879           if (*argv[0] == '+')
880             {
881               (void) SetImageOption(image_info,argv[0]+1,"undefined");
882               break;
883             }
884           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
885           break;
886         }
887       if (LocaleCompare("interpolate",argv[0]+1) == 0)
888         {
889           if (*argv[0] == '+')
890             {
891               (void) SetImageOption(image_info,argv[0]+1,"undefined");
892               break;
893             }
894           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
895           break;
896         }
897       if (LocaleCompare("interword-spacing",argv[0]+1) == 0)
898         {
899           if (*argv[0] == '+')
900             {
901               (void) SetImageOption(image_info,argv[0]+1,"undefined");
902               break;
903             }
904           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
905           break;
906         }
907       break;
908     }
909     case 'k':
910     {
911       if (LocaleCompare("kerning",argv[0]+1) == 0)
912         {
913           if (*argv[0] == '+')
914             {
915               (void) SetImageOption(image_info,argv[0]+1,"undefined");
916               break;
917             }
918           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
919           break;
920         }
921       break;
922     }
923     case 'l':
924     {
925       if (LocaleCompare("label",argv[0]+1) == 0)
926         {
927           if (*argv[0] == '+')
928             {
929               (void) DeleteImageOption(image_info,argv[0]+1);
930               break;
931             }
932           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
933           break;
934         }
935       if (LocaleCompare("limit",argv[0]+1) == 0)
936         {
937           MagickSizeType
938             limit;
939
940           ResourceType
941             type;
942
943           if (*argv[0] == '+')
944             break;
945           type=(ResourceType) ParseCommandOption(MagickResourceOptions,
946             MagickFalse,argv[1]);
947           limit=MagickResourceInfinity;
948           if (LocaleCompare("unlimited",argv[2]) != 0)
949             limit=(MagickSizeType) SiPrefixToDouble(argv[2],100.0);
950           (void) SetMagickResourceLimit(type,limit);
951           break;
952         }
953       if (LocaleCompare("list",argv[0]+1) == 0)
954         {
955           ssize_t
956             list;
957
958           /*
959             Display configuration list.
960           */
961           list=ParseCommandOption(MagickListOptions,MagickFalse,argv[1]);
962           switch (list)
963           {
964             case MagickCoderOptions:
965             {
966               (void) ListCoderInfo((FILE *) NULL,exception);
967               break;
968             }
969             case MagickColorOptions:
970             {
971               (void) ListColorInfo((FILE *) NULL,exception);
972               break;
973             }
974             case MagickConfigureOptions:
975             {
976               (void) ListConfigureInfo((FILE *) NULL,exception);
977               break;
978             }
979             case MagickDelegateOptions:
980             {
981               (void) ListDelegateInfo((FILE *) NULL,exception);
982               break;
983             }
984             case MagickFontOptions:
985             {
986               (void) ListTypeInfo((FILE *) NULL,exception);
987               break;
988             }
989             case MagickFormatOptions:
990             {
991               (void) ListMagickInfo((FILE *) NULL,exception);
992               break;
993             }
994             case MagickLocaleOptions:
995             {
996               (void) ListLocaleInfo((FILE *) NULL,exception);
997               break;
998             }
999             case MagickLogOptions:
1000             {
1001               (void) ListLogInfo((FILE *) NULL,exception);
1002               break;
1003             }
1004             case MagickMagicOptions:
1005             {
1006               (void) ListMagicInfo((FILE *) NULL,exception);
1007               break;
1008             }
1009             case MagickMimeOptions:
1010             {
1011               (void) ListMimeInfo((FILE *) NULL,exception);
1012               break;
1013             }
1014             case MagickModuleOptions:
1015             {
1016               (void) ListModuleInfo((FILE *) NULL,exception);
1017               break;
1018             }
1019             case MagickPolicyOptions:
1020             {
1021               (void) ListPolicyInfo((FILE *) NULL,exception);
1022               break;
1023             }
1024             case MagickResourceOptions:
1025             {
1026               (void) ListMagickResourceInfo((FILE *) NULL,exception);
1027               break;
1028             }
1029             case MagickThresholdOptions:
1030             {
1031               (void) ListThresholdMaps((FILE *) NULL,exception);
1032               break;
1033             }
1034             default:
1035             {
1036               (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
1037                 exception);
1038               break;
1039             }
1040           }
1041           break;
1042         }
1043       if (LocaleCompare("log",argv[0]+1) == 0)
1044         {
1045           if (*argv[0] == '+')
1046             break;
1047           (void) SetLogFormat(argv[1]);
1048           break;
1049         }
1050       if (LocaleCompare("loop",argv[0]+1) == 0)
1051         {
1052           if (*argv[0] == '+')
1053             {
1054               (void) SetImageOption(image_info,argv[0]+1,"0");
1055               break;
1056             }
1057           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1058           break;
1059         }
1060       break;
1061     }
1062     case 'm':
1063     {
1064       if (LocaleCompare("matte",argv[0]+1) == 0)
1065         {
1066           if (*argv[0] == '+')
1067             {
1068               (void) SetImageOption(image_info,argv[0]+1,"false");
1069               break;
1070             }
1071           (void) SetImageOption(image_info,argv[0]+1,"true");
1072           break;
1073         }
1074       if (LocaleCompare("mattecolor",argv[0]+1) == 0)
1075         {
1076           if (*argv[0] == '+')
1077             {
1078               (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1079               (void) QueryColorCompliance(MatteColor,&image_info->matte_color,
1080                 exception);
1081               break;
1082             }
1083           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1084           (void) QueryColorCompliance(argv[1],&image_info->matte_color,
1085             exception);
1086           break;
1087         }
1088       if (LocaleCompare("monitor",argv[0]+1) == 0)
1089         {
1090           (void) SetImageInfoProgressMonitor(image_info,MonitorProgress,
1091             (void *) NULL);
1092           break;
1093         }
1094       if (LocaleCompare("monochrome",argv[0]+1) == 0)
1095         {
1096           image_info->monochrome=(*argv[0] == '-') ? MagickTrue : MagickFalse;
1097           break;
1098         }
1099       break;
1100     }
1101     case 'o':
1102     {
1103       if (LocaleCompare("orient",argv[0]+1) == 0)
1104         {
1105           if (*argv[0] == '+')
1106             {
1107               image_info->orientation=UndefinedOrientation;
1108               (void) SetImageOption(image_info,argv[0]+1,"undefined");
1109               break;
1110             }
1111           image_info->orientation=(OrientationType) ParseCommandOption(
1112             MagickOrientationOptions,MagickFalse,argv[1]);
1113           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1114           break;
1115         }
1116     }
1117     case 'p':
1118     {
1119       if (LocaleCompare("page",argv[0]+1) == 0)
1120         {
1121           char
1122             *canonical_page,
1123             page[MaxTextExtent];
1124
1125           const char
1126             *image_option;
1127
1128           MagickStatusType
1129             flags;
1130
1131           RectangleInfo
1132             geometry;
1133
1134           if (*argv[0] == '+')
1135             {
1136               (void) DeleteImageOption(image_info,argv[0]+1);
1137               (void) CloneString(&image_info->page,(char *) NULL);
1138               break;
1139             }
1140           (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
1141           image_option=GetImageOption(image_info,"page");
1142           if (image_option != (const char *) NULL)
1143             flags=ParseAbsoluteGeometry(image_option,&geometry);
1144           canonical_page=GetPageGeometry(argv[1]);
1145           flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1146           canonical_page=DestroyString(canonical_page);
1147           (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1148             (unsigned long) geometry.width,(unsigned long) geometry.height);
1149           if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1150             (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1151               (unsigned long) geometry.width,(unsigned long) geometry.height,
1152               (long) geometry.x,(long) geometry.y);
1153           (void) SetImageOption(image_info,argv[0]+1,page);
1154           (void) CloneString(&image_info->page,page);
1155           break;
1156         }
1157       if (LocaleCompare("pen",argv[0]+1) == 0)
1158         {
1159           if (*argv[0] == '+')
1160             {
1161               (void) SetImageOption(image_info,argv[0]+1,"none");
1162               break;
1163             }
1164           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1165           break;
1166         }
1167       if (LocaleCompare("ping",argv[0]+1) == 0)
1168         {
1169           image_info->ping=(*argv[0] == '-') ? MagickTrue : MagickFalse;
1170           break;
1171         }
1172       if (LocaleCompare("pointsize",argv[0]+1) == 0)
1173         {
1174           if (*argv[0] == '+')
1175             geometry_info.rho=0.0;
1176           else
1177             (void) ParseGeometry(argv[1],&geometry_info);
1178           image_info->pointsize=geometry_info.rho;
1179           break;
1180         }
1181       if (LocaleCompare("precision",argv[0]+1) == 0)
1182         {
1183           (void) SetMagickPrecision(StringToInteger(argv[1]));
1184           break;
1185         }
1186       if (LocaleCompare("preview",argv[0]+1) == 0)
1187         {
1188           /*
1189             Preview image.
1190           */
1191           if (*argv[0] == '+')
1192             {
1193               image_info->preview_type=UndefinedPreview;
1194               break;
1195             }
1196           image_info->preview_type=(PreviewType) ParseCommandOption(
1197             MagickPreviewOptions,MagickFalse,argv[1]);
1198           break;
1199         }
1200       break;
1201     }
1202     case 'q':
1203     {
1204       if (LocaleCompare("quality",argv[0]+1) == 0)
1205         {
1206           /*
1207             Set image compression quality.
1208           */
1209           if (*argv[0] == '+')
1210             {
1211               image_info->quality=UndefinedCompressionQuality;
1212               (void) SetImageOption(image_info,argv[0]+1,"0");
1213               break;
1214             }
1215           image_info->quality=StringToUnsignedLong(argv[1]);
1216           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1217           break;
1218         }
1219       if (LocaleCompare("quiet",argv[0]+1) == 0)
1220         {
1221           static WarningHandler
1222             warning_handler = (WarningHandler) NULL;
1223
1224           if (*argv[0] == '+')
1225             {
1226               /*
1227                 Restore error or warning messages.
1228               */
1229               warning_handler=SetWarningHandler(warning_handler);
1230               break;
1231             }
1232           /*
1233             Suppress error or warning messages.
1234           */
1235           warning_handler=SetWarningHandler((WarningHandler) NULL);
1236           break;
1237         }
1238       break;
1239     }
1240     case 'r':
1241     {
1242       if (LocaleCompare("red-primary",argv[0]+1) == 0)
1243         {
1244           if (*argv[0] == '+')
1245             {
1246               (void) SetImageOption(image_info,argv[0]+1,"0.0");
1247               break;
1248             }
1249           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1250           break;
1251         }
1252       break;
1253     }
1254     case 's':
1255     {
1256       if (LocaleCompare("sampling-factor",argv[0]+1) == 0)
1257         {
1258           /*
1259             Set image sampling factor.
1260           */
1261           if (*argv[0] == '+')
1262             {
1263               if (image_info->sampling_factor != (char *) NULL)
1264                 image_info->sampling_factor=DestroyString(
1265                   image_info->sampling_factor);
1266               break;
1267             }
1268           (void) CloneString(&image_info->sampling_factor,argv[1]);
1269           break;
1270         }
1271       if (LocaleCompare("scene",argv[0]+1) == 0)
1272         {
1273           /*
1274             Set image scene.
1275           */
1276           if (*argv[0] == '+')
1277             {
1278               image_info->scene=0;
1279               (void) SetImageOption(image_info,argv[0]+1,"0");
1280               break;
1281             }
1282           image_info->scene=StringToUnsignedLong(argv[1]);
1283           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1284           break;
1285         }
1286       if (LocaleCompare("seed",argv[0]+1) == 0)
1287         {
1288           size_t
1289             seed;
1290
1291           if (*argv[0] == '+')
1292             {
1293               seed=(size_t) time((time_t *) NULL);
1294               SeedPseudoRandomGenerator(seed);
1295               break;
1296             }
1297           seed=StringToUnsignedLong(argv[1]);
1298           SeedPseudoRandomGenerator(seed);
1299           break;
1300         }
1301       if (LocaleCompare("size",argv[0]+1) == 0)
1302         {
1303           if (*argv[0] == '+')
1304             {
1305               if (image_info->size != (char *) NULL)
1306                 image_info->size=DestroyString(image_info->size);
1307               break;
1308             }
1309           (void) CloneString(&image_info->size,argv[1]);
1310           break;
1311         }
1312       if (LocaleCompare("stroke",argv[0]+1) == 0)
1313         {
1314           if (*argv[0] == '+')
1315             {
1316               (void) SetImageOption(image_info,argv[0]+1,"none");
1317               break;
1318             }
1319           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1320           break;
1321         }
1322       if (LocaleCompare("strokewidth",argv[0]+1) == 0)
1323         {
1324           if (*argv[0] == '+')
1325             {
1326               (void) SetImageOption(image_info,argv[0]+1,"0");
1327               break;
1328             }
1329           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1330           break;
1331         }
1332       if (LocaleCompare("synchronize",argv[0]+1) == 0)
1333         {
1334           if (*argv[0] == '+')
1335             {
1336               image_info->synchronize=MagickFalse;
1337               break;
1338             }
1339           image_info->synchronize=MagickTrue;
1340           break;
1341         }
1342       break;
1343     }
1344     case 't':
1345     {
1346       if (LocaleCompare("taint",argv[0]+1) == 0)
1347         {
1348           if (*argv[0] == '+')
1349             {
1350               (void) SetImageOption(image_info,argv[0]+1,"false");
1351               break;
1352             }
1353           (void) SetImageOption(image_info,argv[0]+1,"true");
1354           break;
1355         }
1356       if (LocaleCompare("texture",argv[0]+1) == 0)
1357         {
1358           if (*argv[0] == '+')
1359             {
1360               if (image_info->texture != (char *) NULL)
1361                 image_info->texture=DestroyString(image_info->texture);
1362               break;
1363             }
1364           (void) CloneString(&image_info->texture,argv[1]);
1365           break;
1366         }
1367       if (LocaleCompare("tile-offset",argv[0]+1) == 0)
1368         {
1369           if (*argv[0] == '+')
1370             {
1371               (void) SetImageOption(image_info,argv[0]+1,"0");
1372               break;
1373             }
1374           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1375           break;
1376         }
1377       if (LocaleCompare("transparent-color",argv[0]+1) == 0)
1378         {
1379           if (*argv[0] == '+')
1380             {
1381               (void) QueryColorCompliance("none",&image_info->transparent_color,                  exception);
1382               (void) SetImageOption(image_info,argv[0]+1,"none");
1383               break;
1384             }
1385           (void) QueryColorCompliance(argv[1],&image_info->transparent_color,
1386             exception);
1387           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1388           break;
1389         }
1390       if (LocaleCompare("type",argv[0]+1) == 0)
1391         {
1392           if (*argv[0] == '+')
1393             {
1394               image_info->type=UndefinedType;
1395               (void) SetImageOption(image_info,argv[0]+1,"undefined");
1396               break;
1397             }
1398           image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
1399             MagickFalse,argv[1]);
1400           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1401           break;
1402         }
1403       break;
1404     }
1405     case 'u':
1406     {
1407       if (LocaleCompare("undercolor",argv[0]+1) == 0)
1408         {
1409           if (*argv[0] == '+')
1410             {
1411               (void) DeleteImageOption(image_info,argv[0]+1);
1412               break;
1413             }
1414           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1415           break;
1416         }
1417       if (LocaleCompare("units",argv[0]+1) == 0)
1418         {
1419           if (*argv[0] == '+')
1420             {
1421               image_info->units=UndefinedResolution;
1422               (void) SetImageOption(image_info,argv[0]+1,"undefined");
1423               break;
1424             }
1425           image_info->units=(ResolutionType) ParseCommandOption(
1426             MagickResolutionOptions,MagickFalse,argv[1]);
1427           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1428           break;
1429         }
1430       break;
1431     }
1432     case 'v':
1433     {
1434       if (LocaleCompare("verbose",argv[0]+1) == 0)
1435         {
1436           if (*argv[0] == '+')
1437             {
1438               image_info->verbose=MagickFalse;
1439               break;
1440             }
1441           image_info->verbose=MagickTrue;
1442           image_info->ping=MagickFalse;
1443           break;
1444         }
1445       if (LocaleCompare("view",argv[0]+1) == 0)
1446         {
1447           if (*argv[0] == '+')
1448             {
1449               if (image_info->view != (char *) NULL)
1450                 image_info->view=DestroyString(image_info->view);
1451               break;
1452             }
1453           (void) CloneString(&image_info->view,argv[1]);
1454           break;
1455         }
1456       if (LocaleCompare("virtual-pixel",argv[0]+1) == 0)
1457         {
1458           if (*argv[0] == '+')
1459             {
1460               image_info->virtual_pixel_method=UndefinedVirtualPixelMethod;
1461               (void) SetImageOption(image_info,argv[0]+1,"undefined");
1462               break;
1463             }
1464           image_info->virtual_pixel_method=(VirtualPixelMethod)
1465             ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,argv[1]);
1466           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1467           break;
1468         }
1469       break;
1470     }
1471     case 'w':
1472     {
1473       if (LocaleCompare("white-point",argv[0]+1) == 0)
1474         {
1475           if (*argv[0] == '+')
1476             {
1477               (void) SetImageOption(image_info,argv[0]+1,"0.0");
1478               break;
1479             }
1480           (void) SetImageOption(image_info,argv[0]+1,argv[1]);
1481           break;
1482         }
1483       break;
1484     }
1485     default:
1486       break;
1487   }
1488   return(MagickTrue);
1489 }
1490 \f
1491 /*
1492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1493 %                                                                             %
1494 %                                                                             %
1495 %                                                                             %
1496 +     S i m p l e O p e r a t i o n I m a g e                                 %
1497 %                                                                             %
1498 %                                                                             %
1499 %                                                                             %
1500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1501 %
1502 %  SimpleOperationImage() apply one simple operation on one image.
1503 %  The image however may be part of a longer list of images.
1504 %
1505 %  The image in the list may be modified in three different ways...
1506 %
1507 %    * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1508 %    * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1509 %    * replace by a list of images (-separate and -crop only!)
1510 %
1511 %  In each case the result is returned into the list, and the pointer to the
1512 %  modified image (last image added if replaced by a list of images) is
1513 %  returned.  As the image pointed to may be replaced, the first image in the
1514 %  list may also change.  GetFirstImageInList() should be used by caller if
1515 %  they wish return the Image pointer to the first image in list.
1516 %
1517 %  The format of the SimpleOperationImage method is:
1518 %
1519 %    MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
1520 %        const int argc,const char **argv,Image **image)
1521 %
1522 %  A description of each parameter follows:
1523 %
1524 %    o image_info: the image info..
1525 %
1526 %    o argc: Specifies a pointer to an integer describing the number of
1527 %      elements in the argument vector.
1528 %
1529 %    o argv: Specifies a pointer to a text array containing the command line
1530 %      arguments.
1531 %
1532 %    o image: the image.
1533 %
1534 %    o exception: return any errors or warnings in this structure.
1535 %
1536 */
1537 MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
1538      const int wand_unused(argc), const char **argv,Image **image,
1539      ExceptionInfo *exception)
1540 {
1541   Image *
1542     new_image;
1543
1544   ChannelType
1545     channel;
1546
1547   const char
1548     *format;
1549
1550   DrawInfo
1551     *draw_info;
1552
1553   GeometryInfo
1554     geometry_info;
1555
1556   RectangleInfo
1557     geometry;
1558
1559   MagickStatusType
1560     status;
1561
1562   PixelInfo
1563     fill;
1564
1565   MagickStatusType
1566     flags;
1567
1568   QuantizeInfo
1569     *quantize_info;
1570
1571   assert(image_info != (const ImageInfo *) NULL);
1572   assert(image_info->signature == MagickSignature);
1573   assert(image != (Image **) NULL);
1574   assert((*image)->signature == MagickSignature);
1575   if ((*image)->debug != MagickFalse)
1576     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
1577
1578   draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
1579   quantize_info=AcquireQuantizeInfo(image_info);
1580   SetGeometryInfo(&geometry_info);
1581   GetPixelInfo(*image,&fill);
1582   SetPixelInfoPacket(*image,&(*image)->background_color,&fill);
1583   channel=image_info->channel;
1584   format=GetImageOption(image_info,"format");
1585
1586   new_image = (Image *)NULL;
1587
1588   switch (*(argv[0]+1))
1589   {
1590     case 'a':
1591     {
1592       if (LocaleCompare("adaptive-blur",argv[0]+1) == 0)
1593         {
1594           /*
1595             Adaptive blur image.
1596           */
1597           (void) SyncImageSettings(image_info,*image);
1598           flags=ParseGeometry(argv[1],&geometry_info);
1599           if ((flags & SigmaValue) == 0)
1600             geometry_info.sigma=1.0;
1601           if ((flags & XiValue) == 0)
1602             geometry_info.xi=0.0;
1603           new_image=AdaptiveBlurImage(*image,geometry_info.rho,
1604             geometry_info.sigma,geometry_info.xi,exception);
1605           break;
1606         }
1607       if (LocaleCompare("adaptive-resize",argv[0]+1) == 0)
1608         {
1609           /*
1610             Adaptive resize image.
1611           */
1612           (void) SyncImageSettings(image_info,*image);
1613           (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
1614           new_image=AdaptiveResizeImage(*image,geometry.width,
1615             geometry.height,exception);
1616           break;
1617         }
1618       if (LocaleCompare("adaptive-sharpen",argv[0]+1) == 0)
1619         {
1620           /*
1621             Adaptive sharpen image.
1622           */
1623           (void) SyncImageSettings(image_info,*image);
1624           flags=ParseGeometry(argv[1],&geometry_info);
1625           if ((flags & SigmaValue) == 0)
1626             geometry_info.sigma=1.0;
1627           if ((flags & XiValue) == 0)
1628             geometry_info.xi=0.0;
1629           new_image=AdaptiveSharpenImage(*image,geometry_info.rho,
1630             geometry_info.sigma,geometry_info.xi,exception);
1631           break;
1632         }
1633       if (LocaleCompare("affine",argv[0]+1) == 0)
1634         {
1635           /*
1636             Affine matrix.
1637           */
1638           if (*argv[0] == '+')
1639             {
1640               GetAffineMatrix(&draw_info->affine);
1641               break;
1642             }
1643           (void) ParseAffineGeometry(argv[1],&draw_info->affine,exception);
1644           break;
1645         }
1646       if (LocaleCompare("alpha",argv[0]+1) == 0)
1647         {
1648           AlphaChannelType
1649             alpha_type;
1650
1651           (void) SyncImageSettings(image_info,*image);
1652           alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
1653             MagickFalse,argv[1]);
1654           (void) SetImageAlphaChannel(*image,alpha_type,exception);
1655           break;
1656         }
1657       if (LocaleCompare("annotate",argv[0]+1) == 0)
1658         {
1659           char
1660             *text,
1661             geometry[MaxTextExtent];
1662
1663           /*
1664             Annotate image.
1665           */
1666           (void) SyncImageSettings(image_info,*image);
1667           SetGeometryInfo(&geometry_info);
1668           flags=ParseGeometry(argv[1],&geometry_info);
1669           if ((flags & SigmaValue) == 0)
1670             geometry_info.sigma=geometry_info.rho;
1671           text=InterpretImageProperties(image_info,*image,argv[2],
1672             exception);
1673           if (text == (char *) NULL)
1674             break;
1675           (void) CloneString(&draw_info->text,text);
1676           text=DestroyString(text);
1677           (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1678             geometry_info.xi,geometry_info.psi);
1679           (void) CloneString(&draw_info->geometry,geometry);
1680           draw_info->affine.sx=cos(DegreesToRadians(
1681             fmod(geometry_info.rho,360.0)));
1682           draw_info->affine.rx=sin(DegreesToRadians(
1683             fmod(geometry_info.rho,360.0)));
1684           draw_info->affine.ry=(-sin(DegreesToRadians(
1685             fmod(geometry_info.sigma,360.0))));
1686           draw_info->affine.sy=cos(DegreesToRadians(
1687             fmod(geometry_info.sigma,360.0)));
1688           (void) AnnotateImage(*image,draw_info,exception);
1689           break;
1690         }
1691       if (LocaleCompare("antialias",argv[0]+1) == 0)
1692         {
1693           draw_info->stroke_antialias=(*argv[0] == '-') ? MagickTrue :
1694             MagickFalse;
1695           draw_info->text_antialias=(*argv[0] == '-') ? MagickTrue :
1696             MagickFalse;
1697           break;
1698         }
1699       if (LocaleCompare("auto-gamma",argv[0]+1) == 0)
1700         {
1701           /*
1702             Auto Adjust Gamma of image based on its mean
1703           */
1704           (void) SyncImageSettings(image_info,*image);
1705           (void) AutoGammaImage(*image,exception);
1706           break;
1707         }
1708       if (LocaleCompare("auto-level",argv[0]+1) == 0)
1709         {
1710           /*
1711             Perfectly Normalize (max/min stretch) the image
1712           */
1713           (void) SyncImageSettings(image_info,*image);
1714           (void) AutoLevelImage(*image,exception);
1715           break;
1716         }
1717       if (LocaleCompare("auto-orient",argv[0]+1) == 0)
1718         {
1719           (void) SyncImageSettings(image_info,*image);
1720           switch ((*image)->orientation)
1721           {
1722             case TopRightOrientation:
1723             {
1724               new_image=FlopImage(*image,exception);
1725               break;
1726             }
1727             case BottomRightOrientation:
1728             {
1729               new_image=RotateImage(*image,180.0,exception);
1730               break;
1731             }
1732             case BottomLeftOrientation:
1733             {
1734               new_image=FlipImage(*image,exception);
1735               break;
1736             }
1737             case LeftTopOrientation:
1738             {
1739               new_image=TransposeImage(*image,exception);
1740               break;
1741             }
1742             case RightTopOrientation:
1743             {
1744               new_image=RotateImage(*image,90.0,exception);
1745               break;
1746             }
1747             case RightBottomOrientation:
1748             {
1749               new_image=TransverseImage(*image,exception);
1750               break;
1751             }
1752             case LeftBottomOrientation:
1753             {
1754               new_image=RotateImage(*image,270.0,exception);
1755               break;
1756             }
1757             default:
1758               break;
1759           }
1760           if (new_image != (Image *) NULL)
1761             new_image->orientation=TopLeftOrientation;
1762           break;
1763         }
1764       break;
1765     }
1766     case 'b':
1767     {
1768       if (LocaleCompare("black-threshold",argv[0]+1) == 0)
1769         {
1770           /*
1771             Black threshold image.
1772           */
1773           (void) SyncImageSettings(image_info,*image);
1774           (void) BlackThresholdImage(*image,argv[1],exception);
1775           InheritException(exception,&(*image)->exception);
1776           break;
1777         }
1778       if (LocaleCompare("blue-shift",argv[0]+1) == 0)
1779         {
1780           /*
1781             Blue shift image.
1782           */
1783           (void) SyncImageSettings(image_info,*image);
1784           geometry_info.rho=1.5;
1785           if (*argv[0] == '-')
1786             flags=ParseGeometry(argv[1],&geometry_info);
1787           new_image=BlueShiftImage(*image,geometry_info.rho,exception);
1788           break;
1789         }
1790       if (LocaleCompare("blur",argv[0]+1) == 0)
1791         {
1792           /*
1793             Two pass gaussian blur of image.
1794           */
1795           (void) SyncImageSettings(image_info,*image);
1796           flags=ParseGeometry(argv[1],&geometry_info);
1797           if ((flags & SigmaValue) == 0)
1798             geometry_info.sigma=1.0;
1799           if ((flags & XiValue) == 0)
1800             geometry_info.xi=0.0;
1801           new_image=BlurImage(*image,geometry_info.rho,
1802             geometry_info.sigma,geometry_info.xi,exception);
1803           break;
1804         }
1805       if (LocaleCompare("border",argv[0]+1) == 0)
1806         {
1807           /*
1808             Surround image with a border of solid color.
1809           */
1810           (void) SyncImageSettings(image_info,*image);
1811           flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
1812           if ((flags & SigmaValue) == 0)
1813             geometry.height=geometry.width;
1814           new_image=BorderImage(*image,&geometry,exception);
1815           break;
1816         }
1817       if (LocaleCompare("bordercolor",argv[0]+1) == 0)
1818         {
1819           if (*argv[0] == '+')
1820             {
1821               (void) QueryColorCompliance(BorderColor,&draw_info->border_color,
1822                 exception);
1823               break;
1824             }
1825           (void) QueryColorCompliance(argv[1],&draw_info->border_color,
1826             exception);
1827           break;
1828         }
1829       if (LocaleCompare("box",argv[0]+1) == 0)
1830         {
1831           (void) QueryColorCompliance(argv[1],&draw_info->undercolor,
1832             exception);
1833           break;
1834         }
1835       if (LocaleCompare("brightness-contrast",argv[0]+1) == 0)
1836         {
1837           double
1838             brightness,
1839             contrast;
1840
1841           GeometryInfo
1842             geometry_info;
1843
1844           MagickStatusType
1845             flags;
1846
1847           /*
1848             Brightness / contrast image.
1849           */
1850           (void) SyncImageSettings(image_info,*image);
1851           flags=ParseGeometry(argv[1],&geometry_info);
1852           brightness=geometry_info.rho;
1853           contrast=0.0;
1854           if ((flags & SigmaValue) != 0)
1855             contrast=geometry_info.sigma;
1856           (void) BrightnessContrastImage(*image,brightness,contrast,
1857             exception);
1858           InheritException(exception,&(*image)->exception);
1859           break;
1860         }
1861       break;
1862     }
1863     case 'c':
1864     {
1865       if (LocaleCompare("cdl",argv[0]+1) == 0)
1866         {
1867           char
1868             *color_correction_collection;
1869
1870           /*
1871             Color correct with a color decision list.
1872           */
1873           (void) SyncImageSettings(image_info,*image);
1874           color_correction_collection=FileToString(argv[1],~0,exception);
1875           if (color_correction_collection == (char *) NULL)
1876             break;
1877           (void) ColorDecisionListImage(*image,color_correction_collection,
1878             exception);
1879           InheritException(exception,&(*image)->exception);
1880           break;
1881         }
1882       if (LocaleCompare("channel",argv[0]+1) == 0)
1883         {
1884           if (*argv[0] == '+')
1885             channel=DefaultChannels;
1886           else
1887             channel=(ChannelType) ParseChannelOption(argv[1]);
1888           SetPixelChannelMap(*image,channel);
1889           break;
1890         }
1891       if (LocaleCompare("charcoal",argv[0]+1) == 0)
1892         {
1893           /*
1894             Charcoal image.
1895           */
1896           (void) SyncImageSettings(image_info,*image);
1897           flags=ParseGeometry(argv[1],&geometry_info);
1898           if ((flags & SigmaValue) == 0)
1899             geometry_info.sigma=1.0;
1900           if ((flags & XiValue) == 0)
1901             geometry_info.xi=1.0;
1902           new_image=CharcoalImage(*image,geometry_info.rho,
1903             geometry_info.sigma,geometry_info.xi,exception);
1904           break;
1905         }
1906       if (LocaleCompare("chop",argv[0]+1) == 0)
1907         {
1908           /*
1909             Chop the image.
1910           */
1911           (void) SyncImageSettings(image_info,*image);
1912           (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
1913           new_image=ChopImage(*image,&geometry,exception);
1914           break;
1915         }
1916       if (LocaleCompare("clamp",argv[0]+1) == 0)
1917         {
1918           /*
1919             Clamp image.
1920           */
1921           (void) SyncImageSettings(image_info,*image);
1922           (void) ClampImage(*image);
1923           InheritException(exception,&(*image)->exception);
1924           break;
1925         }
1926       if (LocaleCompare("clip",argv[0]+1) == 0)
1927         {
1928           (void) SyncImageSettings(image_info,*image);
1929           if (*argv[0] == '+')
1930             {
1931               (void) SetImageClipMask(*image,(Image *) NULL,exception);
1932               break;
1933             }
1934           (void) ClipImage(*image,exception);
1935           break;
1936         }
1937       if (LocaleCompare("clip-mask",argv[0]+1) == 0)
1938         {
1939           CacheView
1940             *mask_view;
1941
1942           Image
1943             *mask_image;
1944
1945           register Quantum
1946             *restrict q;
1947
1948           register ssize_t
1949             x;
1950
1951           ssize_t
1952             y;
1953
1954           (void) SyncImageSettings(image_info,*image);
1955           if (*argv[0] == '+')
1956             {
1957               /*
1958                 Remove a mask.
1959               */
1960               (void) SetImageMask(*image,(Image *) NULL,exception);
1961               break;
1962             }
1963           mask_image=GetImageCache(image_info,argv[1],exception);
1964           if (mask_image == (Image *) NULL)
1965             break;
1966           if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
1967             return(MagickFalse);
1968           mask_view=AcquireCacheView(mask_image);
1969           for (y=0; y < (ssize_t) mask_image->rows; y++)
1970           {
1971             q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
1972               exception);
1973             if (q == (Quantum *) NULL)
1974               break;
1975             for (x=0; x < (ssize_t) mask_image->columns; x++)
1976             {
1977               if (mask_image->matte == MagickFalse)
1978                 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1979               SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1980               SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1981               SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1982               q+=GetPixelChannels(mask_image);
1983             }
1984             if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
1985               break;
1986           }
1987           mask_view=DestroyCacheView(mask_view);
1988           mask_image->matte=MagickTrue;
1989           (void) SetImageClipMask(*image,mask_image);
1990           mask_image=DestroyImage(mask_image);
1991           InheritException(exception,&(*image)->exception);
1992           break;
1993         }
1994       if (LocaleCompare("clip-path",argv[0]+1) == 0)
1995         {
1996           (void) SyncImageSettings(image_info,*image);
1997           (void) ClipImagePath(*image,argv[1],*argv[0] == '-' ? MagickTrue :
1998             MagickFalse,exception);
1999           break;
2000         }
2001       if (LocaleCompare("colorize",argv[0]+1) == 0)
2002         {
2003           /*
2004             Colorize the image.
2005           */
2006           (void) SyncImageSettings(image_info,*image);
2007           new_image=ColorizeImage(*image,argv[1],draw_info->fill,
2008             exception);
2009           break;
2010         }
2011       if (LocaleCompare("color-matrix",argv[0]+1) == 0)
2012         {
2013           KernelInfo
2014             *kernel;
2015
2016           (void) SyncImageSettings(image_info,*image);
2017           kernel=AcquireKernelInfo(argv[1]);
2018           if (kernel == (KernelInfo *) NULL)
2019             break;
2020           new_image=ColorMatrixImage(*image,kernel,exception);
2021           kernel=DestroyKernelInfo(kernel);
2022           break;
2023         }
2024       if (LocaleCompare("colors",argv[0]+1) == 0)
2025         {
2026           /*
2027             Reduce the number of colors in the image.
2028           */
2029           (void) SyncImageSettings(image_info,*image);
2030           quantize_info->number_colors=StringToUnsignedLong(argv[1]);
2031           if (quantize_info->number_colors == 0)
2032             break;
2033           if (((*image)->storage_class == DirectClass) ||
2034               (*image)->colors > quantize_info->number_colors)
2035             (void) QuantizeImage(quantize_info,*image,exception);
2036           else
2037             (void) CompressImageColormap(*image,exception);
2038           break;
2039         }
2040       if (LocaleCompare("colorspace",argv[0]+1) == 0)
2041         {
2042           ColorspaceType
2043             colorspace;
2044
2045           (void) SyncImageSettings(image_info,*image);
2046           if (*argv[0] == '+')
2047             {
2048               (void) TransformImageColorspace(*image,RGBColorspace);
2049               InheritException(exception,&(*image)->exception);
2050               break;
2051             }
2052           colorspace=(ColorspaceType) ParseCommandOption(
2053             MagickColorspaceOptions,MagickFalse,argv[1]);
2054           (void) TransformImageColorspace(*image,colorspace);
2055           InheritException(exception,&(*image)->exception);
2056           break;
2057         }
2058       if (LocaleCompare("contrast",argv[0]+1) == 0)
2059         {
2060           (void) SyncImageSettings(image_info,*image);
2061           (void) ContrastImage(*image,(*argv[0] == '-') ? MagickTrue :
2062             MagickFalse,exception);
2063           break;
2064         }
2065       if (LocaleCompare("contrast-stretch",argv[0]+1) == 0)
2066         {
2067           double
2068             black_point,
2069             white_point;
2070
2071           MagickStatusType
2072             flags;
2073
2074           /*
2075             Contrast stretch image.
2076           */
2077           (void) SyncImageSettings(image_info,*image);
2078           flags=ParseGeometry(argv[1],&geometry_info);
2079           black_point=geometry_info.rho;
2080           white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2081             black_point;
2082           if ((flags & PercentValue) != 0)
2083             {
2084               black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2085               white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2086             }
2087           white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2088             white_point;
2089           (void) ContrastStretchImage(*image,black_point,white_point,
2090             exception);
2091           InheritException(exception,&(*image)->exception);
2092           break;
2093         }
2094       if (LocaleCompare("convolve",argv[0]+1) == 0)
2095         {
2096           KernelInfo
2097             *kernel_info;
2098
2099           (void) SyncImageSettings(image_info,*image);
2100           kernel_info=AcquireKernelInfo(argv[1]);
2101           if (kernel_info == (KernelInfo *) NULL)
2102             break;
2103           kernel_info->bias=(*image)->bias;
2104           new_image=ConvolveImage(*image,kernel_info,exception);
2105           kernel_info=DestroyKernelInfo(kernel_info);
2106           break;
2107         }
2108       if (LocaleCompare("crop",argv[0]+1) == 0)
2109         {
2110           /*
2111             Crop a image to a smaller size
2112           */
2113           (void) SyncImageSettings(image_info,*image);
2114           new_image=CropImageToTiles(*image,argv[1],exception);
2115           break;
2116         }
2117       if (LocaleCompare("cycle",argv[0]+1) == 0)
2118         {
2119           /*
2120             Cycle an image colormap.
2121           */
2122           (void) SyncImageSettings(image_info,*image);
2123           (void) CycleColormapImage(*image,(ssize_t) StringToLong(argv[1]),
2124             exception);
2125           break;
2126         }
2127       break;
2128     }
2129     case 'd':
2130     {
2131       if (LocaleCompare("decipher",argv[0]+1) == 0)
2132         {
2133           StringInfo
2134             *passkey;
2135
2136           /*
2137             Decipher pixels.
2138           */
2139           (void) SyncImageSettings(image_info,*image);
2140           passkey=FileToStringInfo(argv[1],~0,exception);
2141           if (passkey != (StringInfo *) NULL)
2142             {
2143               (void) PasskeyDecipherImage(*image,passkey,exception);
2144               passkey=DestroyStringInfo(passkey);
2145             }
2146           break;
2147         }
2148       if (LocaleCompare("density",argv[0]+1) == 0)
2149         {
2150           /*
2151             Set image density.
2152           */
2153           (void) CloneString(&draw_info->density,argv[1]);
2154           break;
2155         }
2156       if (LocaleCompare("depth",argv[0]+1) == 0)
2157         {
2158           (void) SyncImageSettings(image_info,*image);
2159           if (*argv[0] == '+')
2160             {
2161               (void) SetImageDepth(*image,MAGICKCORE_QUANTUM_DEPTH);
2162               break;
2163             }
2164           (void) SetImageDepth(*image,StringToUnsignedLong(argv[1]));
2165           break;
2166         }
2167       if (LocaleCompare("deskew",argv[0]+1) == 0)
2168         {
2169           double
2170             threshold;
2171
2172           /*
2173             Straighten the image.
2174           */
2175           (void) SyncImageSettings(image_info,*image);
2176           if (*argv[0] == '+')
2177             threshold=40.0*QuantumRange/100.0;
2178           else
2179             threshold=SiPrefixToDouble(argv[1],QuantumRange);
2180           new_image=DeskewImage(*image,threshold,exception);
2181           break;
2182         }
2183       if (LocaleCompare("despeckle",argv[0]+1) == 0)
2184         {
2185           /*
2186             Reduce the speckles within an image.
2187           */
2188           (void) SyncImageSettings(image_info,*image);
2189           new_image=DespeckleImage(*image,exception);
2190           break;
2191         }
2192       if (LocaleCompare("display",argv[0]+1) == 0)
2193         {
2194           (void) CloneString(&draw_info->server_name,argv[1]);
2195           break;
2196         }
2197       if (LocaleCompare("distort",argv[0]+1) == 0)
2198         {
2199           char
2200             *args,
2201             token[MaxTextExtent];
2202
2203           const char
2204             *p;
2205
2206           DistortImageMethod
2207             method;
2208
2209           double
2210             *arguments;
2211
2212           register ssize_t
2213             x;
2214
2215           size_t
2216             number_arguments;
2217
2218           /*
2219             Distort image.
2220           */
2221           (void) SyncImageSettings(image_info,*image);
2222           method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
2223             MagickFalse,argv[1]);
2224           if ( method == ResizeDistortion )
2225             {
2226                /* Special Case - Argument is actually a resize geometry!
2227                ** Convert that to an appropriate distortion argument array.
2228                */
2229                double
2230                  resize_args[2];
2231                (void) ParseRegionGeometry(*image,argv[2],&geometry,
2232                     exception);
2233                resize_args[0]=(double)geometry.width;
2234                resize_args[1]=(double)geometry.height;
2235                new_image=DistortImage(*image,method,(size_t)2,
2236                     resize_args,MagickTrue,exception);
2237                break;
2238             }
2239           args=InterpretImageProperties(image_info,*image,argv[2],
2240             exception);
2241           if (args == (char *) NULL)
2242             break;
2243           p=(char *) args;
2244           for (x=0; *p != '\0'; x++)
2245           {
2246             GetMagickToken(p,&p,token);
2247             if (*token == ',')
2248               GetMagickToken(p,&p,token);
2249           }
2250           number_arguments=(size_t) x;
2251           arguments=(double *) AcquireQuantumMemory(number_arguments,
2252             sizeof(*arguments));
2253           if (arguments == (double *) NULL)
2254             ThrowWandFatalException(ResourceLimitFatalError,
2255               "MemoryAllocationFailed",(*image)->filename);
2256           (void) ResetMagickMemory(arguments,0,number_arguments*
2257             sizeof(*arguments));
2258           p=(char *) args;
2259           for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2260           {
2261             GetMagickToken(p,&p,token);
2262             if (*token == ',')
2263               GetMagickToken(p,&p,token);
2264             arguments[x]=InterpretLocaleValue(token,(char **) NULL);
2265           }
2266           args=DestroyString(args);
2267           new_image=DistortImage(*image,method,number_arguments,arguments,
2268             (*argv[0] == '+') ? MagickTrue : MagickFalse,exception);
2269           arguments=(double *) RelinquishMagickMemory(arguments);
2270           break;
2271         }
2272       if (LocaleCompare("dither",argv[0]+1) == 0)
2273         {
2274           if (*argv[0] == '+')
2275             {
2276               quantize_info->dither=MagickFalse;
2277               break;
2278             }
2279           quantize_info->dither=MagickTrue;
2280           quantize_info->dither_method=(DitherMethod) ParseCommandOption(
2281             MagickDitherOptions,MagickFalse,argv[1]);
2282           if (quantize_info->dither_method == NoDitherMethod)
2283             quantize_info->dither=MagickFalse;
2284           break;
2285         }
2286       if (LocaleCompare("draw",argv[0]+1) == 0)
2287         {
2288           /*
2289             Draw image.
2290           */
2291           (void) SyncImageSettings(image_info,*image);
2292           (void) CloneString(&draw_info->primitive,argv[1]);
2293           (void) DrawImage(*image,draw_info,exception);
2294           break;
2295         }
2296       break;
2297     }
2298     case 'e':
2299     {
2300       if (LocaleCompare("edge",argv[0]+1) == 0)
2301         {
2302           /*
2303             Enhance edges in the image.
2304           */
2305           (void) SyncImageSettings(image_info,*image);
2306           flags=ParseGeometry(argv[1],&geometry_info);
2307           if ((flags & SigmaValue) == 0)
2308             geometry_info.sigma=1.0;
2309           new_image=EdgeImage(*image,geometry_info.rho,
2310             geometry_info.sigma,exception);
2311           break;
2312         }
2313       if (LocaleCompare("emboss",argv[0]+1) == 0)
2314         {
2315           /*
2316             Gaussian embossen image.
2317           */
2318           (void) SyncImageSettings(image_info,*image);
2319           flags=ParseGeometry(argv[1],&geometry_info);
2320           if ((flags & SigmaValue) == 0)
2321             geometry_info.sigma=1.0;
2322           new_image=EmbossImage(*image,geometry_info.rho,
2323             geometry_info.sigma,exception);
2324           break;
2325         }
2326       if (LocaleCompare("encipher",argv[0]+1) == 0)
2327         {
2328           StringInfo
2329             *passkey;
2330
2331           /*
2332             Encipher pixels.
2333           */
2334           (void) SyncImageSettings(image_info,*image);
2335           passkey=FileToStringInfo(argv[1],~0,exception);
2336           if (passkey != (StringInfo *) NULL)
2337             {
2338               (void) PasskeyEncipherImage(*image,passkey,exception);
2339               passkey=DestroyStringInfo(passkey);
2340             }
2341           break;
2342         }
2343       if (LocaleCompare("encoding",argv[0]+1) == 0)
2344         {
2345           (void) CloneString(&draw_info->encoding,argv[1]);
2346           break;
2347         }
2348       if (LocaleCompare("enhance",argv[0]+1) == 0)
2349         {
2350           /*
2351             Enhance image.
2352           */
2353           (void) SyncImageSettings(image_info,*image);
2354           new_image=EnhanceImage(*image,exception);
2355           break;
2356         }
2357       if (LocaleCompare("equalize",argv[0]+1) == 0)
2358         {
2359           /*
2360             Equalize image.
2361           */
2362           (void) SyncImageSettings(image_info,*image);
2363           (void) EqualizeImage(*image,exception);
2364           break;
2365         }
2366       if (LocaleCompare("evaluate",argv[0]+1) == 0)
2367         {
2368           double
2369             constant;
2370
2371           MagickEvaluateOperator
2372             op;
2373
2374           (void) SyncImageSettings(image_info,*image);
2375           op=(MagickEvaluateOperator) ParseCommandOption(
2376             MagickEvaluateOptions,MagickFalse,argv[1]);
2377           constant=SiPrefixToDouble(argv[2],QuantumRange);
2378           (void) EvaluateImage(*image,op,constant,exception);
2379           break;
2380         }
2381       if (LocaleCompare("extent",argv[0]+1) == 0)
2382         {
2383           /*
2384             Set the image extent.
2385           */
2386           (void) SyncImageSettings(image_info,*image);
2387           flags=ParseGravityGeometry(*image,argv[1],&geometry,exception);
2388           if (geometry.width == 0)
2389             geometry.width=(*image)->columns;
2390           if (geometry.height == 0)
2391             geometry.height=(*image)->rows;
2392           new_image=ExtentImage(*image,&geometry,exception);
2393           break;
2394         }
2395       break;
2396     }
2397     case 'f':
2398     {
2399       if (LocaleCompare("family",argv[0]+1) == 0)
2400         {
2401           if (*argv[0] == '+')
2402             {
2403               if (draw_info->family != (char *) NULL)
2404                 draw_info->family=DestroyString(draw_info->family);
2405               break;
2406             }
2407           (void) CloneString(&draw_info->family,argv[1]);
2408           break;
2409         }
2410       if (LocaleCompare("features",argv[0]+1) == 0)
2411         {
2412           if (*argv[0] == '+')
2413             {
2414               (void) DeleteImageArtifact(*image,"identify:features");
2415               break;
2416             }
2417           (void) SetImageArtifact(*image,"identify:features",argv[1]);
2418           break;
2419         }
2420       if (LocaleCompare("fill",argv[0]+1) == 0)
2421         {
2422           ExceptionInfo
2423             *sans;
2424
2425           GetPixelInfo(*image,&fill);
2426           if (*argv[0] == '+')
2427             {
2428               (void) QueryMagickColorCompliance("none",&fill,exception);
2429               (void) QueryColorCompliance("none",&draw_info->fill,exception);
2430               if (draw_info->fill_pattern != (Image *) NULL)
2431                 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
2432               break;
2433             }
2434           sans=AcquireExceptionInfo();
2435           (void) QueryMagickColorCompliance(argv[1],&fill,sans);
2436           status=QueryColorCompliance(argv[1],&draw_info->fill,sans);
2437           sans=DestroyExceptionInfo(sans);
2438           if (status == MagickFalse)
2439             draw_info->fill_pattern=GetImageCache(image_info,argv[1],
2440               exception);
2441           break;
2442         }
2443       if (LocaleCompare("flip",argv[0]+1) == 0)
2444         {
2445           /*
2446             Flip image scanlines.
2447           */
2448           (void) SyncImageSettings(image_info,*image);
2449           new_image=FlipImage(*image,exception);
2450           break;
2451         }
2452       if (LocaleCompare("flop",argv[0]+1) == 0)
2453         {
2454           /*
2455             Flop image scanlines.
2456           */
2457           (void) SyncImageSettings(image_info,*image);
2458           new_image=FlopImage(*image,exception);
2459           break;
2460         }
2461       if (LocaleCompare("floodfill",argv[0]+1) == 0)
2462         {
2463           PixelInfo
2464             target;
2465
2466           /*
2467             Floodfill image.
2468           */
2469           (void) SyncImageSettings(image_info,*image);
2470           (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
2471           (void) QueryMagickColorCompliance(argv[2],&target,exception);
2472           (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
2473             geometry.y,*argv[0] == '-' ? MagickFalse : MagickTrue,exception);
2474           break;
2475         }
2476       if (LocaleCompare("font",argv[0]+1) == 0)
2477         {
2478           if (*argv[0] == '+')
2479             {
2480               if (draw_info->font != (char *) NULL)
2481                 draw_info->font=DestroyString(draw_info->font);
2482               break;
2483             }
2484           (void) CloneString(&draw_info->font,argv[1]);
2485           break;
2486         }
2487       if (LocaleCompare("format",argv[0]+1) == 0)
2488         {
2489           format=argv[1];
2490           break;
2491         }
2492       if (LocaleCompare("frame",argv[0]+1) == 0)
2493         {
2494           FrameInfo
2495             frame_info;
2496
2497           /*
2498             Surround image with an ornamental border.
2499           */
2500           (void) SyncImageSettings(image_info,*image);
2501           flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
2502           frame_info.width=geometry.width;
2503           frame_info.height=geometry.height;
2504           if ((flags & HeightValue) == 0)
2505             frame_info.height=geometry.width;
2506           frame_info.outer_bevel=geometry.x;
2507           frame_info.inner_bevel=geometry.y;
2508           frame_info.x=(ssize_t) frame_info.width;
2509           frame_info.y=(ssize_t) frame_info.height;
2510           frame_info.width=(*image)->columns+2*frame_info.width;
2511           frame_info.height=(*image)->rows+2*frame_info.height;
2512           new_image=FrameImage(*image,&frame_info,exception);
2513           break;
2514         }
2515       if (LocaleCompare("function",argv[0]+1) == 0)
2516         {
2517           char
2518             *arguments,
2519             token[MaxTextExtent];
2520
2521           const char
2522             *p;
2523
2524           double
2525             *parameters;
2526
2527           MagickFunction
2528             function;
2529
2530           register ssize_t
2531             x;
2532
2533           size_t
2534             number_parameters;
2535
2536           /*
2537             Function Modify Image Values
2538           */
2539           (void) SyncImageSettings(image_info,*image);
2540           function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
2541             MagickFalse,argv[1]);
2542           arguments=InterpretImageProperties(image_info,*image,argv[2],
2543             exception);
2544           if (arguments == (char *) NULL)
2545             break;
2546           p=(char *) arguments;
2547           for (x=0; *p != '\0'; x++)
2548           {
2549             GetMagickToken(p,&p,token);
2550             if (*token == ',')
2551               GetMagickToken(p,&p,token);
2552           }
2553           number_parameters=(size_t) x;
2554           parameters=(double *) AcquireQuantumMemory(number_parameters,
2555             sizeof(*parameters));
2556           if (parameters == (double *) NULL)
2557             ThrowWandFatalException(ResourceLimitFatalError,
2558               "MemoryAllocationFailed",(*image)->filename);
2559           (void) ResetMagickMemory(parameters,0,number_parameters*
2560             sizeof(*parameters));
2561           p=(char *) arguments;
2562           for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
2563           {
2564             GetMagickToken(p,&p,token);
2565             if (*token == ',')
2566               GetMagickToken(p,&p,token);
2567             parameters[x]=InterpretLocaleValue(token,(char **) NULL);
2568           }
2569           arguments=DestroyString(arguments);
2570           (void) FunctionImage(*image,function,number_parameters,parameters,
2571             exception);
2572           parameters=(double *) RelinquishMagickMemory(parameters);
2573           break;
2574         }
2575       break;
2576     }
2577     case 'g':
2578     {
2579       if (LocaleCompare("gamma",argv[0]+1) == 0)
2580         {
2581           /*
2582             Gamma image.
2583           */
2584           (void) SyncImageSettings(image_info,*image);
2585           if (*argv[0] == '+')
2586             (*image)->gamma=InterpretLocaleValue(argv[1],(char **) NULL);
2587           else
2588             (void) GammaImage(*image,InterpretLocaleValue(argv[1],
2589               (char **) NULL),exception);
2590           break;
2591         }
2592       if ((LocaleCompare("gaussian-blur",argv[0]+1) == 0) ||
2593           (LocaleCompare("gaussian",argv[0]+1) == 0))
2594         {
2595           /*
2596             Gaussian blur image.
2597           */
2598           (void) SyncImageSettings(image_info,*image);
2599           flags=ParseGeometry(argv[1],&geometry_info);
2600           if ((flags & SigmaValue) == 0)
2601             geometry_info.sigma=1.0;
2602           if ((flags & XiValue) == 0)
2603             geometry_info.xi=0.0;
2604           new_image=GaussianBlurImage(*image,geometry_info.rho,
2605             geometry_info.sigma,geometry_info.xi,exception);
2606           break;
2607         }
2608       if (LocaleCompare("geometry",argv[0]+1) == 0)
2609         {
2610             /*
2611               Record Image offset, Resize last image.
2612             */
2613           (void) SyncImageSettings(image_info,*image);
2614           if (*argv[0] == '+')
2615             {
2616               if ((*image)->geometry != (char *) NULL)
2617                 (*image)->geometry=DestroyString((*image)->geometry);
2618               break;
2619             }
2620           flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2621           if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2622             (void) CloneString(&(*image)->geometry,argv[1]);
2623           else
2624             new_image=ResizeImage(*image,geometry.width,geometry.height,
2625               (*image)->filter,(*image)->blur,exception);
2626           break;
2627         }
2628       if (LocaleCompare("gravity",argv[0]+1) == 0)
2629         {
2630           if (*argv[0] == '+')
2631             {
2632               draw_info->gravity=UndefinedGravity;
2633               break;
2634             }
2635           draw_info->gravity=(GravityType) ParseCommandOption(
2636             MagickGravityOptions,MagickFalse,argv[1]);
2637           break;
2638         }
2639       break;
2640     }
2641     case 'h':
2642     {
2643       if (LocaleCompare("highlight-color",argv[0]+1) == 0)
2644         {
2645           (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
2646           break;
2647         }
2648       break;
2649     }
2650     case 'i':
2651     {
2652       if (LocaleCompare("identify",argv[0]+1) == 0)
2653         {
2654           char
2655             *text;
2656
2657           (void) SyncImageSettings(image_info,*image);
2658           if (format == (char *) NULL)
2659             {
2660               (void) IdentifyImage(*image,stdout,image_info->verbose,
2661                 exception);
2662               break;
2663             }
2664           text=InterpretImageProperties(image_info,*image,format,
2665             exception);
2666           if (text == (char *) NULL)
2667             break;
2668           (void) fputs(text,stdout);
2669           (void) fputc('\n',stdout);
2670           text=DestroyString(text);
2671           break;
2672         }
2673       if (LocaleCompare("implode",argv[0]+1) == 0)
2674         {
2675           /*
2676             Implode image.
2677           */
2678           (void) SyncImageSettings(image_info,*image);
2679           (void) ParseGeometry(argv[1],&geometry_info);
2680           new_image=ImplodeImage(*image,geometry_info.rho,exception);
2681           break;
2682         }
2683       if (LocaleCompare("interline-spacing",argv[0]+1) == 0)
2684         {
2685           if (*argv[0] == '+')
2686             (void) ParseGeometry("0",&geometry_info);
2687           else
2688             (void) ParseGeometry(argv[1],&geometry_info);
2689           draw_info->interline_spacing=geometry_info.rho;
2690           break;
2691         }
2692       if (LocaleCompare("interword-spacing",argv[0]+1) == 0)
2693         {
2694           if (*argv[0] == '+')
2695             (void) ParseGeometry("0",&geometry_info);
2696           else
2697             (void) ParseGeometry(argv[1],&geometry_info);
2698           draw_info->interword_spacing=geometry_info.rho;
2699           break;
2700         }
2701       break;
2702     }
2703     case 'k':
2704     {
2705       if (LocaleCompare("kerning",argv[0]+1) == 0)
2706         {
2707           if (*argv[0] == '+')
2708             (void) ParseGeometry("0",&geometry_info);
2709           else
2710             (void) ParseGeometry(argv[1],&geometry_info);
2711           draw_info->kerning=geometry_info.rho;
2712           break;
2713         }
2714       break;
2715     }
2716     case 'l':
2717     {
2718       if (LocaleCompare("lat",argv[0]+1) == 0)
2719         {
2720           /*
2721             Local adaptive threshold image.
2722           */
2723           (void) SyncImageSettings(image_info,*image);
2724           flags=ParseGeometry(argv[1],&geometry_info);
2725           if ((flags & PercentValue) != 0)
2726             geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2727           new_image=AdaptiveThresholdImage(*image,(size_t)
2728             geometry_info.rho,(size_t) geometry_info.sigma,(double)
2729             geometry_info.xi,exception);
2730           break;
2731         }
2732       if (LocaleCompare("level",argv[0]+1) == 0)
2733         {
2734           MagickRealType
2735             black_point,
2736             gamma,
2737             white_point;
2738
2739           MagickStatusType
2740             flags;
2741
2742           /*
2743             Parse levels.
2744           */
2745           (void) SyncImageSettings(image_info,*image);
2746           flags=ParseGeometry(argv[1],&geometry_info);
2747           black_point=geometry_info.rho;
2748           white_point=(MagickRealType) QuantumRange;
2749           if ((flags & SigmaValue) != 0)
2750             white_point=geometry_info.sigma;
2751           gamma=1.0;
2752           if ((flags & XiValue) != 0)
2753             gamma=geometry_info.xi;
2754           if ((flags & PercentValue) != 0)
2755             {
2756               black_point*=(MagickRealType) (QuantumRange/100.0);
2757               white_point*=(MagickRealType) (QuantumRange/100.0);
2758             }
2759           if ((flags & SigmaValue) == 0)
2760             white_point=(MagickRealType) QuantumRange-black_point;
2761           if ((*argv[0] == '+') || ((flags & AspectValue) != 0))
2762             (void) LevelizeImage(*image,black_point,white_point,gamma,
2763               exception);
2764           else
2765             (void) LevelImage(*image,black_point,white_point,gamma,
2766               exception);
2767           InheritException(exception,&(*image)->exception);
2768           break;
2769         }
2770       if (LocaleCompare("level-colors",argv[0]+1) == 0)
2771         {
2772           char
2773             token[MaxTextExtent];
2774
2775           const char
2776             *p;
2777
2778           PixelInfo
2779             black_point,
2780             white_point;
2781
2782           p=(const char *) argv[1];
2783           GetMagickToken(p,&p,token);  /* get black point color */
2784           if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2785             (void) QueryMagickColorCompliance(token,&black_point,exception);
2786           else
2787             (void) QueryMagickColorCompliance("#000000",&black_point,exception);
2788           if (isalpha((int) token[0]) || (token[0] == '#'))
2789             GetMagickToken(p,&p,token);
2790           if (*token == '\0')
2791             white_point=black_point; /* set everything to that color */
2792           else
2793             {
2794               if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2795                 GetMagickToken(p,&p,token); /* Get white point color. */
2796               if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2797                 (void) QueryMagickColorCompliance(token,&white_point,exception);
2798               else
2799                 (void) QueryMagickColorCompliance("#ffffff",&white_point,exception);
2800             }
2801           (void) LevelImageColors(*image,&black_point,&white_point,
2802             *argv[0] == '+' ? MagickTrue : MagickFalse,exception);
2803           break;
2804         }
2805       if (LocaleCompare("linear-stretch",argv[0]+1) == 0)
2806         {
2807           double
2808             black_point,
2809             white_point;
2810
2811           MagickStatusType
2812             flags;
2813
2814           (void) SyncImageSettings(image_info,*image);
2815           flags=ParseGeometry(argv[1],&geometry_info);
2816           black_point=geometry_info.rho;
2817           white_point=(MagickRealType) (*image)->columns*(*image)->rows;
2818           if ((flags & SigmaValue) != 0)
2819             white_point=geometry_info.sigma;
2820           if ((flags & PercentValue) != 0)
2821             {
2822               black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2823               white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2824             }
2825           if ((flags & SigmaValue) == 0)
2826             white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2827               black_point;
2828           (void) LinearStretchImage(*image,black_point,white_point,exception);
2829           InheritException(exception,&(*image)->exception);
2830           break;
2831         }
2832       if (LocaleCompare("linewidth",argv[0]+1) == 0)
2833         {
2834           draw_info->stroke_width=InterpretLocaleValue(argv[1],
2835             (char **) NULL);
2836           break;
2837         }
2838       if (LocaleCompare("liquid-rescale",argv[0]+1) == 0)
2839         {
2840           /*
2841             Liquid rescale image.
2842           */
2843           (void) SyncImageSettings(image_info,*image);
2844           flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
2845           if ((flags & XValue) == 0)
2846             geometry.x=1;
2847           if ((flags & YValue) == 0)
2848             geometry.y=0;
2849           new_image=LiquidRescaleImage(*image,geometry.width,
2850             geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
2851           break;
2852         }
2853       if (LocaleCompare("lowlight-color",argv[0]+1) == 0)
2854         {
2855           (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
2856           break;
2857         }
2858       break;
2859     }
2860     case 'm':
2861     {
2862       if (LocaleCompare("map",argv[0]+1) == 0)
2863         {
2864           Image
2865             *remap_image;
2866
2867           /*
2868             Transform image colors to match this set of colors.
2869           */
2870           (void) SyncImageSettings(image_info,*image);
2871           if (*argv[0] == '+')
2872             break;
2873           remap_image=GetImageCache(image_info,argv[1],exception);
2874           if (remap_image == (Image *) NULL)
2875             break;
2876           (void) RemapImage(quantize_info,*image,remap_image,exception);
2877           remap_image=DestroyImage(remap_image);
2878           break;
2879         }
2880       if (LocaleCompare("mask",argv[0]+1) == 0)
2881         {
2882           Image
2883             *mask;
2884
2885           (void) SyncImageSettings(image_info,*image);
2886           if (*argv[0] == '+')
2887             {
2888               /*
2889                 Remove a mask.
2890               */
2891               (void) SetImageMask(*image,(Image *) NULL,exception);
2892               break;
2893             }
2894           /*
2895             Set the image mask.
2896           */
2897           mask=GetImageCache(image_info,argv[1],exception);
2898           if (mask == (Image *) NULL)
2899             break;
2900           (void) SetImageMask(*image,mask,exception);
2901           mask=DestroyImage(mask);
2902           break;
2903         }
2904       if (LocaleCompare("matte",argv[0]+1) == 0)
2905         {
2906           (void) SetImageAlphaChannel(*image,(*argv[0] == '-') ?
2907             SetAlphaChannel : DeactivateAlphaChannel,exception);
2908           break;
2909         }
2910       if (LocaleCompare("median",argv[0]+1) == 0)
2911         {
2912           /*
2913             Median filter image.
2914           */
2915           (void) SyncImageSettings(image_info,*image);
2916           flags=ParseGeometry(argv[1],&geometry_info);
2917           if ((flags & SigmaValue) == 0)
2918             geometry_info.sigma=geometry_info.rho;
2919           new_image=StatisticImage(*image,MedianStatistic,(size_t)
2920             geometry_info.rho,(size_t) geometry_info.sigma,exception);
2921           break;
2922         }
2923       if (LocaleCompare("mode",argv[0]+1) == 0)
2924         {
2925           /*
2926             Mode image.
2927           */
2928           (void) SyncImageSettings(image_info,*image);
2929           flags=ParseGeometry(argv[1],&geometry_info);
2930           if ((flags & SigmaValue) == 0)
2931             geometry_info.sigma=geometry_info.rho;
2932           new_image=StatisticImage(*image,ModeStatistic,(size_t)
2933             geometry_info.rho,(size_t) geometry_info.sigma,exception);
2934           break;
2935         }
2936       if (LocaleCompare("modulate",argv[0]+1) == 0)
2937         {
2938           (void) SyncImageSettings(image_info,*image);
2939           (void) ModulateImage(*image,argv[1],exception);
2940           break;
2941         }
2942       if (LocaleCompare("monitor",argv[0]+1) == 0)
2943         {
2944           if (*argv[0] == '+')
2945             {
2946               (void) SetImageProgressMonitor(*image,
2947                 (MagickProgressMonitor) NULL,(void *) NULL);
2948               break;
2949             }
2950           (void) SetImageProgressMonitor(*image,MonitorProgress,
2951             (void *) NULL);
2952           break;
2953         }
2954       if (LocaleCompare("monochrome",argv[0]+1) == 0)
2955         {
2956           (void) SyncImageSettings(image_info,*image);
2957           (void) SetImageType(*image,BilevelType,exception);
2958           break;
2959         }
2960       if (LocaleCompare("morphology",argv[0]+1) == 0)
2961         {
2962           char
2963             token[MaxTextExtent];
2964
2965           const char
2966             *p;
2967
2968           KernelInfo
2969             *kernel;
2970
2971           MorphologyMethod
2972             method;
2973
2974           ssize_t
2975             iterations;
2976
2977           /*
2978             Morphological Image Operation
2979           */
2980           (void) SyncImageSettings(image_info,*image);
2981           p=argv[1];
2982           GetMagickToken(p,&p,token);
2983           method=(MorphologyMethod) ParseCommandOption(
2984             MagickMorphologyOptions,MagickFalse,token);
2985           iterations=1L;
2986           GetMagickToken(p,&p,token);
2987           if ((*p == ':') || (*p == ','))
2988             GetMagickToken(p,&p,token);
2989           if ((*p != '\0'))
2990             iterations=(ssize_t) StringToLong(p);
2991           kernel=AcquireKernelInfo(argv[2]);
2992           if (kernel == (KernelInfo *) NULL)
2993             {
2994               (void) ThrowMagickException(exception,GetMagickModule(),
2995                 OptionError,"UnabletoParseKernel","morphology");
2996               status=MagickFalse;
2997               break;
2998             }
2999           new_image=MorphologyImage(*image,method,iterations,kernel,
3000             exception);
3001           kernel=DestroyKernelInfo(kernel);
3002           break;
3003         }
3004       if (LocaleCompare("motion-blur",argv[0]+1) == 0)
3005         {
3006           /*
3007             Motion blur image.
3008           */
3009           (void) SyncImageSettings(image_info,*image);
3010           flags=ParseGeometry(argv[1],&geometry_info);
3011           if ((flags & SigmaValue) == 0)
3012             geometry_info.sigma=1.0;
3013           new_image=MotionBlurImage(*image,geometry_info.rho,
3014             geometry_info.sigma,geometry_info.xi,geometry_info.psi,
3015             exception);
3016           break;
3017         }
3018       break;
3019     }
3020     case 'n':
3021     {
3022       if (LocaleCompare("negate",argv[0]+1) == 0)
3023         {
3024           (void) SyncImageSettings(image_info,*image);
3025           (void) NegateImage(*image,*argv[0] == '+' ? MagickTrue :
3026             MagickFalse,exception);
3027           break;
3028         }
3029       if (LocaleCompare("noise",argv[0]+1) == 0)
3030         {
3031           (void) SyncImageSettings(image_info,*image);
3032           if (*argv[0] == '-')
3033             {
3034               flags=ParseGeometry(argv[1],&geometry_info);
3035               if ((flags & SigmaValue) == 0)
3036                 geometry_info.sigma=geometry_info.rho;
3037               new_image=StatisticImage(*image,NonpeakStatistic,(size_t)
3038                 geometry_info.rho,(size_t) geometry_info.sigma,exception);
3039             }
3040           else
3041             {
3042               NoiseType
3043                 noise;
3044
3045               noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
3046                 MagickFalse,argv[1]);
3047               new_image=AddNoiseImage(*image,noise,exception);
3048             }
3049           break;
3050         }
3051       if (LocaleCompare("normalize",argv[0]+1) == 0)
3052         {
3053           (void) SyncImageSettings(image_info,*image);
3054           (void) NormalizeImage(*image,exception);
3055           break;
3056         }
3057       break;
3058     }
3059     case 'o':
3060     {
3061       if (LocaleCompare("opaque",argv[0]+1) == 0)
3062         {
3063           PixelInfo
3064             target;
3065
3066           (void) SyncImageSettings(image_info,*image);
3067           (void) QueryMagickColorCompliance(argv[1],&target,exception);
3068           (void) OpaquePaintImage(*image,&target,&fill,*argv[0] == '-' ?
3069             MagickFalse : MagickTrue,exception);
3070           break;
3071         }
3072       if (LocaleCompare("ordered-dither",argv[0]+1) == 0)
3073         {
3074           (void) SyncImageSettings(image_info,*image);
3075           (void) OrderedPosterizeImage(*image,argv[1],exception);
3076           break;
3077         }
3078       break;
3079     }
3080     case 'p':
3081     {
3082       if (LocaleCompare("paint",argv[0]+1) == 0)
3083         {
3084           (void) SyncImageSettings(image_info,*image);
3085           (void) ParseGeometry(argv[1],&geometry_info);
3086           new_image=OilPaintImage(*image,geometry_info.rho,
3087             geometry_info.sigma,exception);
3088           break;
3089         }
3090       if (LocaleCompare("pen",argv[0]+1) == 0)
3091         {
3092           if (*argv[0] == '+')
3093             {
3094               (void) QueryColorCompliance("none",&draw_info->fill,exception);
3095               break;
3096             }
3097           (void) QueryColorCompliance(argv[1],&draw_info->fill,exception);
3098           break;
3099         }
3100       if (LocaleCompare("pointsize",argv[0]+1) == 0)
3101         {
3102           if (*argv[0] == '+')
3103             (void) ParseGeometry("12",&geometry_info);
3104           else
3105             (void) ParseGeometry(argv[1],&geometry_info);
3106           draw_info->pointsize=geometry_info.rho;
3107           break;
3108         }
3109       if (LocaleCompare("polaroid",argv[0]+1) == 0)
3110         {
3111           double
3112             angle;
3113
3114           RandomInfo
3115             *random_info;
3116
3117           /*
3118             Simulate a Polaroid picture.
3119           */
3120           (void) SyncImageSettings(image_info,*image);
3121           random_info=AcquireRandomInfo();
3122           angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
3123           random_info=DestroyRandomInfo(random_info);
3124           if (*argv[0] == '-')
3125             {
3126               SetGeometryInfo(&geometry_info);
3127               flags=ParseGeometry(argv[1],&geometry_info);
3128               angle=geometry_info.rho;
3129             }
3130           new_image=PolaroidImage(*image,draw_info,angle,
3131             interpolate_method,exception);
3132           break;
3133         }
3134       if (LocaleCompare("posterize",argv[0]+1) == 0)
3135         {
3136           /*
3137             Posterize image.
3138           */
3139           (void) SyncImageSettings(image_info,*image);
3140           (void) PosterizeImage(*image,StringToUnsignedLong(argv[1]),
3141             quantize_info->dither,exception);
3142           break;
3143         }
3144       if (LocaleCompare("preview",argv[0]+1) == 0)
3145         {
3146           PreviewType
3147             preview_type;
3148
3149           /*
3150             Preview image.
3151           */
3152           (void) SyncImageSettings(image_info,*image);
3153           if (*argv[0] == '+')
3154             preview_type=UndefinedPreview;
3155           else
3156             preview_type=(PreviewType) ParseCommandOption(
3157               MagickPreviewOptions,MagickFalse,argv[1]);
3158           new_image=PreviewImage(*image,preview_type,exception);
3159           break;
3160         }
3161       if (LocaleCompare("profile",argv[0]+1) == 0)
3162         {
3163           const char
3164             *name;
3165
3166           const StringInfo
3167             *profile;
3168
3169           Image
3170             *profile_image;
3171
3172           ImageInfo
3173             *profile_info;
3174
3175           (void) SyncImageSettings(image_info,*image);
3176           if (*argv[0] == '+')
3177             {
3178               /*
3179                 Remove a profile from the image.
3180               */
3181               (void) ProfileImage(*image,argv[1],(const unsigned char *)
3182                 NULL,0,MagickTrue);
3183               InheritException(exception,&(*image)->exception);
3184               break;
3185             }
3186           /*
3187             Associate a profile with the image.
3188           */
3189           profile_info=CloneImageInfo(image_info);
3190           profile=GetImageProfile(*image,"iptc");
3191           if (profile != (StringInfo *) NULL)
3192             profile_info->profile=(void *) CloneStringInfo(profile);
3193           profile_image=GetImageCache(profile_info,argv[1],exception);
3194           profile_info=DestroyImageInfo(profile_info);
3195           if (profile_image == (Image *) NULL)
3196             {
3197               StringInfo
3198                 *profile;
3199
3200               profile_info=CloneImageInfo(image_info);
3201               (void) CopyMagickString(profile_info->filename,argv[1],
3202                 MaxTextExtent);
3203               profile=FileToStringInfo(profile_info->filename,~0UL,exception);
3204               if (profile != (StringInfo *) NULL)
3205                 {
3206                   (void) ProfileImage(*image,profile_info->magick,
3207                     GetStringInfoDatum(profile),(size_t)
3208                     GetStringInfoLength(profile),MagickFalse);
3209                   profile=DestroyStringInfo(profile);
3210                 }
3211               profile_info=DestroyImageInfo(profile_info);
3212               break;
3213             }
3214           ResetImageProfileIterator(profile_image);
3215           name=GetNextImageProfile(profile_image);
3216           while (name != (const char *) NULL)
3217           {
3218             profile=GetImageProfile(profile_image,name);
3219             if (profile != (StringInfo *) NULL)
3220               (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
3221                 (size_t) GetStringInfoLength(profile),MagickFalse);
3222             name=GetNextImageProfile(profile_image);
3223           }
3224           profile_image=DestroyImage(profile_image);
3225           break;
3226         }
3227       break;
3228     }
3229     case 'q':
3230     {
3231       if (LocaleCompare("quantize",argv[0]+1) == 0)
3232         {
3233           if (*argv[0] == '+')
3234             {
3235               quantize_info->colorspace=UndefinedColorspace;
3236               break;
3237             }
3238           quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
3239             MagickColorspaceOptions,MagickFalse,argv[1]);
3240           break;
3241         }
3242       break;
3243     }
3244     case 'r':
3245     {
3246       if (LocaleCompare("radial-blur",argv[0]+1) == 0)
3247         {
3248           /*
3249             Radial blur image.
3250           */
3251           (void) SyncImageSettings(image_info,*image);
3252           flags=ParseGeometry(argv[1],&geometry_info);
3253           new_image=RadialBlurImage(*image,geometry_info.rho,
3254             geometry_info.sigma,exception);
3255           break;
3256         }
3257       if (LocaleCompare("raise",argv[0]+1) == 0)
3258         {
3259           /*
3260             Surround image with a raise of solid color.
3261           */
3262           flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3263           if ((flags & SigmaValue) == 0)
3264             geometry.height=geometry.width;
3265           (void) RaiseImage(*image,&geometry,*argv[0] == '-' ? MagickTrue :
3266             MagickFalse,exception);
3267           break;
3268         }
3269       if (LocaleCompare("random-threshold",argv[0]+1) == 0)
3270         {
3271           /*
3272             Threshold image.
3273           */
3274           (void) SyncImageSettings(image_info,*image);
3275           (void) RandomThresholdImage(*image,argv[1],exception);
3276           break;
3277         }
3278       if (LocaleCompare("recolor",argv[0]+1) == 0)
3279         {
3280           KernelInfo
3281             *kernel;
3282
3283           (void) SyncImageSettings(image_info,*image);
3284           kernel=AcquireKernelInfo(argv[1]);
3285           if (kernel == (KernelInfo *) NULL)
3286             break;
3287           new_image=ColorMatrixImage(*image,kernel,exception);
3288           kernel=DestroyKernelInfo(kernel);
3289           break;
3290         }
3291       if (LocaleCompare("render",argv[0]+1) == 0)
3292         {
3293           (void) SyncImageSettings(image_info,*image);
3294           draw_info->render=(*argv[0] == '+') ? MagickTrue : MagickFalse;
3295           break;
3296         }
3297       if (LocaleCompare("remap",argv[0]+1) == 0)
3298         {
3299           Image
3300             *remap_image;
3301
3302           /*
3303             Transform image colors to match this set of colors.
3304           */
3305           (void) SyncImageSettings(image_info,*image);
3306           if (*argv[0] == '+')
3307             break;
3308           remap_image=GetImageCache(image_info,argv[1],exception);
3309           if (remap_image == (Image *) NULL)
3310             break;
3311           (void) RemapImage(quantize_info,*image,remap_image,exception);
3312           remap_image=DestroyImage(remap_image);
3313           break;
3314         }
3315       if (LocaleCompare("repage",argv[0]+1) == 0)
3316         {
3317           if (*argv[0] == '+')
3318             {
3319               (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
3320               break;
3321             }
3322           (void) ResetImagePage(*image,argv[1]);
3323           InheritException(exception,&(*image)->exception);
3324           break;
3325         }
3326       if (LocaleCompare("resample",argv[0]+1) == 0)
3327         {
3328           /*
3329             Resample image.
3330           */
3331           (void) SyncImageSettings(image_info,*image);
3332           flags=ParseGeometry(argv[1],&geometry_info);
3333           if ((flags & SigmaValue) == 0)
3334             geometry_info.sigma=geometry_info.rho;
3335           new_image=ResampleImage(*image,geometry_info.rho,
3336             geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
3337           break;
3338         }
3339       if (LocaleCompare("resize",argv[0]+1) == 0)
3340         {
3341           /*
3342             Resize image.
3343           */
3344           (void) SyncImageSettings(image_info,*image);
3345           (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3346           new_image=ResizeImage(*image,geometry.width,geometry.height,
3347             (*image)->filter,(*image)->blur,exception);
3348           break;
3349         }
3350       if (LocaleCompare("roll",argv[0]+1) == 0)
3351         {
3352           /*
3353             Roll image.
3354           */
3355           (void) SyncImageSettings(image_info,*image);
3356           (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
3357           new_image=RollImage(*image,geometry.x,geometry.y,exception);
3358           break;
3359         }
3360       if (LocaleCompare("rotate",argv[0]+1) == 0)
3361         {
3362           char
3363             *geometry;
3364
3365           /*
3366             Check for conditional image rotation.
3367           */
3368           (void) SyncImageSettings(image_info,*image);
3369           if (strchr(argv[1],'>') != (char *) NULL)
3370             if ((*image)->columns <= (*image)->rows)
3371               break;
3372           if (strchr(argv[1],'<') != (char *) NULL)
3373             if ((*image)->columns >= (*image)->rows)
3374               break;
3375           /*
3376             Rotate image.
3377           */
3378           geometry=ConstantString(argv[1]);
3379           (void) SubstituteString(&geometry,">","");
3380           (void) SubstituteString(&geometry,"<","");
3381           (void) ParseGeometry(geometry,&geometry_info);
3382           geometry=DestroyString(geometry);
3383           new_image=RotateImage(*image,geometry_info.rho,exception);
3384           break;
3385         }
3386       break;
3387     }
3388     case 's':
3389     {
3390       if (LocaleCompare("sample",argv[0]+1) == 0)
3391         {
3392           /*
3393             Sample image with pixel replication.
3394           */
3395           (void) SyncImageSettings(image_info,*image);
3396           (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3397           new_image=SampleImage(*image,geometry.width,geometry.height,
3398             exception);
3399           break;
3400         }
3401       if (LocaleCompare("scale",argv[0]+1) == 0)
3402         {
3403           /*
3404             Resize image.
3405           */
3406           (void) SyncImageSettings(image_info,*image);
3407           (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3408           new_image=ScaleImage(*image,geometry.width,geometry.height,
3409             exception);
3410           break;
3411         }
3412       if (LocaleCompare("selective-blur",argv[0]+1) == 0)
3413         {
3414           /*
3415             Selectively blur pixels within a contrast threshold.
3416           */
3417           (void) SyncImageSettings(image_info,*image);
3418           flags=ParseGeometry(argv[1],&geometry_info);
3419           if ((flags & PercentValue) != 0)
3420             geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3421           new_image=SelectiveBlurImage(*image,geometry_info.rho,
3422             geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3423           break;
3424         }
3425       if (LocaleCompare("separate",argv[0]+1) == 0)
3426         {
3427           /*
3428             Break channels into separate images.
3429             WARNING: This can generate multiple images!
3430           */
3431           (void) SyncImageSettings(image_info,*image);
3432           new_image=SeparateImages(*image,exception);
3433           break;
3434         }
3435       if (LocaleCompare("sepia-tone",argv[0]+1) == 0)
3436         {
3437           double
3438             threshold;
3439
3440           /*
3441             Sepia-tone image.
3442           */
3443           (void) SyncImageSettings(image_info,*image);
3444           threshold=SiPrefixToDouble(argv[1],QuantumRange);
3445           new_image=SepiaToneImage(*image,threshold,exception);
3446           break;
3447         }
3448       if (LocaleCompare("segment",argv[0]+1) == 0)
3449         {
3450           /*
3451             Segment image.
3452           */
3453           (void) SyncImageSettings(image_info,*image);
3454           flags=ParseGeometry(argv[1],&geometry_info);
3455           if ((flags & SigmaValue) == 0)
3456             geometry_info.sigma=1.0;
3457           (void) SegmentImage(*image,(*image)->colorspace,
3458             image_info->verbose,geometry_info.rho,geometry_info.sigma,
3459             exception);
3460           break;
3461         }
3462       if (LocaleCompare("set",argv[0]+1) == 0)
3463         {
3464           char
3465             *value;
3466
3467           /*
3468             Set image argv[0].
3469           */
3470           if (*argv[0] == '+')
3471             {
3472               if (LocaleNCompare(argv[1],"registry:",9) == 0)
3473                 (void) DeleteImageRegistry(argv[1]+9);
3474               else
3475                 if (LocaleNCompare(argv[1],"argv[0]:",7) == 0)
3476                   {
3477                     (void) DeleteImageOption(image_info,argv[1]+7);
3478                     (void) DeleteImageArtifact(*image,argv[1]+7);
3479                   }
3480                 else
3481                   (void) DeleteImageProperty(*image,argv[1]);
3482               break;
3483             }
3484           value=InterpretImageProperties(image_info,*image,argv[2],
3485             exception);
3486           if (value == (char *) NULL)
3487             break;
3488           if (LocaleNCompare(argv[1],"registry:",9) == 0)
3489             (void) SetImageRegistry(StringRegistryType,argv[1]+9,value,
3490               exception);
3491           else
3492             if (LocaleNCompare(argv[1],"argv[0]:",7) == 0)
3493               {
3494                 (void) SetImageOption(image_info,argv[1]+7,value);
3495                 (void) SetImageOption(image_info,argv[1]+7,value);
3496                 (void) SetImageArtifact(*image,argv[1]+7,value);
3497               }
3498             else
3499               (void) SetImageProperty(*image,argv[1],value);
3500           value=DestroyString(value);
3501           break;
3502         }
3503       if (LocaleCompare("shade",argv[0]+1) == 0)
3504         {
3505           /*
3506             Shade image.
3507           */
3508           (void) SyncImageSettings(image_info,*image);
3509           flags=ParseGeometry(argv[1],&geometry_info);
3510           if ((flags & SigmaValue) == 0)
3511             geometry_info.sigma=1.0;
3512           new_image=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue :
3513             MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
3514           break;
3515         }
3516       if (LocaleCompare("shadow",argv[0]+1) == 0)
3517         {
3518           /*
3519             Shadow image.
3520           */
3521           (void) SyncImageSettings(image_info,*image);
3522           flags=ParseGeometry(argv[1],&geometry_info);
3523           if ((flags & SigmaValue) == 0)
3524             geometry_info.sigma=1.0;
3525           if ((flags & XiValue) == 0)
3526             geometry_info.xi=4.0;
3527           if ((flags & PsiValue) == 0)
3528             geometry_info.psi=4.0;
3529           new_image=ShadowImage(*image,geometry_info.rho,
3530             geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3531             ceil(geometry_info.psi-0.5),exception);
3532           break;
3533         }
3534       if (LocaleCompare("sharpen",argv[0]+1) == 0)
3535         {
3536           /*
3537             Sharpen image.
3538           */
3539           (void) SyncImageSettings(image_info,*image);
3540           flags=ParseGeometry(argv[1],&geometry_info);
3541           if ((flags & SigmaValue) == 0)
3542             geometry_info.sigma=1.0;
3543           if ((flags & XiValue) == 0)
3544             geometry_info.xi=0.0;
3545           new_image=SharpenImage(*image,geometry_info.rho,
3546             geometry_info.sigma,geometry_info.xi,exception);
3547           break;
3548         }
3549       if (LocaleCompare("shave",argv[0]+1) == 0)
3550         {
3551           /*
3552             Shave the image edges.
3553           */
3554           (void) SyncImageSettings(image_info,*image);
3555           flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
3556           new_image=ShaveImage(*image,&geometry,exception);
3557           break;
3558         }
3559       if (LocaleCompare("shear",argv[0]+1) == 0)
3560         {
3561           /*
3562             Shear image.
3563           */
3564           (void) SyncImageSettings(image_info,*image);
3565           flags=ParseGeometry(argv[1],&geometry_info);
3566           if ((flags & SigmaValue) == 0)
3567             geometry_info.sigma=geometry_info.rho;
3568           new_image=ShearImage(*image,geometry_info.rho,
3569             geometry_info.sigma,exception);
3570           break;
3571         }
3572       if (LocaleCompare("sigmoidal-contrast",argv[0]+1) == 0)
3573         {
3574           /*
3575             Sigmoidal non-linearity contrast control.
3576           */
3577           (void) SyncImageSettings(image_info,*image);
3578           flags=ParseGeometry(argv[1],&geometry_info);
3579           if ((flags & SigmaValue) == 0)
3580             geometry_info.sigma=(double) QuantumRange/2.0;
3581           if ((flags & PercentValue) != 0)
3582             geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3583               100.0;
3584           (void) SigmoidalContrastImage(*image,(*argv[0] == '-') ?
3585             MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
3586             exception);
3587           break;
3588         }
3589       if (LocaleCompare("sketch",argv[0]+1) == 0)
3590         {
3591           /*
3592             Sketch image.
3593           */
3594           (void) SyncImageSettings(image_info,*image);
3595           flags=ParseGeometry(argv[1],&geometry_info);
3596           if ((flags & SigmaValue) == 0)
3597             geometry_info.sigma=1.0;
3598           new_image=SketchImage(*image,geometry_info.rho,
3599             geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3600           break;
3601         }
3602       if (LocaleCompare("solarize",argv[0]+1) == 0)
3603         {
3604           double
3605             threshold;
3606
3607           (void) SyncImageSettings(image_info,*image);
3608           threshold=SiPrefixToDouble(argv[1],QuantumRange);
3609           (void) SolarizeImage(*image,threshold,exception);
3610           break;
3611         }
3612       if (LocaleCompare("sparse-color",argv[0]+1) == 0)
3613         {
3614           SparseColorMethod
3615             method;
3616
3617           char
3618             *arguments;
3619
3620           /*
3621             Sparse Color Interpolated Gradient
3622           */
3623           (void) SyncImageSettings(image_info,*image);
3624           method=(SparseColorMethod) ParseCommandOption(
3625             MagickSparseColorOptions,MagickFalse,argv[1]);
3626           arguments=InterpretImageProperties(image_info,*image,argv[2],
3627             exception);
3628           if (arguments == (char *) NULL)
3629             break;
3630           new_image=SparseColorOption(*image,method,arguments,
3631             argv[0][0] == '+' ? MagickTrue : MagickFalse,exception);
3632           arguments=DestroyString(arguments);
3633           break;
3634         }
3635       if (LocaleCompare("splice",argv[0]+1) == 0)
3636         {
3637           /*
3638             Splice a solid color into the image.
3639           */
3640           (void) SyncImageSettings(image_info,*image);
3641           (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
3642           new_image=SpliceImage(*image,&geometry,exception);
3643           break;
3644         }
3645       if (LocaleCompare("spread",argv[0]+1) == 0)
3646         {
3647           /*
3648             Spread an image.
3649           */
3650           (void) SyncImageSettings(image_info,*image);
3651           (void) ParseGeometry(argv[1],&geometry_info);
3652           new_image=SpreadImage(*image,geometry_info.rho,
3653             interpolate_method,exception);
3654           break;
3655         }
3656       if (LocaleCompare("statistic",argv[0]+1) == 0)
3657         {
3658           StatisticType
3659             type;
3660
3661           (void) SyncImageSettings(image_info,*image);
3662           type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
3663             MagickFalse,argv[1]);
3664           (void) ParseGeometry(argv[2],&geometry_info);
3665           new_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
3666             (size_t) geometry_info.sigma,exception);
3667           break;
3668         }
3669       if (LocaleCompare("stretch",argv[0]+1) == 0)
3670         {
3671           if (*argv[0] == '+')
3672             {
3673               draw_info->stretch=UndefinedStretch;
3674               break;
3675             }
3676           draw_info->stretch=(StretchType) ParseCommandOption(
3677             MagickStretchOptions,MagickFalse,argv[1]);
3678           break;
3679         }
3680       if (LocaleCompare("strip",argv[0]+1) == 0)
3681         {
3682           /*
3683             Strip image of profiles and comments.
3684           */
3685           (void) SyncImageSettings(image_info,*image);
3686           (void) StripImage(*image);
3687           InheritException(exception,&(*image)->exception);
3688           break;
3689         }
3690       if (LocaleCompare("stroke",argv[0]+1) == 0)
3691         {
3692           ExceptionInfo
3693             *sans;
3694
3695           if (*argv[0] == '+')
3696             {
3697               (void) QueryColorCompliance("none",&draw_info->stroke,exception);
3698               if (draw_info->stroke_pattern != (Image *) NULL)
3699                 draw_info->stroke_pattern=DestroyImage(
3700                   draw_info->stroke_pattern);
3701               break;
3702             }
3703           sans=AcquireExceptionInfo();
3704           status=QueryColorCompliance(argv[1],&draw_info->stroke,sans);
3705           sans=DestroyExceptionInfo(sans);
3706           if (status == MagickFalse)
3707             draw_info->stroke_pattern=GetImageCache(image_info,argv[1],
3708               exception);
3709           break;
3710         }
3711       if (LocaleCompare("strokewidth",argv[0]+1) == 0)
3712         {
3713           draw_info->stroke_width=InterpretLocaleValue(argv[1],
3714             (char **) NULL);
3715           break;
3716         }
3717       if (LocaleCompare("style",argv[0]+1) == 0)
3718         {
3719           if (*argv[0] == '+')
3720             {
3721               draw_info->style=UndefinedStyle;
3722               break;
3723             }
3724           draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
3725             MagickFalse,argv[1]);
3726           break;
3727         }
3728       if (LocaleCompare("swirl",argv[0]+1) == 0)
3729         {
3730           /*
3731             Swirl image.
3732           */
3733           (void) SyncImageSettings(image_info,*image);
3734           (void) ParseGeometry(argv[1],&geometry_info);
3735           new_image=SwirlImage(*image,geometry_info.rho,
3736             interpolate_method,exception);
3737           break;
3738         }
3739       break;
3740     }
3741     case 't':
3742     {
3743       if (LocaleCompare("threshold",argv[0]+1) == 0)
3744         {
3745           double
3746             threshold;
3747
3748           /*
3749             Threshold image.
3750           */
3751           (void) SyncImageSettings(image_info,*image);
3752           if (*argv[0] == '+')
3753             threshold=(double) QuantumRange/2;
3754           else
3755             threshold=SiPrefixToDouble(argv[1],QuantumRange);
3756           (void) BilevelImage(*image,threshold);
3757           InheritException(exception,&(*image)->exception);
3758           break;
3759         }
3760       if (LocaleCompare("thumbnail",argv[0]+1) == 0)
3761         {
3762           /*
3763             Thumbnail image.
3764           */
3765           (void) SyncImageSettings(image_info,*image);
3766           (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
3767           new_image=ThumbnailImage(*image,geometry.width,geometry.height,
3768             exception);
3769           break;
3770         }
3771       if (LocaleCompare("tile",argv[0]+1) == 0)
3772         {
3773           if (*argv[0] == '+')
3774             {
3775               if (draw_info->fill_pattern != (Image *) NULL)
3776                 draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
3777               break;
3778             }
3779           draw_info->fill_pattern=GetImageCache(image_info,argv[1],
3780             exception);
3781           break;
3782         }
3783       if (LocaleCompare("tint",argv[0]+1) == 0)
3784         {
3785           /*
3786             Tint the image.
3787           */
3788           (void) SyncImageSettings(image_info,*image);
3789           new_image=TintImage(*image,argv[1],&fill,exception);
3790           break;
3791         }
3792       if (LocaleCompare("transform",argv[0]+1) == 0)
3793         {
3794           /*
3795             Affine transform image.
3796           */
3797           (void) SyncImageSettings(image_info,*image);
3798           new_image=AffineTransformImage(*image,&draw_info->affine,
3799             exception);
3800           break;
3801         }
3802       if (LocaleCompare("transparent",argv[0]+1) == 0)
3803         {
3804           PixelInfo
3805             target;
3806
3807           (void) SyncImageSettings(image_info,*image);
3808           (void) QueryMagickColorCompliance(argv[1],&target,exception);
3809           (void) TransparentPaintImage(*image,&target,(Quantum)
3810             TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue,
3811             &(*image)->exception);
3812           break;
3813         }
3814       if (LocaleCompare("transpose",argv[0]+1) == 0)
3815         {
3816           /*
3817             Transpose image scanlines.
3818           */
3819           (void) SyncImageSettings(image_info,*image);
3820           new_image=TransposeImage(*image,exception);
3821           break;
3822         }
3823       if (LocaleCompare("transverse",argv[0]+1) == 0)
3824         {
3825           /*
3826             Transverse image scanlines.
3827           */
3828           (void) SyncImageSettings(image_info,*image);
3829           new_image=TransverseImage(*image,exception);
3830           break;
3831         }
3832       if (LocaleCompare("treedepth",argv[0]+1) == 0)
3833         {
3834           quantize_info->tree_depth=StringToUnsignedLong(argv[1]);
3835           break;
3836         }
3837       if (LocaleCompare("trim",argv[0]+1) == 0)
3838         {
3839           /*
3840             Trim image.
3841           */
3842           (void) SyncImageSettings(image_info,*image);
3843           new_image=TrimImage(*image,exception);
3844           break;
3845         }
3846       if (LocaleCompare("type",argv[0]+1) == 0)
3847         {
3848           ImageType
3849             type;
3850
3851           (void) SyncImageSettings(image_info,*image);
3852           if (*argv[0] == '+')
3853             type=UndefinedType;
3854           else
3855             type=(ImageType) ParseCommandOption(MagickTypeOptions,MagickFalse,
3856               argv[1]);
3857           (*image)->type=UndefinedType;
3858           (void) SetImageType(*image,type,exception);
3859           break;
3860         }
3861       break;
3862     }
3863     case 'u':
3864     {
3865       if (LocaleCompare("undercolor",argv[0]+1) == 0)
3866         {
3867           (void) QueryColorCompliance(argv[1],&draw_info->undercolor,
3868             exception);
3869           break;
3870         }
3871       if (LocaleCompare("unique",argv[0]+1) == 0)
3872         {
3873           if (*argv[0] == '+')
3874             {
3875               (void) DeleteImageArtifact(*image,"identify:unique-colors");
3876               break;
3877             }
3878           (void) SetImageArtifact(*image,"identify:unique-colors","true");
3879           (void) SetImageArtifact(*image,"verbose","true");
3880           break;
3881         }
3882       if (LocaleCompare("unique-colors",argv[0]+1) == 0)
3883         {
3884           /*
3885             Unique image colors.
3886           */
3887           (void) SyncImageSettings(image_info,*image);
3888           new_image=UniqueImageColors(*image,exception);
3889           break;
3890         }
3891       if (LocaleCompare("unsharp",argv[0]+1) == 0)
3892         {
3893           /*
3894             Unsharp mask image.
3895           */
3896           (void) SyncImageSettings(image_info,*image);
3897           flags=ParseGeometry(argv[1],&geometry_info);
3898           if ((flags & SigmaValue) == 0)
3899             geometry_info.sigma=1.0;
3900           if ((flags & XiValue) == 0)
3901             geometry_info.xi=1.0;
3902           if ((flags & PsiValue) == 0)
3903             geometry_info.psi=0.05;
3904           new_image=UnsharpMaskImage(*image,geometry_info.rho,
3905             geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3906           break;
3907         }
3908       break;
3909     }
3910     case 'v':
3911     {
3912       if (LocaleCompare("verbose",argv[0]+1) == 0)
3913         {
3914           (void) SetImageArtifact(*image,argv[0]+1,
3915             *argv[0] == '+' ? "false" : "true");
3916           break;
3917         }
3918       if (LocaleCompare("vignette",argv[0]+1) == 0)
3919         {
3920           /*
3921             Vignette image.
3922           */
3923           (void) SyncImageSettings(image_info,*image);
3924           flags=ParseGeometry(argv[1],&geometry_info);
3925           if ((flags & SigmaValue) == 0)
3926             geometry_info.sigma=1.0;
3927           if ((flags & XiValue) == 0)
3928             geometry_info.xi=0.1*(*image)->columns;
3929           if ((flags & PsiValue) == 0)
3930             geometry_info.psi=0.1*(*image)->rows;
3931           new_image=VignetteImage(*image,geometry_info.rho,
3932             geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3933             ceil(geometry_info.psi-0.5),exception);
3934           break;
3935         }
3936       if (LocaleCompare("virtual-pixel",argv[0]+1) == 0)
3937         {
3938           if (*argv[0] == '+')
3939             {
3940               (void) SetImageVirtualPixelMethod(*image,
3941                 UndefinedVirtualPixelMethod);
3942               break;
3943             }
3944           (void) SetImageVirtualPixelMethod(*image,(VirtualPixelMethod)
3945             ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
3946             argv[1]));
3947           break;
3948         }
3949       break;
3950     }
3951     case 'w':
3952     {
3953       if (LocaleCompare("wave",argv[0]+1) == 0)
3954         {
3955           /*
3956             Wave image.
3957           */
3958           (void) SyncImageSettings(image_info,*image);
3959           flags=ParseGeometry(argv[1],&geometry_info);
3960           if ((flags & SigmaValue) == 0)
3961             geometry_info.sigma=1.0;
3962           new_image=WaveImage(*image,geometry_info.rho,
3963             geometry_info.sigma,exception);
3964           break;
3965         }
3966       if (LocaleCompare("weight",argv[0]+1) == 0)
3967         {
3968           draw_info->weight=StringToUnsignedLong(argv[1]);
3969           if (LocaleCompare(argv[1],"all") == 0)
3970             draw_info->weight=0;
3971           if (LocaleCompare(argv[1],"bold") == 0)
3972             draw_info->weight=700;
3973           if (LocaleCompare(argv[1],"bolder") == 0)
3974             if (draw_info->weight <= 800)
3975               draw_info->weight+=100;
3976           if (LocaleCompare(argv[1],"lighter") == 0)
3977             if (draw_info->weight >= 100)
3978               draw_info->weight-=100;
3979           if (LocaleCompare(argv[1],"normal") == 0)
3980             draw_info->weight=400;
3981           break;
3982         }
3983       if (LocaleCompare("white-threshold",argv[0]+1) == 0)
3984         {
3985           /*
3986             White threshold image.
3987           */
3988           (void) SyncImageSettings(image_info,*image);
3989           (void) WhiteThresholdImage(*image,argv[1],exception);
3990           InheritException(exception,&(*image)->exception);
3991           break;
3992         }
3993       break;
3994     }
3995     default:
3996       break;
3997   }
3998   /*
3999      Replace current image with any image that was generated
4000   */
4001   if (new_image != (Image *) NULL)
4002     ReplaceImageInListReturnLast(image,new_image);
4003
4004   /*
4005     Free resources.
4006   */
4007   quantize_info=DestroyQuantizeInfo(quantize_info);
4008   draw_info=DestroyDrawInfo(draw_info);
4009   status=(*image)->exception.severity == UndefinedException ? 1 : 0;
4010
4011   return(status);
4012 }
4013 \f
4014 /*
4015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4016 %                                                                             %
4017 %                                                                             %
4018 %                                                                             %
4019 +     S e q u e n c e O p e r a t i o n I m a g e s                           %
4020 %                                                                             %
4021 %                                                                             %
4022 %                                                                             %
4023 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4024 %
4025 %  SequenceOperationImages() applies a single operation that apply to the
4026 %  entire image list (e.g. -append, -layers, -coalesce, etc.).
4027 %
4028 %  The format of the MogrifyImage method is:
4029 %
4030 %    MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
4031 %        const int argc, const char **argv,Image **images,
4032 %        ExceptionInfo *exception)
4033 %
4034 %  A description of each parameter follows:
4035 %
4036 %    o image_info: the image info..
4037 %
4038 %    o argc: Specifies a pointer to an integer describing the number of
4039 %      elements in the argument vector.
4040 %
4041 %    o argv: Specifies a pointer to a text array containing the command line
4042 %      arguments.
4043 %
4044 %    o images: pointer to pointer of the first image in image list.
4045 %
4046 %    o exception: return any errors or warnings in this structure.
4047 %
4048 */
4049 WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
4050   const int argc,const char **argv,Image **images,ExceptionInfo *exception)
4051 {
4052
4053   MagickStatusType
4054     status;
4055
4056   QuantizeInfo
4057     *quantize_info;
4058
4059   assert(image_info != (ImageInfo *) NULL);
4060   assert(image_info->signature == MagickSignature);
4061   assert(images != (Image **) NULL);
4062   assert((*images)->previous == (Image *) NULL);
4063   assert((*images)->signature == MagickSignature);
4064   if ((*images)->debug != MagickFalse)
4065     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
4066       (*images)->filename);
4067
4068   quantize_info=AcquireQuantizeInfo(image_info);
4069   channel=image_info->channel;
4070
4071   status=MagickTrue;
4072
4073   switch (*(argv[0]+1))
4074   {
4075     case 'a':
4076     {
4077       if (LocaleCompare("affinity",argv[0]+1) == 0)
4078         {
4079           (void) SyncImagesSettings(image_info,*images);
4080           if (*argv[0] == '+')
4081             {
4082               (void) RemapImages(quantize_info,*images,(Image *) NULL,
4083                 exception);
4084               break;
4085             }
4086           break;
4087         }
4088       if (LocaleCompare("append",argv[0]+1) == 0)
4089         {
4090           Image
4091             *append_image;
4092
4093           (void) SyncImagesSettings(image_info,*images);
4094           append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue :
4095             MagickFalse,exception);
4096           if (append_image == (Image *) NULL)
4097             {
4098               status=MagickFalse;
4099               break;
4100             }
4101           *images=DestroyImageList(*images);
4102           *images=append_image;
4103           break;
4104         }
4105       if (LocaleCompare("average",argv[0]+1) == 0)
4106         {
4107           Image
4108             *average_image;
4109
4110           /*
4111             Average an image sequence (deprecated).
4112           */
4113           (void) SyncImagesSettings(image_info,*images);
4114           average_image=EvaluateImages(*images,MeanEvaluateOperator,
4115             exception);
4116           if (average_image == (Image *) NULL)
4117             {
4118               status=MagickFalse;
4119               break;
4120             }
4121           *images=DestroyImageList(*images);
4122           *images=average_image;
4123           break;
4124         }
4125       break;
4126     }
4127     case 'c':
4128     {
4129       if (LocaleCompare("channel",argv[0]+1) == 0)
4130         {
4131           ChannelType
4132             channel;
4133
4134           if (*argv[0] == '+')
4135             {
4136               channel=DefaultChannels;
4137               break;
4138             }
4139           channel=(ChannelType) ParseChannelOption(argv[1]);
4140           SetPixelChannelMap(*images,channel);
4141           break;
4142         }
4143       if (LocaleCompare("clut",argv[0]+1) == 0)
4144         {
4145           Image
4146             *clut_image,
4147             *image;
4148
4149           (void) SyncImagesSettings(image_info,*images);
4150           image=RemoveFirstImageFromList(images);
4151           clut_image=RemoveFirstImageFromList(images);
4152           if (clut_image == (Image *) NULL)
4153             {
4154               status=MagickFalse;
4155               break;
4156             }
4157           (void) ClutImageChannel(image,channel,clut_image);
4158           clut_image=DestroyImage(clut_image);
4159           *images=DestroyImageList(*images);
4160           *images=image;
4161           break;
4162         }
4163       if (LocaleCompare("coalesce",argv[0]+1) == 0)
4164         {
4165           Image
4166             *coalesce_image;
4167
4168           (void) SyncImagesSettings(image_info,*images);
4169           coalesce_image=CoalesceImages(*images,exception);
4170           if (coalesce_image == (Image *) NULL)
4171             {
4172               status=MagickFalse;
4173               break;
4174             }
4175           *images=DestroyImageList(*images);
4176           *images=coalesce_image;
4177           break;
4178         }
4179       if (LocaleCompare("combine",argv[0]+1) == 0)
4180         {
4181           Image
4182             *combine_image;
4183
4184           (void) SyncImagesSettings(image_info,*images);
4185           combine_image=CombineImages(*images,exception);
4186           if (combine_image == (Image *) NULL)
4187             {
4188               status=MagickFalse;
4189               break;
4190             }
4191           *images=DestroyImageList(*images);
4192           *images=combine_image;
4193           break;
4194         }
4195       if (LocaleCompare("composite",argv[0]+1) == 0)
4196         {
4197           Image
4198             *mask_image,
4199             *composite_image,
4200             *image;
4201
4202           RectangleInfo
4203             geometry;
4204
4205           (void) SyncImagesSettings(image_info,*images);
4206           image=RemoveFirstImageFromList(images);
4207           composite_image=RemoveFirstImageFromList(images);
4208           if (composite_image == (Image *) NULL)
4209             {
4210               status=MagickFalse;
4211               break;
4212             }
4213           (void) TransformImage(&composite_image,(char *) NULL,
4214             composite_image->geometry);
4215           SetGeometry(composite_image,&geometry);
4216           (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
4217           GravityAdjustGeometry(image->columns,image->rows,image->gravity,
4218             &geometry);
4219           mask_image=RemoveFirstImageFromList(images);
4220           if (mask_image != (Image *) NULL)
4221             {
4222               if ((image->compose == DisplaceCompositeOp) ||
4223                   (image->compose == DistortCompositeOp))
4224                 {
4225                   /*
4226                     Merge Y displacement into X displacement image.
4227                   */
4228                   (void) CompositeImage(composite_image,CopyGreenCompositeOp,
4229                     mask_image,0,0);
4230                   mask_image=DestroyImage(mask_image);
4231                 }
4232               else
4233                 {
4234                   /*
4235                     Set a blending mask for the composition.
4236                     Posible error, what if image->mask already set.
4237                   */
4238                   image->mask=mask_image;
4239                   (void) NegateImage(image->mask,MagickFalse,exception);
4240                 }
4241             }
4242           (void) CompositeImage(image,image->compose,composite_image,
4243             geometry.x,geometry.y);
4244           if (mask_image != (Image *) NULL)
4245             mask_image=image->mask=DestroyImage(image->mask);
4246           composite_image=DestroyImage(composite_image);
4247           InheritException(exception,&image->exception);
4248           *images=DestroyImageList(*images);
4249           *images=image;
4250           break;
4251         }
4252       break;
4253     }
4254     case 'd':
4255     {
4256       if (LocaleCompare("deconstruct",argv[0]+1) == 0)
4257         {
4258           Image
4259             *deconstruct_image;
4260
4261           (void) SyncImagesSettings(image_info,*images);
4262           deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
4263             exception);
4264           if (deconstruct_image == (Image *) NULL)
4265             {
4266               status=MagickFalse;
4267               break;
4268             }
4269           *images=DestroyImageList(*images);
4270           *images=deconstruct_image;
4271           break;
4272         }
4273       if (LocaleCompare("delete",argv[0]+1) == 0)
4274         {
4275           if (*argv[0] == '+')
4276             DeleteImages(images,"-1",exception);
4277           else
4278             DeleteImages(images,argv[1],exception);
4279           break;
4280         }
4281       if (LocaleCompare("dither",argv[0]+1) == 0)
4282         {
4283           if (*argv[0] == '+')
4284             {
4285               quantize_info->dither=MagickFalse;
4286               break;
4287             }
4288           quantize_info->dither=MagickTrue;
4289           quantize_info->dither_method=(DitherMethod) ParseCommandOption(
4290             MagickDitherOptions,MagickFalse,argv[1]);
4291           break;
4292         }
4293       if (LocaleCompare("duplicate",argv[0]+1) == 0)
4294         {
4295           Image
4296             *duplicate_images;
4297
4298           if (*argv[0] == '+')
4299             duplicate_images=DuplicateImages(*images,1,"-1",exception);
4300           else
4301             {
4302               const char
4303                 *p;
4304
4305               size_t
4306                 number_duplicates;
4307
4308               number_duplicates=(size_t) StringToLong(argv[1]);
4309               p=strchr(argv[1],',');
4310               if (p == (const char *) NULL)
4311                 duplicate_images=DuplicateImages(*images,number_duplicates,
4312                   "-1",exception);
4313               else
4314                 duplicate_images=DuplicateImages(*images,number_duplicates,p,
4315                   exception);
4316             }
4317           AppendImageToList(images, duplicate_images);
4318           (void) SyncImagesSettings(image_info,*images);
4319           break;
4320         }
4321       break;
4322     }
4323     case 'e':
4324     {
4325       if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0)
4326         {
4327           Image
4328             *evaluate_image;
4329
4330           MagickEvaluateOperator
4331             op;
4332
4333           (void) SyncImageSettings(image_info,*images);
4334           op=(MagickEvaluateOperator) ParseCommandOption(
4335             MagickEvaluateOptions,MagickFalse,argv[1]);
4336           evaluate_image=EvaluateImages(*images,op,exception);
4337           if (evaluate_image == (Image *) NULL)
4338             {
4339               status=MagickFalse;
4340               break;
4341             }
4342           *images=DestroyImageList(*images);
4343           *images=evaluate_image;
4344           break;
4345         }
4346       break;
4347     }
4348     case 'f':
4349     {
4350       if (LocaleCompare("fft",argv[0]+1) == 0)
4351         {
4352           Image
4353             *fourier_image;
4354
4355           /*
4356             Implements the discrete Fourier transform (DFT).
4357           */
4358           (void) SyncImageSettings(image_info,*images);
4359           fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ?
4360             MagickTrue : MagickFalse,exception);
4361           if (fourier_image == (Image *) NULL)
4362             break;
4363           *images=DestroyImage(*images);
4364           *images=fourier_image;
4365           break;
4366         }
4367       if (LocaleCompare("flatten",argv[0]+1) == 0)
4368         {
4369           Image
4370             *flatten_image;
4371
4372           (void) SyncImagesSettings(image_info,*images);
4373           flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
4374           if (flatten_image == (Image *) NULL)
4375             break;
4376           *images=DestroyImageList(*images);
4377           *images=flatten_image;
4378           break;
4379         }
4380       if (LocaleCompare("fx",argv[0]+1) == 0)
4381         {
4382           Image
4383             *fx_image;
4384
4385           (void) SyncImagesSettings(image_info,*images);
4386           fx_image=FxImage(*images,argv[1],exception);
4387           if (fx_image == (Image *) NULL)
4388             {
4389               status=MagickFalse;
4390               break;
4391             }
4392           *images=DestroyImageList(*images);
4393           *images=fx_image;
4394           break;
4395         }
4396       break;
4397     }
4398     case 'h':
4399     {
4400       if (LocaleCompare("hald-clut",argv[0]+1) == 0)
4401         {
4402           Image
4403             *hald_image,
4404             *image;
4405
4406           (void) SyncImagesSettings(image_info,*images);
4407           image=RemoveFirstImageFromList(images);
4408           hald_image=RemoveFirstImageFromList(images);
4409           if (hald_image == (Image *) NULL)
4410             {
4411               status=MagickFalse;
4412               break;
4413             }
4414           (void) HaldClutImage(image,hald_image,exception);
4415           hald_image=DestroyImage(hald_image);
4416           if (*images != (Image *) NULL)
4417             *images=DestroyImageList(*images);
4418           *images=image;
4419           break;
4420         }
4421       break;
4422     }
4423     case 'i':
4424     {
4425       if (LocaleCompare("ift",argv[0]+1) == 0)
4426         {
4427           Image
4428             *fourier_image,
4429             *magnitude_image,
4430             *phase_image;
4431
4432           /*
4433             Implements the inverse fourier discrete Fourier transform (DFT).
4434           */
4435           (void) SyncImagesSettings(image_info,*images);
4436           magnitude_image=RemoveFirstImageFromList(images);
4437           phase_image=RemoveFirstImageFromList(images);
4438           if (phase_image == (Image *) NULL)
4439             {
4440               status=MagickFalse;
4441               break;
4442             }
4443           fourier_image=InverseFourierTransformImage(magnitude_image,
4444             phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception);
4445           if (fourier_image == (Image *) NULL)
4446             break;
4447           if (*images != (Image *) NULL)
4448             *images=DestroyImage(*images);
4449           *images=fourier_image;
4450           break;
4451         }
4452       if (LocaleCompare("insert",argv[0]+1) == 0)
4453         {
4454           Image
4455             *p,
4456             *q;
4457
4458           index=0;
4459           if (*argv[0] != '+')
4460             index=(ssize_t) StringToLong(argv[1]);
4461           p=RemoveLastImageFromList(images);
4462           if (p == (Image *) NULL)
4463             {
4464               (void) ThrowMagickException(exception,GetMagickModule(),
4465                 OptionError,"NoSuchImage","`%s'",argv[1]);
4466               status=MagickFalse;
4467               break;
4468             }
4469           q=p;
4470           if (index == 0)
4471             PrependImageToList(images,q);
4472           else
4473             if (index == (ssize_t) GetImageListLength(*images))
4474               AppendImageToList(images,q);
4475             else
4476               {
4477                  q=GetImageFromList(*images,index-1);
4478                  if (q == (Image *) NULL)
4479                    {
4480                      (void) ThrowMagickException(exception,GetMagickModule(),
4481                        OptionError,"NoSuchImage","`%s'",argv[1]);
4482                      status=MagickFalse;
4483                      break;
4484                    }
4485                 InsertImageInList(&q,p);
4486               }
4487           *images=GetFirstImageInList(q);
4488           break;
4489         }
4490       if (LocaleCompare("interpolate",argv[0]+1) == 0)
4491         {
4492           interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
4493             MagickInterpolateOptions,MagickFalse,argv[1]);
4494           break;
4495         }
4496       break;
4497     }
4498     case 'l':
4499     {
4500       if (LocaleCompare("layers",argv[0]+1) == 0)
4501         {
4502           Image
4503             *layers;
4504
4505           ImageLayerMethod
4506             method;
4507
4508           (void) SyncImagesSettings(image_info,*images);
4509           layers=(Image *) NULL;
4510           method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
4511             MagickFalse,argv[1]);
4512           switch (method)
4513           {
4514             case CoalesceLayer:
4515             {
4516               layers=CoalesceImages(*images,exception);
4517               break;
4518             }
4519             case CompareAnyLayer:
4520             case CompareClearLayer:
4521             case CompareOverlayLayer:
4522             default:
4523             {
4524               layers=CompareImagesLayers(*images,method,exception);
4525               break;
4526             }
4527             case MergeLayer:
4528             case FlattenLayer:
4529             case MosaicLayer:
4530             case TrimBoundsLayer:
4531             {
4532               layers=MergeImageLayers(*images,method,exception);
4533               break;
4534             }
4535             case DisposeLayer:
4536             {
4537               layers=DisposeImages(*images,exception);
4538               break;
4539             }
4540             case OptimizeImageLayer:
4541             {
4542               layers=OptimizeImageLayers(*images,exception);
4543               break;
4544             }
4545             case OptimizePlusLayer:
4546             {
4547               layers=OptimizePlusImageLayers(*images,exception);
4548               break;
4549             }
4550             case OptimizeTransLayer:
4551             {
4552               OptimizeImageTransparency(*images,exception);
4553               break;
4554             }
4555             case RemoveDupsLayer:
4556             {
4557               RemoveDuplicateLayers(images,exception);
4558               break;
4559             }
4560             case RemoveZeroLayer:
4561             {
4562               RemoveZeroDelayLayers(images,exception);
4563               break;
4564             }
4565             case OptimizeLayer:
4566             {
4567               /*
4568                 General Purpose, GIF Animation Optimizer.
4569               */
4570               layers=CoalesceImages(*images,exception);
4571               if (layers == (Image *) NULL)
4572                 {
4573                   status=MagickFalse;
4574                   break;
4575                 }
4576               *images=DestroyImageList(*images);
4577               *images=layers;
4578               layers=OptimizeImageLayers(*images,exception);
4579               if (layers == (Image *) NULL)
4580                 {
4581                   status=MagickFalse;
4582                   break;
4583                 }
4584               *images=DestroyImageList(*images);
4585               *images=layers;
4586               layers=(Image *) NULL;
4587               OptimizeImageTransparency(*images,exception);
4588               (void) RemapImages(quantize_info,*images,(Image *) NULL,
4589                 exception);
4590               break;
4591             }
4592             case CompositeLayer:
4593             {
4594               CompositeOperator
4595                 compose;
4596
4597               Image
4598                 *source;
4599
4600               RectangleInfo
4601                 geometry;
4602
4603               /*
4604                 Split image sequence at the first 'NULL:' image.
4605               */
4606               source=(*images);
4607               while (source != (Image *) NULL)
4608               {
4609                 source=GetNextImageInList(source);
4610                 if ((source != (Image *) NULL) &&
4611                     (LocaleCompare(source->magick,"NULL") == 0))
4612                   break;
4613               }
4614               if (source != (Image *) NULL)
4615                 {
4616                   if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4617                       (GetNextImageInList(source) == (Image *) NULL))
4618                     source=(Image *) NULL;
4619                   else
4620                     {
4621                       /*
4622                         Separate the two lists, junk the null: image.
4623                       */
4624                       source=SplitImageList(source->previous);
4625                       DeleteImageFromList(&source);
4626                     }
4627                 }
4628               if (source == (Image *) NULL)
4629                 {
4630                   (void) ThrowMagickException(exception,GetMagickModule(),
4631                     OptionError,"MissingNullSeparator","layers Composite");
4632                   status=MagickFalse;
4633                   break;
4634                 }
4635               /*
4636                 Adjust offset with gravity and virtual canvas.
4637               */
4638               SetGeometry(*images,&geometry);
4639               (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
4640               geometry.width=source->page.width != 0 ?
4641                 source->page.width : source->columns;
4642               geometry.height=source->page.height != 0 ?
4643                source->page.height : source->rows;
4644               GravityAdjustGeometry((*images)->page.width != 0 ?
4645                 (*images)->page.width : (*images)->columns,
4646                 (*images)->page.height != 0 ? (*images)->page.height :
4647                 (*images)->rows,(*images)->gravity,&geometry);
4648               compose=OverCompositeOp;
4649               argv[0]=GetImageOption(image_info,"compose");
4650               if (argv[0] != (const char *) NULL)
4651                 compose=(CompositeOperator) ParseCommandOption(
4652                   MagickComposeOptions,MagickFalse,argv[0]);
4653               CompositeLayers(*images,compose,source,geometry.x,geometry.y,
4654                 exception);
4655               source=DestroyImageList(source);
4656               break;
4657             }
4658           }
4659           if (layers == (Image *) NULL)
4660             break;
4661           InheritException(exception,&layers->exception);
4662           *images=DestroyImageList(*images);
4663           *images=layers;
4664           break;
4665         }
4666       break;
4667     }
4668     case 'm':
4669     {
4670       if (LocaleCompare("map",argv[0]+1) == 0)
4671         {
4672           (void) SyncImagesSettings(image_info,*images);
4673           if (*argv[0] == '+')
4674             {
4675               (void) RemapImages(quantize_info,*images,(Image *) NULL,
4676                 exception);
4677               break;
4678             }
4679           break;
4680         }
4681       if (LocaleCompare("maximum",argv[0]+1) == 0)
4682         {
4683           Image
4684             *maximum_image;
4685
4686           /*
4687             Maximum image sequence (deprecated).
4688           */
4689           (void) SyncImagesSettings(image_info,*images);
4690           maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
4691           if (maximum_image == (Image *) NULL)
4692             {
4693               status=MagickFalse;
4694               break;
4695             }
4696           *images=DestroyImageList(*images);
4697           *images=maximum_image;
4698           break;
4699         }
4700       if (LocaleCompare("minimum",argv[0]+1) == 0)
4701         {
4702           Image
4703             *minimum_image;
4704
4705           /*
4706             Minimum image sequence (deprecated).
4707           */
4708           (void) SyncImagesSettings(image_info,*images);
4709           minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
4710           if (minimum_image == (Image *) NULL)
4711             {
4712               status=MagickFalse;
4713               break;
4714             }
4715           *images=DestroyImageList(*images);
4716           *images=minimum_image;
4717           break;
4718         }
4719       if (LocaleCompare("morph",argv[0]+1) == 0)
4720         {
4721           Image
4722             *morph_image;
4723
4724           (void) SyncImagesSettings(image_info,*images);
4725           morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]),
4726             exception);
4727           if (morph_image == (Image *) NULL)
4728             {
4729               status=MagickFalse;
4730               break;
4731             }
4732           *images=DestroyImageList(*images);
4733           *images=morph_image;
4734           break;
4735         }
4736       if (LocaleCompare("mosaic",argv[0]+1) == 0)
4737         {
4738           Image
4739             *mosaic_image;
4740
4741           (void) SyncImagesSettings(image_info,*images);
4742           mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
4743           if (mosaic_image == (Image *) NULL)
4744             {
4745               status=MagickFalse;
4746               break;
4747             }
4748           *images=DestroyImageList(*images);
4749           *images=mosaic_image;
4750           break;
4751         }
4752       break;
4753     }
4754     case 'p':
4755     {
4756       if (LocaleCompare("print",argv[0]+1) == 0)
4757         {
4758           char
4759             *string;
4760
4761           (void) SyncImagesSettings(image_info,*images);
4762           string=InterpretImageProperties(image_info,*images,argv[1],
4763             exception);
4764           if (string == (char *) NULL)
4765             break;
4766           (void) FormatLocaleFile(stdout,"%s",string);
4767           string=DestroyString(string);
4768         }
4769       if (LocaleCompare("process",argv[0]+1) == 0)
4770         {
4771           char
4772             **arguments;
4773
4774           int
4775             j,
4776             number_arguments;
4777
4778           (void) SyncImagesSettings(image_info,*images);
4779           arguments=StringToArgv(argv[1],&number_arguments);
4780           if (arguments == (char **) NULL)
4781             break;
4782           if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
4783             {
4784               char
4785                 breaker,
4786                 quote,
4787                 *token;
4788
4789               const char
4790                 *arguments;
4791
4792               int
4793                 next,
4794                 status;
4795
4796               size_t
4797                 length;
4798
4799               TokenInfo
4800                 *token_info;
4801
4802               /*
4803                 Support old style syntax, filter="-option arg".
4804               */
4805               length=strlen(argv[1]);
4806               token=(char *) NULL;
4807               if (~length >= (MaxTextExtent-1))
4808                 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4809                   sizeof(*token));
4810               if (token == (char *) NULL)
4811                 break;
4812               next=0;
4813               arguments=argv[1];
4814               token_info=AcquireTokenInfo();
4815               status=Tokenizer(token_info,0,token,length,arguments,"","=",
4816                 "\"",'\0',&breaker,&next,&quote);
4817               token_info=DestroyTokenInfo(token_info);
4818               if (status == 0)
4819                 {
4820                   const char
4821                     *argv;
4822
4823                   argv=(&(arguments[next]));
4824                   (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
4825                     exception);
4826                 }
4827               token=DestroyString(token);
4828               break;
4829             }
4830           (void) SubstituteString(&arguments[1],"-","");
4831           (void) InvokeDynamicImageFilter(arguments[1],&(*images),
4832             number_arguments-2,(const char **) arguments+2,exception);
4833           for (j=0; j < number_arguments; j++)
4834             arguments[j]=DestroyString(arguments[j]);
4835           arguments=(char **) RelinquishMagickMemory(arguments);
4836           break;
4837         }
4838       break;
4839     }
4840     case 'r':
4841     {
4842       if (LocaleCompare("reverse",argv[0]+1) == 0)
4843         {
4844           ReverseImageList(images);
4845           InheritException(exception,&(*images)->exception);
4846           break;
4847         }
4848       break;
4849     }
4850     case 's':
4851     {
4852       if (LocaleCompare("smush",argv[0]+1) == 0)
4853         {
4854           Image
4855             *smush_image;
4856
4857           ssize_t
4858             offset;
4859
4860           (void) SyncImagesSettings(image_info,*images);
4861           offset=(ssize_t) StringToLong(argv[1]);
4862           smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue :
4863             MagickFalse,offset,exception);
4864           if (smush_image == (Image *) NULL)
4865             {
4866               status=MagickFalse;
4867               break;
4868             }
4869           *images=DestroyImageList(*images);
4870           *images=smush_image;
4871           break;
4872         }
4873       if (LocaleCompare("swap",argv[0]+1) == 0)
4874         {
4875           Image
4876             *p,
4877             *q,
4878             *swap;
4879
4880           ssize_t
4881             swap_index;
4882
4883           index=(-1);
4884           swap_index=(-2);
4885           if (*argv[0] != '+')
4886             {
4887               GeometryInfo
4888                 geometry_info;
4889
4890               MagickStatusType
4891                 flags;
4892
4893               swap_index=(-1);
4894               flags=ParseGeometry(argv[1],&geometry_info);
4895               index=(ssize_t) geometry_info.rho;
4896               if ((flags & SigmaValue) != 0)
4897                 swap_index=(ssize_t) geometry_info.sigma;
4898             }
4899           p=GetImageFromList(*images,index);
4900           q=GetImageFromList(*images,swap_index);
4901           if ((p == (Image *) NULL) || (q == (Image *) NULL))
4902             {
4903               (void) ThrowMagickException(exception,GetMagickModule(),
4904                 OptionError,"NoSuchImage","`%s'",(*images)->filename);
4905               status=MagickFalse;
4906               break;
4907             }
4908           if (p == q)
4909             break;
4910           swap=CloneImage(p,0,0,MagickTrue,exception);
4911           ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
4912           ReplaceImageInList(&q,swap);
4913           *images=GetFirstImageInList(q);
4914           break;
4915         }
4916       break;
4917     }
4918     case 'w':
4919     {
4920       if (LocaleCompare("write",argv[0]+1) == 0)
4921         {
4922           char
4923             key[MaxTextExtent];
4924
4925           Image
4926             *write_images;
4927
4928           ImageInfo
4929             *write_info;
4930
4931           (void) SyncImagesSettings(image_info,*images);
4932           (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]);
4933           (void) DeleteImageRegistry(key);
4934           write_images=(*images);
4935           if (*argv[0] == '+')
4936             write_images=CloneImageList(*images,exception);
4937           write_info=CloneImageInfo(image_info);
4938           status&=WriteImages(write_info,write_images,argv[1],exception);
4939           write_info=DestroyImageInfo(write_info);
4940           if (*argv[0] == '+')
4941             write_images=DestroyImageList(write_images);
4942           break;
4943         }
4944       break;
4945     }
4946     default:
4947       break;
4948   }
4949   quantize_info=DestroyQuantizeInfo(quantize_info);
4950
4951   return(status != 0 ? MagickTrue : MagickFalse);
4952 }
4953 #endif