mogrify.c revision 14154224e937198c540f38d146528c0cdc45d24d
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%              M   M   OOO   GGGGG  RRRR   IIIII  FFFFF  Y   Y                %
7%              MM MM  O   O  G      R   R    I    F       Y Y                 %
8%              M M M  O   O  G GGG  RRRR     I    FFF      Y                  %
9%              M   M  O   O  G   G  R R      I    F        Y                  %
10%              M   M   OOO   GGGG   R  R   IIIII  F        Y                  %
11%                                                                             %
12%                                                                             %
13%                         MagickWand Module Methods                           %
14%                                                                             %
15%                              Software Design                                %
16%                                John Cristy                                  %
17%                                March 2000                                   %
18%                                                                             %
19%                                                                             %
20%  Copyright 1999-2012 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%  Use the mogrify program to resize an image, blur, crop, despeckle, dither,
37%  draw on, flip, join, re-sample, and much more. This tool is similiar to
38%  convert except that the original image file is overwritten (unless you
39%  change the file suffix with the -format option) with any changes you
40%  request.
41%
42*/
43
44/*
45  Include declarations.
46*/
47#include "MagickWand/studio.h"
48#include "MagickWand/MagickWand.h"
49#include "MagickWand/mogrify-private.h"
50#undef DegreesToRadians
51#undef RadiansToDegrees
52#include "MagickCore/image-private.h"
53#include "MagickCore/monitor-private.h"
54#include "MagickCore/string-private.h"
55#include "MagickCore/thread-private.h"
56#include "MagickCore/utility-private.h"
57
58/*
59 Constant declaration.
60*/
61static const char
62  MogrifyBackgroundColor[] = "#ffffff",  /* white */
63  MogrifyBorderColor[] = "#dfdfdf",  /* gray */
64  MogrifyMatteColor[] = "#bdbdbd";  /* gray */
65
66/*
67  Define declarations.
68*/
69#define UndefinedCompressionQuality  0UL
70
71/*
72%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73%                                                                             %
74%                                                                             %
75%                                                                             %
76%     M a g i c k C o m m a n d G e n e s i s                                 %
77%                                                                             %
78%                                                                             %
79%                                                                             %
80%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81%
82%  MagickCommandGenesis() applies image processing options to an image as
83%  prescribed by command line options.
84%
85%  The format of the MagickCommandGenesis method is:
86%
87%      MagickBooleanType MagickCommandGenesis(ImageInfo *image_info,
88%        MagickCommand command,int argc,char **argv,char **metadata,
89%        ExceptionInfo *exception)
90%
91%  A description of each parameter follows:
92%
93%    o image_info: the image info.
94%
95%    o command: Choose from ConvertImageCommand, IdentifyImageCommand,
96%      MogrifyImageCommand, CompositeImageCommand, CompareImagesCommand,
97%      ConjureImageCommand, StreamImageCommand, ImportImageCommand,
98%      DisplayImageCommand, or AnimateImageCommand.
99%
100%    o argc: Specifies a pointer to an integer describing the number of
101%      elements in the argument vector.
102%
103%    o argv: Specifies a pointer to a text array containing the command line
104%      arguments.
105%
106%    o metadata: any metadata is returned here.
107%
108%    o exception: return any errors or warnings in this structure.
109%
110*/
111WandExport MagickBooleanType MagickCommandGenesis(ImageInfo *image_info,
112  MagickCommand command,int argc,char **argv,char **metadata,
113  ExceptionInfo *exception)
114{
115  char
116    *option;
117
118  double
119    duration,
120    serial;
121
122  MagickBooleanType
123    concurrent,
124    regard_warnings,
125    status;
126
127  register ssize_t
128    i;
129
130  size_t
131    iterations,
132    number_threads;
133
134  ssize_t
135    n;
136
137  (void) setlocale(LC_ALL,"");
138  (void) setlocale(LC_NUMERIC,"C");
139  concurrent=MagickFalse;
140  duration=(-1.0);
141  iterations=1;
142  status=MagickFalse;
143  regard_warnings=MagickFalse;
144  for (i=1; i < (ssize_t) (argc-1); i++)
145  {
146    option=argv[i];
147    if ((strlen(option) == 1) || ((*option != '-') && (*option != '+')))
148      continue;
149    if (LocaleCompare("-bench",option) == 0)
150      iterations=StringToUnsignedLong(argv[++i]);
151    if (LocaleCompare("-concurrent",option) == 0)
152      concurrent=MagickTrue;
153    if (LocaleCompare("-debug",option) == 0)
154      (void) SetLogEventMask(argv[++i]);
155    if (LocaleCompare("-duration",option) == 0)
156      duration=StringToDouble(argv[++i],(char **) NULL);
157    if (LocaleCompare("-regard-warnings",option) == 0)
158      regard_warnings=MagickTrue;
159  }
160  if (iterations == 1)
161    {
162      status=command(image_info,argc,argv,metadata,exception);
163      if (exception->severity != UndefinedException)
164        {
165          if ((exception->severity > ErrorException) ||
166              (regard_warnings != MagickFalse))
167            status=MagickTrue;
168          CatchException(exception);
169        }
170        if ((metadata != (char **) NULL) && (*metadata != (char *) NULL))
171          {
172            (void) fputs(*metadata,stdout);
173            (void) fputc('\n',stdout);
174            *metadata=DestroyString(*metadata);
175          }
176      return(status);
177    }
178  number_threads=GetOpenMPMaximumThreads();
179  serial=0.0;
180  for (n=1; n <= (ssize_t) number_threads; n++)
181  {
182    double
183      e,
184      parallel,
185      user_time;
186
187    TimerInfo
188      *timer;
189
190    (void) SetMagickResourceLimit(ThreadResource,(MagickSizeType) n);
191    timer=AcquireTimerInfo();
192    if (concurrent == MagickFalse)
193      {
194        for (i=0; i < (ssize_t) iterations; i++)
195        {
196          if (status != MagickFalse)
197            continue;
198          if (duration > 0)
199            {
200              if (GetElapsedTime(timer) > duration)
201                continue;
202              (void) ContinueTimer(timer);
203            }
204          status=command(image_info,argc,argv,metadata,exception);
205          if (exception->severity != UndefinedException)
206            {
207              if ((exception->severity > ErrorException) ||
208                  (regard_warnings != MagickFalse))
209                status=MagickTrue;
210              CatchException(exception);
211            }
212          if ((metadata != (char **) NULL) && (*metadata != (char *) NULL))
213            {
214              (void) fputs(*metadata,stdout);
215              (void) fputc('\n',stdout);
216              *metadata=DestroyString(*metadata);
217            }
218        }
219      }
220    else
221      {
222        SetOpenMPNested(1);
223#if defined(MAGICKCORE_OPENMP_SUPPORT)
224        # pragma omp parallel for shared(status)
225#endif
226        for (i=0; i < (ssize_t) iterations; i++)
227        {
228          if (status != MagickFalse)
229            continue;
230          if (duration > 0)
231            {
232              if (GetElapsedTime(timer) > duration)
233                continue;
234              (void) ContinueTimer(timer);
235            }
236          status=command(image_info,argc,argv,metadata,exception);
237#if defined(MAGICKCORE_OPENMP_SUPPORT)
238           # pragma omp critical (MagickCore_CommandGenesis)
239#endif
240          {
241            if (exception->severity != UndefinedException)
242              {
243                if ((exception->severity > ErrorException) ||
244                    (regard_warnings != MagickFalse))
245                  status=MagickTrue;
246                CatchException(exception);
247              }
248            if ((metadata != (char **) NULL) && (*metadata != (char *) NULL))
249              {
250                (void) fputs(*metadata,stdout);
251                (void) fputc('\n',stdout);
252                *metadata=DestroyString(*metadata);
253              }
254          }
255        }
256      }
257    user_time=GetUserTime(timer);
258    parallel=GetElapsedTime(timer);
259    e=1.0;
260    if (n == 1)
261      serial=parallel;
262    else
263      e=((1.0/(1.0/((serial/(serial+parallel))+(1.0-(serial/(serial+parallel)))/
264        (double) n)))-(1.0/(double) n))/(1.0-1.0/(double) n);
265    (void) FormatLocaleFile(stderr,
266      "Performance[%.20g]: %.20gi %0.3fips %0.3fe %0.3fu %lu:%02lu.%03lu\n",
267      (double) n,(double) iterations,(double) iterations/parallel,e,
268      user_time,(unsigned long) (parallel/60.0),(unsigned long)
269      floor(fmod(parallel,60.0)),(unsigned long)
270      (1000.0*(parallel-floor(parallel))+0.5));
271    timer=DestroyTimerInfo(timer);
272  }
273  return(status);
274}
275
276/*
277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278%                                                                             %
279%                                                                             %
280%                                                                             %
281+     M o g r i f y I m a g e                                                 %
282%                                                                             %
283%                                                                             %
284%                                                                             %
285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286%
287%  MogrifyImage() applies simple single image processing options to a single
288%  image that may be part of a large list, but also handles any 'region'
289%  image handling.
290%
291%  The image in the list may be modified in three different ways...
292%
293%    * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
294%    * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
295%    * replace by a list of images (only the -separate option!)
296%
297%  In each case the result is returned into the list, and a pointer to the
298%  modified image (last image added if replaced by a list of images) is
299%  returned.
300%
301%  ASIDE: The -crop is present but restricted to non-tile single image crops
302%
303%  This means if all the images are being processed (such as by
304%  MogrifyImages(), next image to be processed will be as per the pointer
305%  (*image)->next.  Also the image list may grow as a result of some specific
306%  operations but as images are never merged or deleted, it will never shrink
307%  in length.  Typically the list will remain the same length.
308%
309%  WARNING: As the image pointed to may be replaced, the first image in the
310%  list may also change.  GetFirstImageInList() should be used by caller if
311%  they wish return the Image pointer to the first image in list.
312%
313%
314%  The format of the MogrifyImage method is:
315%
316%      MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
317%        const char **argv,Image **image)
318%
319%  A description of each parameter follows:
320%
321%    o image_info: the image info..
322%
323%    o argc: Specifies a pointer to an integer describing the number of
324%      elements in the argument vector.
325%
326%    o argv: Specifies a pointer to a text array containing the command line
327%      arguments.
328%
329%    o image: the image.
330%
331%    o exception: return any errors or warnings in this structure.
332%
333*/
334
335static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
336  ExceptionInfo *exception)
337{
338  char
339    key[MaxTextExtent];
340
341  ExceptionInfo
342    *sans_exception;
343
344  Image
345    *image;
346
347  ImageInfo
348    *read_info;
349
350  /*
351    Read an image into a image cache (for repeated usage) if not already in
352    cache.  Then return the image that is in the cache.
353  */
354  (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
355  sans_exception=AcquireExceptionInfo();
356  image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
357  sans_exception=DestroyExceptionInfo(sans_exception);
358  if (image != (Image *) NULL)
359    return(image);
360  read_info=CloneImageInfo(image_info);
361  (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
362  image=ReadImage(read_info,exception);
363  read_info=DestroyImageInfo(read_info);
364  if (image != (Image *) NULL)
365    (void) SetImageRegistry(ImageRegistryType,key,image,exception);
366  return(image);
367}
368
369static MagickBooleanType IsPathWritable(const char *path)
370{
371  if (IsPathAccessible(path) == MagickFalse)
372    return(MagickFalse);
373  if (access_utf8(path,W_OK) != 0)
374    return(MagickFalse);
375  return(MagickTrue);
376}
377
378static inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
379{
380  if (x > y)
381    return(x);
382  return(y);
383}
384
385static MagickBooleanType MonitorProgress(const char *text,
386  const MagickOffsetType offset,const MagickSizeType extent,
387  void *wand_unused(client_data))
388{
389  char
390    message[MaxTextExtent],
391    tag[MaxTextExtent];
392
393  const char
394    *locale_message;
395
396  register char
397    *p;
398
399  if (extent < 2)
400    return(MagickTrue);
401  (void) CopyMagickMemory(tag,text,MaxTextExtent);
402  p=strrchr(tag,'/');
403  if (p != (char *) NULL)
404    *p='\0';
405  (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
406  locale_message=GetLocaleMessage(message);
407  if (locale_message == message)
408    locale_message=tag;
409  if (p == (char *) NULL)
410    (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
411      locale_message,(long) offset,(unsigned long) extent,(long)
412      (100L*offset/(extent-1)));
413  else
414    (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
415      locale_message,p+1,(long) offset,(unsigned long) extent,(long)
416      (100L*offset/(extent-1)));
417  if (offset == (MagickOffsetType) (extent-1))
418    (void) FormatLocaleFile(stderr,"\n");
419  (void) fflush(stderr);
420  return(MagickTrue);
421}
422
423static Image *SparseColorOption(const Image *image,
424  const SparseColorMethod method,const char *arguments,
425  const MagickBooleanType color_from_image,ExceptionInfo *exception)
426{
427  char
428    token[MaxTextExtent];
429
430  const char
431    *p;
432
433  double
434    *sparse_arguments;
435
436  Image
437    *sparse_image;
438
439  PixelInfo
440    color;
441
442  MagickBooleanType
443    error;
444
445  register size_t
446    x;
447
448  size_t
449    number_arguments,
450    number_colors;
451
452  /*
453    SparseColorOption() parses the complex -sparse-color argument into an an
454    array of floating point values then calls SparseColorImage().  Argument is
455    a complex mix of floating-point pixel coodinates, and color specifications
456    (or direct floating point numbers).  The number of floats needed to
457    represent a color varies depending on the current channel setting.
458  */
459  assert(image != (Image *) NULL);
460  assert(image->signature == MagickSignature);
461  if (image->debug != MagickFalse)
462    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
463  assert(exception != (ExceptionInfo *) NULL);
464  assert(exception->signature == MagickSignature);
465  /*
466    Limit channels according to image - and add up number of color channel.
467  */
468  number_colors=0;
469  if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
470    number_colors++;
471  if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
472    number_colors++;
473  if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
474    number_colors++;
475  if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
476      (image->colorspace == CMYKColorspace))
477    number_colors++;
478  if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
479      (image->matte != MagickFalse))
480    number_colors++;
481
482  /*
483    Read string, to determine number of arguments needed,
484  */
485  p=arguments;
486  x=0;
487  while( *p != '\0' )
488  {
489    GetMagickToken(p,&p,token);
490    if ( token[0] == ',' ) continue;
491    if ( isalpha((int) token[0]) || token[0] == '#' ) {
492      if ( color_from_image ) {
493        (void) ThrowMagickException(exception,GetMagickModule(),
494            OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
495            "Color arg given, when colors are coming from image");
496        return( (Image *)NULL);
497      }
498      x += number_colors;  /* color argument */
499    }
500    else {
501      x++;   /* floating point argument */
502    }
503  }
504  error=MagickTrue;
505  if ( color_from_image ) {
506    /* just the control points are being given */
507    error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse;
508    number_arguments=(x/2)*(2+number_colors);
509  }
510  else {
511    /* control points and color values */
512    error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
513    number_arguments=x;
514  }
515  if ( error ) {
516    (void) ThrowMagickException(exception,GetMagickModule(),
517               OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
518               "Invalid number of Arguments");
519    return( (Image *)NULL);
520  }
521
522  /* Allocate and fill in the floating point arguments */
523  sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
524    sizeof(*sparse_arguments));
525  if (sparse_arguments == (double *) NULL) {
526    (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
527      "MemoryAllocationFailed","%s","SparseColorOption");
528    return( (Image *)NULL);
529  }
530  (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
531    sizeof(*sparse_arguments));
532  p=arguments;
533  x=0;
534  while( *p != '\0' && x < number_arguments ) {
535    /* X coordinate */
536    token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
537    if ( token[0] == '\0' ) break;
538    if ( isalpha((int) token[0]) || token[0] == '#' ) {
539      (void) ThrowMagickException(exception,GetMagickModule(),
540            OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
541            "Color found, instead of X-coord");
542      error = MagickTrue;
543      break;
544    }
545    sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
546    /* Y coordinate */
547    token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
548    if ( token[0] == '\0' ) break;
549    if ( isalpha((int) token[0]) || token[0] == '#' ) {
550      (void) ThrowMagickException(exception,GetMagickModule(),
551            OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
552            "Color found, instead of Y-coord");
553      error = MagickTrue;
554      break;
555    }
556    sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
557    /* color values for this control point */
558#if 0
559    if ( (color_from_image ) {
560      /* get color from image */
561      /* HOW??? */
562    }
563    else
564#endif
565    {
566      /* color name or function given in string argument */
567      token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
568      if ( token[0] == '\0' ) break;
569      if ( isalpha((int) token[0]) || token[0] == '#' ) {
570        /* Color string given */
571        (void) QueryColorCompliance(token,AllCompliance,&color,exception);
572        if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
573          sparse_arguments[x++] = QuantumScale*color.red;
574        if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
575          sparse_arguments[x++] = QuantumScale*color.green;
576        if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
577          sparse_arguments[x++] = QuantumScale*color.blue;
578        if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
579            (image->colorspace == CMYKColorspace))
580          sparse_arguments[x++] = QuantumScale*color.black;
581        if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
582            (image->matte != MagickFalse))
583          sparse_arguments[x++] = QuantumScale*color.alpha;
584      }
585      else {
586        /* Colors given as a set of floating point values - experimental */
587        /* NB: token contains the first floating point value to use! */
588        if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
589          {
590          while ( token[0] == ',' ) GetMagickToken(p,&p,token);
591          if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
592            break;
593          sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
594          token[0] = ','; /* used this token - get another */
595        }
596        if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
597          {
598          while ( token[0] == ',' ) GetMagickToken(p,&p,token);
599          if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
600            break;
601          sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
602          token[0] = ','; /* used this token - get another */
603        }
604        if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
605          {
606          while ( token[0] == ',' ) GetMagickToken(p,&p,token);
607          if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
608            break;
609          sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
610          token[0] = ','; /* used this token - get another */
611        }
612        if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
613            (image->colorspace == CMYKColorspace))
614          {
615          while ( token[0] == ',' ) GetMagickToken(p,&p,token);
616          if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
617            break;
618          sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
619          token[0] = ','; /* used this token - get another */
620        }
621        if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
622            (image->matte != MagickFalse))
623          {
624          while ( token[0] == ',' ) GetMagickToken(p,&p,token);
625          if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
626            break;
627          sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
628          token[0] = ','; /* used this token - get another */
629        }
630      }
631    }
632  }
633  if ( number_arguments != x && !error ) {
634    (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
635      "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
636    sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
637    return( (Image *)NULL);
638  }
639  if ( error )
640    return( (Image *)NULL);
641
642  /* Call the Interpolation function with the parsed arguments */
643  sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
644    exception);
645  sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
646  return( sparse_image );
647}
648
649WandExport MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
650  const char **argv,Image **image,ExceptionInfo *exception)
651{
652  CompositeOperator
653    compose;
654
655  const char
656    *format,
657    *option;
658
659  double
660    attenuate;
661
662  DrawInfo
663    *draw_info;
664
665  GeometryInfo
666    geometry_info;
667
668  Image
669    *region_image;
670
671  ImageInfo
672    *mogrify_info;
673
674  MagickStatusType
675    status;
676
677  PixelInfo
678    fill;
679
680  MagickStatusType
681    flags;
682
683  PixelInterpolateMethod
684    interpolate_method;
685
686  QuantizeInfo
687    *quantize_info;
688
689  RectangleInfo
690    geometry,
691    region_geometry;
692
693  register ssize_t
694    i;
695
696  /*
697    Initialize method variables.
698  */
699  assert(image_info != (const ImageInfo *) NULL);
700  assert(image_info->signature == MagickSignature);
701  assert(image != (Image **) NULL);
702  assert((*image)->signature == MagickSignature);
703  if ((*image)->debug != MagickFalse)
704    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
705  if (argc < 0)
706    return(MagickTrue);
707  mogrify_info=CloneImageInfo(image_info);
708  draw_info=CloneDrawInfo(mogrify_info,(DrawInfo *) NULL);
709  quantize_info=AcquireQuantizeInfo(mogrify_info);
710  SetGeometryInfo(&geometry_info);
711  GetPixelInfo(*image,&fill);
712  fill=(*image)->background_color;
713  attenuate=1.0;
714  compose=(*image)->compose;
715  interpolate_method=UndefinedInterpolatePixel;
716  format=GetImageOption(mogrify_info,"format");
717  SetGeometry(*image,&region_geometry);
718  region_image=NewImageList();
719  /*
720    Transmogrify the image.
721  */
722  for (i=0; i < (ssize_t) argc; i++)
723  {
724    Image
725      *mogrify_image;
726
727    ssize_t
728      count;
729
730    option=argv[i];
731    if (IsCommandOption(option) == MagickFalse)
732      continue;
733    count=MagickMax(ParseCommandOption(MagickCommandOptions,MagickFalse,option),
734      0L);
735    if ((i+count) >= (ssize_t) argc)
736      break;
737    status=MogrifyImageInfo(mogrify_info,(int) count+1,argv+i,exception);
738    mogrify_image=(Image *)NULL;
739    switch (*(option+1))
740    {
741      case 'a':
742      {
743        if (LocaleCompare("adaptive-blur",option+1) == 0)
744          {
745            /*
746              Adaptive blur image.
747            */
748            (void) SyncImageSettings(mogrify_info,*image,exception);
749            flags=ParseGeometry(argv[i+1],&geometry_info);
750            if ((flags & SigmaValue) == 0)
751              geometry_info.sigma=1.0;
752            mogrify_image=AdaptiveBlurImage(*image,geometry_info.rho,
753              geometry_info.sigma,exception);
754            break;
755          }
756        if (LocaleCompare("adaptive-resize",option+1) == 0)
757          {
758            /*
759              Adaptive resize image.
760            */
761            (void) SyncImageSettings(mogrify_info,*image,exception);
762            (void) ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
763            mogrify_image=AdaptiveResizeImage(*image,geometry.width,
764              geometry.height,exception);
765            break;
766          }
767        if (LocaleCompare("adaptive-sharpen",option+1) == 0)
768          {
769            /*
770              Adaptive sharpen image.
771            */
772            (void) SyncImageSettings(mogrify_info,*image,exception);
773            flags=ParseGeometry(argv[i+1],&geometry_info);
774            if ((flags & SigmaValue) == 0)
775              geometry_info.sigma=1.0;
776            mogrify_image=AdaptiveSharpenImage(*image,geometry_info.rho,
777              geometry_info.sigma,exception);
778            break;
779          }
780        if (LocaleCompare("affine",option+1) == 0)
781          {
782            /*
783              Affine matrix.
784            */
785            if (*option == '+')
786              {
787                GetAffineMatrix(&draw_info->affine);
788                break;
789              }
790            (void) ParseAffineGeometry(argv[i+1],&draw_info->affine,exception);
791            break;
792          }
793        if (LocaleCompare("alpha",option+1) == 0)
794          {
795            AlphaChannelType
796              alpha_type;
797
798            (void) SyncImageSettings(mogrify_info,*image,exception);
799            alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
800              MagickFalse,argv[i+1]);
801            (void) SetImageAlphaChannel(*image,alpha_type,exception);
802            break;
803          }
804        if (LocaleCompare("annotate",option+1) == 0)
805          {
806            char
807              *text,
808              geometry[MaxTextExtent];
809
810            /*
811              Annotate image.
812            */
813            (void) SyncImageSettings(mogrify_info,*image,exception);
814            SetGeometryInfo(&geometry_info);
815            flags=ParseGeometry(argv[i+1],&geometry_info);
816            if ((flags & SigmaValue) == 0)
817              geometry_info.sigma=geometry_info.rho;
818            text=InterpretImageProperties(mogrify_info,*image,argv[i+2],
819              exception);
820            if (text == (char *) NULL)
821              break;
822            (void) CloneString(&draw_info->text,text);
823            text=DestroyString(text);
824            (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
825              geometry_info.xi,geometry_info.psi);
826            (void) CloneString(&draw_info->geometry,geometry);
827            draw_info->affine.sx=cos(DegreesToRadians(
828              fmod(geometry_info.rho,360.0)));
829            draw_info->affine.rx=sin(DegreesToRadians(
830              fmod(geometry_info.rho,360.0)));
831            draw_info->affine.ry=(-sin(DegreesToRadians(
832              fmod(geometry_info.sigma,360.0))));
833            draw_info->affine.sy=cos(DegreesToRadians(
834              fmod(geometry_info.sigma,360.0)));
835            (void) AnnotateImage(*image,draw_info,exception);
836            break;
837          }
838        if (LocaleCompare("antialias",option+1) == 0)
839          {
840            draw_info->stroke_antialias=(*option == '-') ? MagickTrue :
841              MagickFalse;
842            draw_info->text_antialias=(*option == '-') ? MagickTrue :
843              MagickFalse;
844            break;
845          }
846        if (LocaleCompare("attenuate",option+1) == 0)
847          {
848            if (*option == '+')
849              {
850                attenuate=1.0;
851                break;
852              }
853            attenuate=StringToDouble(argv[i+1],(char **) NULL);
854            break;
855          }
856        if (LocaleCompare("auto-gamma",option+1) == 0)
857          {
858            /*
859              Auto Adjust Gamma of image based on its mean
860            */
861            (void) SyncImageSettings(mogrify_info,*image,exception);
862            (void) AutoGammaImage(*image,exception);
863            break;
864          }
865        if (LocaleCompare("auto-level",option+1) == 0)
866          {
867            /*
868              Perfectly Normalize (max/min stretch) the image
869            */
870            (void) SyncImageSettings(mogrify_info,*image,exception);
871            (void) AutoLevelImage(*image,exception);
872            break;
873          }
874        if (LocaleCompare("auto-orient",option+1) == 0)
875          {
876            (void) SyncImageSettings(mogrify_info,*image,exception);
877            switch ((*image)->orientation)
878            {
879              case TopRightOrientation:
880              {
881                mogrify_image=FlopImage(*image,exception);
882                break;
883              }
884              case BottomRightOrientation:
885              {
886                mogrify_image=RotateImage(*image,180.0,exception);
887                break;
888              }
889              case BottomLeftOrientation:
890              {
891                mogrify_image=FlipImage(*image,exception);
892                break;
893              }
894              case LeftTopOrientation:
895              {
896                mogrify_image=TransposeImage(*image,exception);
897                break;
898              }
899              case RightTopOrientation:
900              {
901                mogrify_image=RotateImage(*image,90.0,exception);
902                break;
903              }
904              case RightBottomOrientation:
905              {
906                mogrify_image=TransverseImage(*image,exception);
907                break;
908              }
909              case LeftBottomOrientation:
910              {
911                mogrify_image=RotateImage(*image,270.0,exception);
912                break;
913              }
914              default:
915                break;
916            }
917            if (mogrify_image != (Image *) NULL)
918              mogrify_image->orientation=TopLeftOrientation;
919            break;
920          }
921        break;
922      }
923      case 'b':
924      {
925        if (LocaleCompare("black-threshold",option+1) == 0)
926          {
927            /*
928              Black threshold image.
929            */
930            (void) SyncImageSettings(mogrify_info,*image,exception);
931            (void) BlackThresholdImage(*image,argv[i+1],exception);
932            break;
933          }
934        if (LocaleCompare("blue-shift",option+1) == 0)
935          {
936            /*
937              Blue shift image.
938            */
939            (void) SyncImageSettings(mogrify_info,*image,exception);
940            geometry_info.rho=1.5;
941            if (*option == '-')
942              flags=ParseGeometry(argv[i+1],&geometry_info);
943            mogrify_image=BlueShiftImage(*image,geometry_info.rho,exception);
944            break;
945          }
946        if (LocaleCompare("blur",option+1) == 0)
947          {
948            /*
949              Gaussian blur image.
950            */
951            (void) SyncImageSettings(mogrify_info,*image,exception);
952            flags=ParseGeometry(argv[i+1],&geometry_info);
953            if ((flags & SigmaValue) == 0)
954              geometry_info.sigma=1.0;
955            if ((flags & XiValue) == 0)
956              geometry_info.xi=0.0;
957            mogrify_image=BlurImage(*image,geometry_info.rho,
958              geometry_info.sigma,exception);
959            break;
960          }
961        if (LocaleCompare("border",option+1) == 0)
962          {
963            /*
964              Surround image with a border of solid color.
965            */
966            (void) SyncImageSettings(mogrify_info,*image,exception);
967            flags=ParsePageGeometry(*image,argv[i+1],&geometry,exception);
968            if ((flags & SigmaValue) == 0)
969              geometry.height=geometry.width;
970            mogrify_image=BorderImage(*image,&geometry,compose,exception);
971            break;
972          }
973        if (LocaleCompare("bordercolor",option+1) == 0)
974          {
975            if (*option == '+')
976              {
977                (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
978                  &draw_info->border_color,exception);
979                break;
980              }
981            (void) QueryColorCompliance(argv[i+1],AllCompliance,
982              &draw_info->border_color,exception);
983            break;
984          }
985        if (LocaleCompare("box",option+1) == 0)
986          {
987            (void) QueryColorCompliance(argv[i+1],AllCompliance,
988              &draw_info->undercolor,exception);
989            break;
990          }
991        if (LocaleCompare("brightness-contrast",option+1) == 0)
992          {
993            double
994              brightness,
995              contrast;
996
997            GeometryInfo
998              geometry_info;
999
1000            MagickStatusType
1001              flags;
1002
1003            /*
1004              Brightness / contrast image.
1005            */
1006            (void) SyncImageSettings(mogrify_info,*image,exception);
1007            flags=ParseGeometry(argv[i+1],&geometry_info);
1008            brightness=geometry_info.rho;
1009            contrast=0.0;
1010            if ((flags & SigmaValue) != 0)
1011              contrast=geometry_info.sigma;
1012            (void) BrightnessContrastImage(*image,brightness,contrast,
1013              exception);
1014            break;
1015          }
1016        break;
1017      }
1018      case 'c':
1019      {
1020        if (LocaleCompare("cdl",option+1) == 0)
1021          {
1022            char
1023              *color_correction_collection;
1024
1025            /*
1026              Color correct with a color decision list.
1027            */
1028            (void) SyncImageSettings(mogrify_info,*image,exception);
1029            color_correction_collection=FileToString(argv[i+1],~0,exception);
1030            if (color_correction_collection == (char *) NULL)
1031              break;
1032            (void) ColorDecisionListImage(*image,color_correction_collection,
1033              exception);
1034            break;
1035          }
1036        if (LocaleCompare("charcoal",option+1) == 0)
1037          {
1038            /*
1039              Charcoal image.
1040            */
1041            (void) SyncImageSettings(mogrify_info,*image,exception);
1042            flags=ParseGeometry(argv[i+1],&geometry_info);
1043            if ((flags & SigmaValue) == 0)
1044              geometry_info.sigma=1.0;
1045            if ((flags & XiValue) == 0)
1046              geometry_info.xi=1.0;
1047            mogrify_image=CharcoalImage(*image,geometry_info.rho,
1048              geometry_info.sigma,exception);
1049            break;
1050          }
1051        if (LocaleCompare("chop",option+1) == 0)
1052          {
1053            /*
1054              Chop the image.
1055            */
1056            (void) SyncImageSettings(mogrify_info,*image,exception);
1057            (void) ParseGravityGeometry(*image,argv[i+1],&geometry,exception);
1058            mogrify_image=ChopImage(*image,&geometry,exception);
1059            break;
1060          }
1061        if (LocaleCompare("clamp",option+1) == 0)
1062          {
1063            /*
1064              Clamp image.
1065            */
1066            (void) SyncImageSettings(mogrify_info,*image,exception);
1067            (void) ClampImage(*image,exception);
1068            break;
1069          }
1070        if (LocaleCompare("clip",option+1) == 0)
1071          {
1072            (void) SyncImageSettings(mogrify_info,*image,exception);
1073            if (*option == '+')
1074              {
1075                (void) SetImageMask(*image,(Image *) NULL,exception);
1076                break;
1077              }
1078            (void) ClipImage(*image,exception);
1079            break;
1080          }
1081        if (LocaleCompare("clip-mask",option+1) == 0)
1082          {
1083            CacheView
1084              *mask_view;
1085
1086            Image
1087              *mask_image;
1088
1089            register Quantum
1090              *restrict q;
1091
1092            register ssize_t
1093              x;
1094
1095            ssize_t
1096              y;
1097
1098            (void) SyncImageSettings(mogrify_info,*image,exception);
1099            if (*option == '+')
1100              {
1101                /*
1102                  Remove a mask.
1103                */
1104                (void) SetImageMask(*image,(Image *) NULL,exception);
1105                break;
1106              }
1107            /*
1108              Set the image mask.
1109              FUTURE: This Should Be a SetImageAlphaChannel() call, Or two.
1110            */
1111            mask_image=GetImageCache(mogrify_info,argv[i+1],exception);
1112            if (mask_image == (Image *) NULL)
1113              break;
1114            if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
1115              return(MagickFalse);
1116            mask_view=AcquireAuthenticCacheView(mask_image,exception);
1117            for (y=0; y < (ssize_t) mask_image->rows; y++)
1118            {
1119              q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
1120                exception);
1121              if (q == (Quantum *) NULL)
1122                break;
1123              for (x=0; x < (ssize_t) mask_image->columns; x++)
1124              {
1125                if (mask_image->matte == MagickFalse)
1126                  SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1127                SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1128                SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1129                SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1130                q+=GetPixelChannels(mask_image);
1131              }
1132              if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
1133                break;
1134            }
1135            mask_view=DestroyCacheView(mask_view);
1136            mask_image->matte=MagickTrue;
1137            (void) SetImageMask(*image,mask_image,exception);
1138            break;
1139          }
1140        if (LocaleCompare("clip-path",option+1) == 0)
1141          {
1142            (void) SyncImageSettings(mogrify_info,*image,exception);
1143            (void) ClipImagePath(*image,argv[i+1],*option == '-' ? MagickTrue :
1144              MagickFalse,exception);
1145            break;
1146          }
1147        if (LocaleCompare("colorize",option+1) == 0)
1148          {
1149            /*
1150              Colorize the image.
1151            */
1152            (void) SyncImageSettings(mogrify_info,*image,exception);
1153            mogrify_image=ColorizeImage(*image,argv[i+1],&fill,exception);
1154            break;
1155          }
1156        if (LocaleCompare("color-matrix",option+1) == 0)
1157          {
1158            KernelInfo
1159              *kernel;
1160
1161            (void) SyncImageSettings(mogrify_info,*image,exception);
1162            kernel=AcquireKernelInfo(argv[i+1]);
1163            if (kernel == (KernelInfo *) NULL)
1164              break;
1165            /* FUTURE: check on size of the matrix */
1166            mogrify_image=ColorMatrixImage(*image,kernel,exception);
1167            kernel=DestroyKernelInfo(kernel);
1168            break;
1169          }
1170        if (LocaleCompare("colors",option+1) == 0)
1171          {
1172            /*
1173              Reduce the number of colors in the image.
1174            */
1175            (void) SyncImageSettings(mogrify_info,*image,exception);
1176            quantize_info->number_colors=StringToUnsignedLong(argv[i+1]);
1177            if (quantize_info->number_colors == 0)
1178              break;
1179            if (((*image)->storage_class == DirectClass) ||
1180                (*image)->colors > quantize_info->number_colors)
1181              (void) QuantizeImage(quantize_info,*image,exception);
1182            else
1183              (void) CompressImageColormap(*image,exception);
1184            break;
1185          }
1186        if (LocaleCompare("colorspace",option+1) == 0)
1187          {
1188            ColorspaceType
1189              colorspace;
1190
1191            (void) SyncImageSettings(mogrify_info,*image,exception);
1192            if (*option == '+')
1193              {
1194                (void) TransformImageColorspace(*image,sRGBColorspace,
1195                  exception);
1196                break;
1197              }
1198            colorspace=(ColorspaceType) ParseCommandOption(
1199              MagickColorspaceOptions,MagickFalse,argv[i+1]);
1200            (void) TransformImageColorspace(*image,colorspace,exception);
1201            break;
1202          }
1203        if (LocaleCompare("compose",option+1) == 0)
1204          {
1205            (void) SyncImageSettings(mogrify_info,*image,exception);
1206            compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
1207              MagickFalse,argv[i+1]);
1208            break;
1209          }
1210        if (LocaleCompare("contrast",option+1) == 0)
1211          {
1212            (void) SyncImageSettings(mogrify_info,*image,exception);
1213            (void) ContrastImage(*image,(*option == '-') ? MagickTrue :
1214              MagickFalse,exception);
1215            break;
1216          }
1217        if (LocaleCompare("contrast-stretch",option+1) == 0)
1218          {
1219            double
1220              black_point,
1221              white_point;
1222
1223            MagickStatusType
1224              flags;
1225
1226            /*
1227              Contrast stretch image.
1228            */
1229            (void) SyncImageSettings(mogrify_info,*image,exception);
1230            flags=ParseGeometry(argv[i+1],&geometry_info);
1231            black_point=geometry_info.rho;
1232            white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
1233              black_point;
1234            if ((flags & PercentValue) != 0)
1235              {
1236                black_point*=(double) (*image)->columns*(*image)->rows/100.0;
1237                white_point*=(double) (*image)->columns*(*image)->rows/100.0;
1238              }
1239            white_point=(MagickRealType) (*image)->columns*(*image)->rows-
1240              white_point;
1241            (void) ContrastStretchImage(*image,black_point,white_point,
1242              exception);
1243            break;
1244          }
1245        if (LocaleCompare("convolve",option+1) == 0)
1246          {
1247            KernelInfo
1248              *kernel_info;
1249
1250            (void) SyncImageSettings(mogrify_info,*image,exception);
1251            kernel_info=AcquireKernelInfo(argv[i+1]);
1252            if (kernel_info == (KernelInfo *) NULL)
1253              break;
1254            /* kernel_info->bias=(*image)->bias; -- FUTURE: check this path! */
1255            mogrify_image=MorphologyImage(*image,CorrelateMorphology,1,
1256              kernel_info,exception);
1257            kernel_info=DestroyKernelInfo(kernel_info);
1258            break;
1259          }
1260        if (LocaleCompare("crop",option+1) == 0)
1261          {
1262            /*
1263              Crop a image to a smaller size
1264            */
1265            (void) SyncImageSettings(mogrify_info,*image,exception);
1266            mogrify_image=CropImageToTiles(*image,argv[i+1],exception);
1267            break;
1268          }
1269        if (LocaleCompare("cycle",option+1) == 0)
1270          {
1271            /*
1272              Cycle an image colormap.
1273            */
1274            (void) SyncImageSettings(mogrify_info,*image,exception);
1275            (void) CycleColormapImage(*image,(ssize_t) StringToLong(argv[i+1]),
1276              exception);
1277            break;
1278          }
1279        break;
1280      }
1281      case 'd':
1282      {
1283        if (LocaleCompare("decipher",option+1) == 0)
1284          {
1285            StringInfo
1286              *passkey;
1287
1288            /*
1289              Decipher pixels.
1290            */
1291            (void) SyncImageSettings(mogrify_info,*image,exception);
1292            passkey=FileToStringInfo(argv[i+1],~0,exception);
1293            if (passkey != (StringInfo *) NULL)
1294              {
1295                (void) PasskeyDecipherImage(*image,passkey,exception);
1296                passkey=DestroyStringInfo(passkey);
1297              }
1298            break;
1299          }
1300        if (LocaleCompare("density",option+1) == 0)
1301          {
1302            /*
1303              Set image density.
1304            */
1305            (void) CloneString(&draw_info->density,argv[i+1]);
1306            break;
1307          }
1308        if (LocaleCompare("depth",option+1) == 0)
1309          {
1310            (void) SyncImageSettings(mogrify_info,*image,exception);
1311            if (*option == '+')
1312              {
1313                (void) SetImageDepth(*image,MAGICKCORE_QUANTUM_DEPTH,exception);
1314                break;
1315              }
1316            (void) SetImageDepth(*image,StringToUnsignedLong(argv[i+1]),
1317              exception);
1318            break;
1319          }
1320        if (LocaleCompare("deskew",option+1) == 0)
1321          {
1322            double
1323              threshold;
1324
1325            /*
1326              Straighten the image.
1327            */
1328            (void) SyncImageSettings(mogrify_info,*image,exception);
1329            if (*option == '+')
1330              threshold=40.0*QuantumRange/100.0;
1331            else
1332              threshold=StringToDoubleInterval(argv[i+1],(double) QuantumRange+
1333                1.0);
1334            mogrify_image=DeskewImage(*image,threshold,exception);
1335            break;
1336          }
1337        if (LocaleCompare("despeckle",option+1) == 0)
1338          {
1339            /*
1340              Reduce the speckles within an image.
1341            */
1342            (void) SyncImageSettings(mogrify_info,*image,exception);
1343            mogrify_image=DespeckleImage(*image,exception);
1344            break;
1345          }
1346        if (LocaleCompare("display",option+1) == 0)
1347          {
1348            (void) CloneString(&draw_info->server_name,argv[i+1]);
1349            break;
1350          }
1351        if (LocaleCompare("distort",option+1) == 0)
1352          {
1353            char
1354              *args,
1355              token[MaxTextExtent];
1356
1357            const char
1358              *p;
1359
1360            DistortImageMethod
1361              method;
1362
1363            double
1364              *arguments;
1365
1366            register ssize_t
1367              x;
1368
1369            size_t
1370              number_arguments;
1371
1372            /*
1373              Distort image.
1374            */
1375            (void) SyncImageSettings(mogrify_info,*image,exception);
1376            method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
1377              MagickFalse,argv[i+1]);
1378            if (method == ResizeDistortion)
1379              {
1380                 double
1381                   resize_args[2];
1382
1383                 /*
1384                   Special Case - Argument is actually a resize geometry!
1385                   Convert that to an appropriate distortion argument array.
1386                 */
1387                 (void) ParseRegionGeometry(*image,argv[i+2],&geometry,
1388                   exception);
1389                 resize_args[0]=(double) geometry.width;
1390                 resize_args[1]=(double) geometry.height;
1391                 mogrify_image=DistortImage(*image,method,(size_t)2,
1392                   resize_args,MagickTrue,exception);
1393                 break;
1394              }
1395            args=InterpretImageProperties(mogrify_info,*image,argv[i+2],
1396              exception);
1397            if (args == (char *) NULL)
1398              break;
1399            p=(char *) args;
1400            for (x=0; *p != '\0'; x++)
1401            {
1402              GetMagickToken(p,&p,token);
1403              if (*token == ',')
1404                GetMagickToken(p,&p,token);
1405            }
1406            number_arguments=(size_t) x;
1407            arguments=(double *) AcquireQuantumMemory(number_arguments,
1408              sizeof(*arguments));
1409            if (arguments == (double *) NULL)
1410              ThrowWandFatalException(ResourceLimitFatalError,
1411                "MemoryAllocationFailed",(*image)->filename);
1412            (void) ResetMagickMemory(arguments,0,number_arguments*
1413              sizeof(*arguments));
1414            p=(char *) args;
1415            for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
1416            {
1417              GetMagickToken(p,&p,token);
1418              if (*token == ',')
1419                GetMagickToken(p,&p,token);
1420              arguments[x]=StringToDouble(token,(char **) NULL);
1421            }
1422            args=DestroyString(args);
1423            mogrify_image=DistortImage(*image,method,number_arguments,arguments,
1424              (*option == '+') ? MagickTrue : MagickFalse,exception);
1425            arguments=(double *) RelinquishMagickMemory(arguments);
1426            break;
1427          }
1428        if (LocaleCompare("dither",option+1) == 0)
1429          {
1430            if (*option == '+')
1431              {
1432                quantize_info->dither_method=NoDitherMethod;
1433                break;
1434              }
1435            quantize_info->dither_method=(DitherMethod) ParseCommandOption(
1436              MagickDitherOptions,MagickFalse,argv[i+1]);
1437            break;
1438          }
1439        if (LocaleCompare("draw",option+1) == 0)
1440          {
1441            /*
1442              Draw image.
1443            */
1444            (void) SyncImageSettings(mogrify_info,*image,exception);
1445            (void) CloneString(&draw_info->primitive,argv[i+1]);
1446            (void) DrawImage(*image,draw_info,exception);
1447            break;
1448          }
1449        break;
1450      }
1451      case 'e':
1452      {
1453        if (LocaleCompare("edge",option+1) == 0)
1454          {
1455            /*
1456              Enhance edges in the image.
1457            */
1458            (void) SyncImageSettings(mogrify_info,*image,exception);
1459            flags=ParseGeometry(argv[i+1],&geometry_info);
1460            if ((flags & SigmaValue) == 0)
1461              geometry_info.sigma=1.0;
1462            mogrify_image=EdgeImage(*image,geometry_info.rho,
1463              geometry_info.sigma,exception);
1464            break;
1465          }
1466        if (LocaleCompare("emboss",option+1) == 0)
1467          {
1468            /*
1469              Emboss image.
1470            */
1471            (void) SyncImageSettings(mogrify_info,*image,exception);
1472            flags=ParseGeometry(argv[i+1],&geometry_info);
1473            if ((flags & SigmaValue) == 0)
1474              geometry_info.sigma=1.0;
1475            mogrify_image=EmbossImage(*image,geometry_info.rho,
1476              geometry_info.sigma,exception);
1477            break;
1478          }
1479        if (LocaleCompare("encipher",option+1) == 0)
1480          {
1481            StringInfo
1482              *passkey;
1483
1484            /*
1485              Encipher pixels.
1486            */
1487            (void) SyncImageSettings(mogrify_info,*image,exception);
1488            passkey=FileToStringInfo(argv[i+1],~0,exception);
1489            if (passkey != (StringInfo *) NULL)
1490              {
1491                (void) PasskeyEncipherImage(*image,passkey,exception);
1492                passkey=DestroyStringInfo(passkey);
1493              }
1494            break;
1495          }
1496        if (LocaleCompare("encoding",option+1) == 0)
1497          {
1498            (void) CloneString(&draw_info->encoding,argv[i+1]);
1499            break;
1500          }
1501        if (LocaleCompare("enhance",option+1) == 0)
1502          {
1503            /*
1504              Enhance image.
1505            */
1506            (void) SyncImageSettings(mogrify_info,*image,exception);
1507            mogrify_image=EnhanceImage(*image,exception);
1508            break;
1509          }
1510        if (LocaleCompare("equalize",option+1) == 0)
1511          {
1512            /*
1513              Equalize image.
1514            */
1515            (void) SyncImageSettings(mogrify_info,*image,exception);
1516            (void) EqualizeImage(*image,exception);
1517            break;
1518          }
1519        if (LocaleCompare("evaluate",option+1) == 0)
1520          {
1521            double
1522              constant;
1523
1524            MagickEvaluateOperator
1525              op;
1526
1527            (void) SyncImageSettings(mogrify_info,*image,exception);
1528            op=(MagickEvaluateOperator) ParseCommandOption(
1529              MagickEvaluateOptions,MagickFalse,argv[i+1]);
1530            constant=StringToDoubleInterval(argv[i+2],(double) QuantumRange+
1531              1.0);
1532            (void) EvaluateImage(*image,op,constant,exception);
1533            break;
1534          }
1535        if (LocaleCompare("extent",option+1) == 0)
1536          {
1537            /*
1538              Set the image extent.
1539            */
1540            (void) SyncImageSettings(mogrify_info,*image,exception);
1541            flags=ParseGravityGeometry(*image,argv[i+1],&geometry,exception);
1542            if (geometry.width == 0)
1543              geometry.width=(*image)->columns;
1544            if (geometry.height == 0)
1545              geometry.height=(*image)->rows;
1546            mogrify_image=ExtentImage(*image,&geometry,exception);
1547            break;
1548          }
1549        break;
1550      }
1551      case 'f':
1552      {
1553        if (LocaleCompare("family",option+1) == 0)
1554          {
1555            if (*option == '+')
1556              {
1557                if (draw_info->family != (char *) NULL)
1558                  draw_info->family=DestroyString(draw_info->family);
1559                break;
1560              }
1561            (void) CloneString(&draw_info->family,argv[i+1]);
1562            break;
1563          }
1564        if (LocaleCompare("features",option+1) == 0)
1565          {
1566            if (*option == '+')
1567              {
1568                (void) DeleteImageArtifact(*image,"identify:features");
1569                break;
1570              }
1571            (void) SetImageArtifact(*image,"identify:features",argv[i+1]);
1572            break;
1573          }
1574        if (LocaleCompare("fill",option+1) == 0)
1575          {
1576            ExceptionInfo
1577              *sans;
1578
1579            PixelInfo
1580              color;
1581
1582            GetPixelInfo(*image,&fill);
1583            if (*option == '+')
1584              {
1585                (void) QueryColorCompliance("none",AllCompliance,&fill,
1586                  exception);
1587                draw_info->fill=fill;
1588                if (draw_info->fill_pattern != (Image *) NULL)
1589                  draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
1590                break;
1591              }
1592            sans=AcquireExceptionInfo();
1593            status=QueryColorCompliance(argv[i+1],AllCompliance,&color,sans);
1594            sans=DestroyExceptionInfo(sans);
1595            if (status == MagickFalse)
1596              draw_info->fill_pattern=GetImageCache(mogrify_info,argv[i+1],
1597                exception);
1598            else
1599              draw_info->fill=fill=color;
1600            break;
1601          }
1602        if (LocaleCompare("flip",option+1) == 0)
1603          {
1604            /*
1605              Flip image scanlines.
1606            */
1607            (void) SyncImageSettings(mogrify_info,*image,exception);
1608            mogrify_image=FlipImage(*image,exception);
1609            break;
1610          }
1611        if (LocaleCompare("floodfill",option+1) == 0)
1612          {
1613            PixelInfo
1614              target;
1615
1616            /*
1617              Floodfill image.
1618            */
1619            (void) SyncImageSettings(mogrify_info,*image,exception);
1620            (void) ParsePageGeometry(*image,argv[i+1],&geometry,exception);
1621            (void) QueryColorCompliance(argv[i+2],AllCompliance,&target,
1622              exception);
1623            (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
1624              geometry.y,*option == '-' ? MagickFalse : MagickTrue,exception);
1625            break;
1626          }
1627        if (LocaleCompare("flop",option+1) == 0)
1628          {
1629            /*
1630              Flop image scanlines.
1631            */
1632            (void) SyncImageSettings(mogrify_info,*image,exception);
1633            mogrify_image=FlopImage(*image,exception);
1634            break;
1635          }
1636        if (LocaleCompare("font",option+1) == 0)
1637          {
1638            if (*option == '+')
1639              {
1640                if (draw_info->font != (char *) NULL)
1641                  draw_info->font=DestroyString(draw_info->font);
1642                break;
1643              }
1644            (void) CloneString(&draw_info->font,argv[i+1]);
1645            break;
1646          }
1647        if (LocaleCompare("format",option+1) == 0)
1648          {
1649            format=argv[i+1];
1650            break;
1651          }
1652        if (LocaleCompare("frame",option+1) == 0)
1653          {
1654            FrameInfo
1655              frame_info;
1656
1657            /*
1658              Surround image with an ornamental border.
1659            */
1660            (void) SyncImageSettings(mogrify_info,*image,exception);
1661            flags=ParsePageGeometry(*image,argv[i+1],&geometry,exception);
1662            frame_info.width=geometry.width;
1663            frame_info.height=geometry.height;
1664            if ((flags & HeightValue) == 0)
1665              frame_info.height=geometry.width;
1666            frame_info.outer_bevel=geometry.x;
1667            frame_info.inner_bevel=geometry.y;
1668            frame_info.x=(ssize_t) frame_info.width;
1669            frame_info.y=(ssize_t) frame_info.height;
1670            frame_info.width=(*image)->columns+2*frame_info.width;
1671            frame_info.height=(*image)->rows+2*frame_info.height;
1672            mogrify_image=FrameImage(*image,&frame_info,compose,exception);
1673            break;
1674          }
1675        if (LocaleCompare("function",option+1) == 0)
1676          {
1677            char
1678              *arguments,
1679              token[MaxTextExtent];
1680
1681            const char
1682              *p;
1683
1684            double
1685              *parameters;
1686
1687            MagickFunction
1688              function;
1689
1690            register ssize_t
1691              x;
1692
1693            size_t
1694              number_parameters;
1695
1696            /*
1697              Function Modify Image Values
1698            */
1699            (void) SyncImageSettings(mogrify_info,*image,exception);
1700            function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
1701              MagickFalse,argv[i+1]);
1702            arguments=InterpretImageProperties(mogrify_info,*image,argv[i+2],
1703              exception);
1704            if (arguments == (char *) NULL)
1705              break;
1706            p=(char *) arguments;
1707            for (x=0; *p != '\0'; x++)
1708            {
1709              GetMagickToken(p,&p,token);
1710              if (*token == ',')
1711                GetMagickToken(p,&p,token);
1712            }
1713            number_parameters=(size_t) x;
1714            parameters=(double *) AcquireQuantumMemory(number_parameters,
1715              sizeof(*parameters));
1716            if (parameters == (double *) NULL)
1717              ThrowWandFatalException(ResourceLimitFatalError,
1718                "MemoryAllocationFailed",(*image)->filename);
1719            (void) ResetMagickMemory(parameters,0,number_parameters*
1720              sizeof(*parameters));
1721            p=(char *) arguments;
1722            for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
1723            {
1724              GetMagickToken(p,&p,token);
1725              if (*token == ',')
1726                GetMagickToken(p,&p,token);
1727              parameters[x]=StringToDouble(token,(char **) NULL);
1728            }
1729            arguments=DestroyString(arguments);
1730            (void) FunctionImage(*image,function,number_parameters,parameters,
1731              exception);
1732            parameters=(double *) RelinquishMagickMemory(parameters);
1733            break;
1734          }
1735        break;
1736      }
1737      case 'g':
1738      {
1739        if (LocaleCompare("gamma",option+1) == 0)
1740          {
1741            /*
1742              Gamma image.
1743            */
1744            (void) SyncImageSettings(mogrify_info,*image,exception);
1745            if (*option == '+')
1746              (*image)->gamma=StringToDouble(argv[i+1],(char **) NULL);
1747            else
1748              (void) GammaImage(*image,StringToDouble(argv[i+1],
1749                (char **) NULL),exception);
1750            break;
1751          }
1752        if ((LocaleCompare("gaussian-blur",option+1) == 0) ||
1753            (LocaleCompare("gaussian",option+1) == 0))
1754          {
1755            /*
1756              Gaussian blur image.
1757            */
1758            (void) SyncImageSettings(mogrify_info,*image,exception);
1759            flags=ParseGeometry(argv[i+1],&geometry_info);
1760            if ((flags & SigmaValue) == 0)
1761              geometry_info.sigma=1.0;
1762            mogrify_image=GaussianBlurImage(*image,geometry_info.rho,
1763              geometry_info.sigma,exception);
1764            break;
1765          }
1766        if (LocaleCompare("geometry",option+1) == 0)
1767          {
1768              /*
1769                Record Image offset, Resize last image.
1770              */
1771            (void) SyncImageSettings(mogrify_info,*image,exception);
1772            if (*option == '+')
1773              {
1774                if ((*image)->geometry != (char *) NULL)
1775                  (*image)->geometry=DestroyString((*image)->geometry);
1776                break;
1777              }
1778            flags=ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
1779            if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1780              (void) CloneString(&(*image)->geometry,argv[i+1]);
1781            else
1782              mogrify_image=ResizeImage(*image,geometry.width,geometry.height,
1783                (*image)->filter,exception);
1784            break;
1785          }
1786        if (LocaleCompare("gravity",option+1) == 0)
1787          {
1788            if (*option == '+')
1789              {
1790                draw_info->gravity=UndefinedGravity;
1791                break;
1792              }
1793            draw_info->gravity=(GravityType) ParseCommandOption(
1794              MagickGravityOptions,MagickFalse,argv[i+1]);
1795            break;
1796          }
1797        break;
1798      }
1799      case 'h':
1800      {
1801        if (LocaleCompare("highlight-color",option+1) == 0)
1802          {
1803            (void) SetImageArtifact(*image,option+1,argv[i+1]);
1804            break;
1805          }
1806        break;
1807      }
1808      case 'i':
1809      {
1810        if (LocaleCompare("identify",option+1) == 0)
1811          {
1812            char
1813              *text;
1814
1815            (void) SyncImageSettings(mogrify_info,*image,exception);
1816            if (format == (char *) NULL)
1817              {
1818                (void) IdentifyImage(*image,stdout,mogrify_info->verbose,
1819                  exception);
1820                break;
1821              }
1822            text=InterpretImageProperties(mogrify_info,*image,format,
1823              exception);
1824            if (text == (char *) NULL)
1825              break;
1826            (void) fputs(text,stdout);
1827            (void) fputc('\n',stdout);
1828            text=DestroyString(text);
1829            break;
1830          }
1831        if (LocaleCompare("implode",option+1) == 0)
1832          {
1833            /*
1834              Implode image.
1835            */
1836            (void) SyncImageSettings(mogrify_info,*image,exception);
1837            (void) ParseGeometry(argv[i+1],&geometry_info);
1838            mogrify_image=ImplodeImage(*image,geometry_info.rho,
1839              interpolate_method,exception);
1840            break;
1841          }
1842        if (LocaleCompare("interline-spacing",option+1) == 0)
1843          {
1844            if (*option == '+')
1845              (void) ParseGeometry("0",&geometry_info);
1846            else
1847              (void) ParseGeometry(argv[i+1],&geometry_info);
1848            draw_info->interline_spacing=geometry_info.rho;
1849            break;
1850          }
1851        if (LocaleCompare("interpolate",option+1) == 0)
1852          {
1853            interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
1854              MagickInterpolateOptions,MagickFalse,argv[i+1]);
1855            break;
1856          }
1857        if (LocaleCompare("interword-spacing",option+1) == 0)
1858          {
1859            if (*option == '+')
1860              (void) ParseGeometry("0",&geometry_info);
1861            else
1862              (void) ParseGeometry(argv[i+1],&geometry_info);
1863            draw_info->interword_spacing=geometry_info.rho;
1864            break;
1865          }
1866        if (LocaleCompare("interpolative-resize",option+1) == 0)
1867          {
1868            /*
1869              Interpolative resize image.
1870            */
1871            (void) SyncImageSettings(mogrify_info,*image,exception);
1872            (void) ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
1873            mogrify_image=InterpolativeResizeImage(*image,geometry.width,
1874              geometry.height,interpolate_method,exception);
1875            break;
1876          }
1877        break;
1878      }
1879      case 'k':
1880      {
1881        if (LocaleCompare("kerning",option+1) == 0)
1882          {
1883            if (*option == '+')
1884              (void) ParseGeometry("0",&geometry_info);
1885            else
1886              (void) ParseGeometry(argv[i+1],&geometry_info);
1887            draw_info->kerning=geometry_info.rho;
1888            break;
1889          }
1890        break;
1891      }
1892      case 'l':
1893      {
1894        if (LocaleCompare("lat",option+1) == 0)
1895          {
1896            /*
1897              Local adaptive threshold image.
1898            */
1899            (void) SyncImageSettings(mogrify_info,*image,exception);
1900            flags=ParseGeometry(argv[i+1],&geometry_info);
1901            if ((flags & PercentValue) != 0)
1902              geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
1903            mogrify_image=AdaptiveThresholdImage(*image,(size_t)
1904              geometry_info.rho,(size_t) geometry_info.sigma,(double)
1905              geometry_info.xi,exception);
1906            break;
1907          }
1908        if (LocaleCompare("level",option+1) == 0)
1909          {
1910            MagickRealType
1911              black_point,
1912              gamma,
1913              white_point;
1914
1915            MagickStatusType
1916              flags;
1917
1918            /*
1919              Parse levels.
1920            */
1921            (void) SyncImageSettings(mogrify_info,*image,exception);
1922            flags=ParseGeometry(argv[i+1],&geometry_info);
1923            black_point=geometry_info.rho;
1924            white_point=(MagickRealType) QuantumRange;
1925            if ((flags & SigmaValue) != 0)
1926              white_point=geometry_info.sigma;
1927            gamma=1.0;
1928            if ((flags & XiValue) != 0)
1929              gamma=geometry_info.xi;
1930            if ((flags & PercentValue) != 0)
1931              {
1932                black_point*=(MagickRealType) (QuantumRange/100.0);
1933                white_point*=(MagickRealType) (QuantumRange/100.0);
1934              }
1935            if ((flags & SigmaValue) == 0)
1936              white_point=(MagickRealType) QuantumRange-black_point;
1937            if ((*option == '+') || ((flags & AspectValue) != 0))
1938              (void) LevelizeImage(*image,black_point,white_point,gamma,
1939                exception);
1940            else
1941              (void) LevelImage(*image,black_point,white_point,gamma,
1942                exception);
1943            break;
1944          }
1945        if (LocaleCompare("level-colors",option+1) == 0)
1946          {
1947            char
1948              token[MaxTextExtent];
1949
1950            const char
1951              *p;
1952
1953            PixelInfo
1954              black_point,
1955              white_point;
1956
1957            p=(const char *) argv[i+1];
1958            GetMagickToken(p,&p,token);  /* get black point color */
1959            if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
1960              (void) QueryColorCompliance(token,AllCompliance,
1961                &black_point,exception);
1962            else
1963              (void) QueryColorCompliance("#000000",AllCompliance,
1964                &black_point,exception);
1965            if (isalpha((int) token[0]) || (token[0] == '#'))
1966              GetMagickToken(p,&p,token);
1967            if (*token == '\0')
1968              white_point=black_point; /* set everything to that color */
1969            else
1970              {
1971                if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
1972                  GetMagickToken(p,&p,token); /* Get white point color. */
1973                if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
1974                  (void) QueryColorCompliance(token,AllCompliance,
1975                    &white_point,exception);
1976                else
1977                  (void) QueryColorCompliance("#ffffff",AllCompliance,
1978                    &white_point,exception);
1979              }
1980            (void) LevelImageColors(*image,&black_point,&white_point,
1981              *option == '+' ? MagickTrue : MagickFalse,exception);
1982            break;
1983          }
1984        if (LocaleCompare("linear-stretch",option+1) == 0)
1985          {
1986            double
1987              black_point,
1988              white_point;
1989
1990            MagickStatusType
1991              flags;
1992
1993            (void) SyncImageSettings(mogrify_info,*image,exception);
1994            flags=ParseGeometry(argv[i+1],&geometry_info);
1995            black_point=geometry_info.rho;
1996            white_point=(MagickRealType) (*image)->columns*(*image)->rows;
1997            if ((flags & SigmaValue) != 0)
1998              white_point=geometry_info.sigma;
1999            if ((flags & PercentValue) != 0)
2000              {
2001                black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2002                white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2003              }
2004            if ((flags & SigmaValue) == 0)
2005              white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2006                black_point;
2007            (void) LinearStretchImage(*image,black_point,white_point,exception);
2008            break;
2009          }
2010        if (LocaleCompare("liquid-rescale",option+1) == 0)
2011          {
2012            /*
2013              Liquid rescale image.
2014            */
2015            (void) SyncImageSettings(mogrify_info,*image,exception);
2016            flags=ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
2017            if ((flags & XValue) == 0)
2018              geometry.x=1;
2019            if ((flags & YValue) == 0)
2020              geometry.y=0;
2021            mogrify_image=LiquidRescaleImage(*image,geometry.width,
2022              geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
2023            break;
2024          }
2025        if (LocaleCompare("lowlight-color",option+1) == 0)
2026          {
2027            (void) SetImageArtifact(*image,option+1,argv[i+1]);
2028            break;
2029          }
2030        break;
2031      }
2032      case 'm':
2033      {
2034        if (LocaleCompare("map",option+1) == 0)
2035          {
2036            Image
2037              *remap_image;
2038
2039            /*
2040              Transform image colors to match this set of colors.
2041            */
2042            (void) SyncImageSettings(mogrify_info,*image,exception);
2043            if (*option == '+')
2044              break;
2045            remap_image=GetImageCache(mogrify_info,argv[i+1],exception);
2046            if (remap_image == (Image *) NULL)
2047              break;
2048            (void) RemapImage(quantize_info,*image,remap_image,exception);
2049            remap_image=DestroyImage(remap_image);
2050            break;
2051          }
2052        if (LocaleCompare("mask",option+1) == 0)
2053          {
2054            Image
2055              *mask;
2056
2057            (void) SyncImageSettings(mogrify_info,*image,exception);
2058            if (*option == '+')
2059              {
2060                /*
2061                  Remove a mask.
2062                */
2063                (void) SetImageMask(*image,(Image *) NULL,exception);
2064                break;
2065              }
2066            /*
2067              Set the image mask.
2068            */
2069            mask=GetImageCache(mogrify_info,argv[i+1],exception);
2070            if (mask == (Image *) NULL)
2071              break;
2072            (void) SetImageMask(*image,mask,exception);
2073            mask=DestroyImage(mask);
2074            break;
2075          }
2076        if (LocaleCompare("matte",option+1) == 0)
2077          {
2078            (void) SetImageAlphaChannel(*image,(*option == '-') ?
2079              SetAlphaChannel : DeactivateAlphaChannel,exception);
2080            break;
2081          }
2082        if (LocaleCompare("median",option+1) == 0)
2083          {
2084            /*
2085              Median filter image.
2086            */
2087            (void) SyncImageSettings(mogrify_info,*image,exception);
2088            flags=ParseGeometry(argv[i+1],&geometry_info);
2089            if ((flags & SigmaValue) == 0)
2090              geometry_info.sigma=geometry_info.rho;
2091            mogrify_image=StatisticImage(*image,MedianStatistic,(size_t)
2092              geometry_info.rho,(size_t) geometry_info.sigma,exception);
2093            break;
2094          }
2095        if (LocaleCompare("mode",option+1) == 0)
2096          {
2097            /*
2098              Mode image.
2099            */
2100            (void) SyncImageSettings(mogrify_info,*image,exception);
2101            flags=ParseGeometry(argv[i+1],&geometry_info);
2102            if ((flags & SigmaValue) == 0)
2103              geometry_info.sigma=geometry_info.rho;
2104            mogrify_image=StatisticImage(*image,ModeStatistic,(size_t)
2105              geometry_info.rho,(size_t) geometry_info.sigma,exception);
2106            break;
2107          }
2108        if (LocaleCompare("modulate",option+1) == 0)
2109          {
2110            (void) SyncImageSettings(mogrify_info,*image,exception);
2111            (void) ModulateImage(*image,argv[i+1],exception);
2112            break;
2113          }
2114        if (LocaleCompare("monitor",option+1) == 0)
2115          {
2116            if (*option == '+')
2117              {
2118                (void) SetImageProgressMonitor(*image,
2119                  (MagickProgressMonitor) NULL,(void *) NULL);
2120                break;
2121              }
2122            (void) SetImageProgressMonitor(*image,MonitorProgress,
2123              (void *) NULL);
2124            break;
2125          }
2126        if (LocaleCompare("monochrome",option+1) == 0)
2127          {
2128            (void) SyncImageSettings(mogrify_info,*image,exception);
2129            (void) SetImageType(*image,BilevelType,exception);
2130            break;
2131          }
2132        if (LocaleCompare("morphology",option+1) == 0)
2133          {
2134            char
2135              token[MaxTextExtent];
2136
2137            const char
2138              *p;
2139
2140            KernelInfo
2141              *kernel;
2142
2143            MorphologyMethod
2144              method;
2145
2146            ssize_t
2147              iterations;
2148
2149            /*
2150              Morphological Image Operation
2151            */
2152            (void) SyncImageSettings(mogrify_info,*image,exception);
2153            p=argv[i+1];
2154            GetMagickToken(p,&p,token);
2155            method=(MorphologyMethod) ParseCommandOption(
2156              MagickMorphologyOptions,MagickFalse,token);
2157            iterations=1L;
2158            GetMagickToken(p,&p,token);
2159            if ((*p == ':') || (*p == ','))
2160              GetMagickToken(p,&p,token);
2161            if ((*p != '\0'))
2162              iterations=(ssize_t) StringToLong(p);
2163            kernel=AcquireKernelInfo(argv[i+2]);
2164            if (kernel == (KernelInfo *) NULL)
2165              {
2166                (void) ThrowMagickException(exception,GetMagickModule(),
2167                  OptionError,"UnabletoParseKernel","morphology");
2168                status=MagickFalse;
2169                break;
2170              }
2171            mogrify_image=MorphologyImage(*image,method,iterations,kernel,
2172              exception);
2173            kernel=DestroyKernelInfo(kernel);
2174            break;
2175          }
2176        if (LocaleCompare("motion-blur",option+1) == 0)
2177          {
2178            /*
2179              Motion blur image.
2180            */
2181            (void) SyncImageSettings(mogrify_info,*image,exception);
2182            flags=ParseGeometry(argv[i+1],&geometry_info);
2183            if ((flags & SigmaValue) == 0)
2184              geometry_info.sigma=1.0;
2185            mogrify_image=MotionBlurImage(*image,geometry_info.rho,
2186              geometry_info.sigma,geometry_info.xi,exception);
2187            break;
2188          }
2189        break;
2190      }
2191      case 'n':
2192      {
2193        if (LocaleCompare("negate",option+1) == 0)
2194          {
2195            (void) SyncImageSettings(mogrify_info,*image,exception);
2196            (void) NegateImage(*image,*option == '+' ? MagickTrue :
2197              MagickFalse,exception);
2198            break;
2199          }
2200        if (LocaleCompare("noise",option+1) == 0)
2201          {
2202            (void) SyncImageSettings(mogrify_info,*image,exception);
2203            if (*option == '-')
2204              {
2205                flags=ParseGeometry(argv[i+1],&geometry_info);
2206                if ((flags & SigmaValue) == 0)
2207                  geometry_info.sigma=geometry_info.rho;
2208                mogrify_image=StatisticImage(*image,NonpeakStatistic,(size_t)
2209                  geometry_info.rho,(size_t) geometry_info.sigma,exception);
2210              }
2211            else
2212              {
2213                NoiseType
2214                  noise;
2215
2216                noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
2217                  MagickFalse,argv[i+1]);
2218                mogrify_image=AddNoiseImage(*image,noise,attenuate,exception);
2219              }
2220            break;
2221          }
2222        if (LocaleCompare("normalize",option+1) == 0)
2223          {
2224            (void) SyncImageSettings(mogrify_info,*image,exception);
2225            (void) NormalizeImage(*image,exception);
2226            break;
2227          }
2228        break;
2229      }
2230      case 'o':
2231      {
2232        if (LocaleCompare("opaque",option+1) == 0)
2233          {
2234            PixelInfo
2235              target;
2236
2237            (void) SyncImageSettings(mogrify_info,*image,exception);
2238            (void) QueryColorCompliance(argv[i+1],AllCompliance,&target,
2239              exception);
2240            (void) OpaquePaintImage(*image,&target,&fill,*option == '-' ?
2241              MagickFalse : MagickTrue,exception);
2242            break;
2243          }
2244        if (LocaleCompare("ordered-dither",option+1) == 0)
2245          {
2246            (void) SyncImageSettings(mogrify_info,*image,exception);
2247            (void) OrderedPosterizeImage(*image,argv[i+1],exception);
2248            break;
2249          }
2250        break;
2251      }
2252      case 'p':
2253      {
2254        if (LocaleCompare("paint",option+1) == 0)
2255          {
2256            (void) SyncImageSettings(mogrify_info,*image,exception);
2257            (void) ParseGeometry(argv[i+1],&geometry_info);
2258            mogrify_image=OilPaintImage(*image,geometry_info.rho,
2259              geometry_info.sigma,exception);
2260            break;
2261          }
2262        if (LocaleCompare("pointsize",option+1) == 0)
2263          {
2264            if (*option == '+')
2265              (void) ParseGeometry("12",&geometry_info);
2266            else
2267              (void) ParseGeometry(argv[i+1],&geometry_info);
2268            draw_info->pointsize=geometry_info.rho;
2269            break;
2270          }
2271        if (LocaleCompare("polaroid",option+1) == 0)
2272          {
2273            const char
2274              *caption;
2275
2276            double
2277              angle;
2278
2279            RandomInfo
2280              *random_info;
2281
2282            /*
2283              Simulate a Polaroid picture.
2284            */
2285            (void) SyncImageSettings(mogrify_info,*image,exception);
2286            random_info=AcquireRandomInfo();
2287            angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2288            random_info=DestroyRandomInfo(random_info);
2289            if (*option == '-')
2290              {
2291                SetGeometryInfo(&geometry_info);
2292                flags=ParseGeometry(argv[i+1],&geometry_info);
2293                angle=geometry_info.rho;
2294              }
2295            caption=GetImageProperty(*image,"caption",exception);
2296            mogrify_image=PolaroidImage(*image,draw_info,caption,angle,
2297              interpolate_method,exception);
2298            break;
2299          }
2300        if (LocaleCompare("posterize",option+1) == 0)
2301          {
2302            /*
2303              Posterize image.
2304            */
2305            (void) SyncImageSettings(mogrify_info,*image,exception);
2306            (void) PosterizeImage(*image,StringToUnsignedLong(argv[i+1]),
2307              quantize_info->dither_method,exception);
2308            break;
2309          }
2310        if (LocaleCompare("preview",option+1) == 0)
2311          {
2312            PreviewType
2313              preview_type;
2314
2315            /*
2316              Preview image.
2317            */
2318            (void) SyncImageSettings(mogrify_info,*image,exception);
2319            if (*option == '+')
2320              preview_type=UndefinedPreview;
2321            else
2322              preview_type=(PreviewType) ParseCommandOption(
2323                MagickPreviewOptions,MagickFalse,argv[i+1]);
2324            mogrify_image=PreviewImage(*image,preview_type,exception);
2325            break;
2326          }
2327        if (LocaleCompare("profile",option+1) == 0)
2328          {
2329            const char
2330              *name;
2331
2332            const StringInfo
2333              *profile;
2334
2335            Image
2336              *profile_image;
2337
2338            ImageInfo
2339              *profile_info;
2340
2341            (void) SyncImageSettings(mogrify_info,*image,exception);
2342            if (*option == '+')
2343              {
2344                /*
2345                  Remove a profile from the image.
2346                */
2347                (void) ProfileImage(*image,argv[i+1],(const unsigned char *)
2348                  NULL,0,exception);
2349                break;
2350              }
2351            /*
2352              Associate a profile with the image.
2353            */
2354            profile_info=CloneImageInfo(mogrify_info);
2355            profile=GetImageProfile(*image,"iptc");
2356            if (profile != (StringInfo *) NULL)
2357              profile_info->profile=(void *) CloneStringInfo(profile);
2358            profile_image=GetImageCache(profile_info,argv[i+1],exception);
2359            profile_info=DestroyImageInfo(profile_info);
2360            if (profile_image == (Image *) NULL)
2361              {
2362                StringInfo
2363                  *profile;
2364
2365                profile_info=CloneImageInfo(mogrify_info);
2366                (void) CopyMagickString(profile_info->filename,argv[i+1],
2367                  MaxTextExtent);
2368                profile=FileToStringInfo(profile_info->filename,~0UL,exception);
2369                if (profile != (StringInfo *) NULL)
2370                  {
2371                    (void) ProfileImage(*image,profile_info->magick,
2372                      GetStringInfoDatum(profile),(size_t)
2373                      GetStringInfoLength(profile),exception);
2374                    profile=DestroyStringInfo(profile);
2375                  }
2376                profile_info=DestroyImageInfo(profile_info);
2377                break;
2378              }
2379            ResetImageProfileIterator(profile_image);
2380            name=GetNextImageProfile(profile_image);
2381            while (name != (const char *) NULL)
2382            {
2383              profile=GetImageProfile(profile_image,name);
2384              if (profile != (StringInfo *) NULL)
2385                (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
2386                  (size_t) GetStringInfoLength(profile),exception);
2387              name=GetNextImageProfile(profile_image);
2388            }
2389            profile_image=DestroyImage(profile_image);
2390            break;
2391          }
2392        break;
2393      }
2394      case 'q':
2395      {
2396        if (LocaleCompare("quantize",option+1) == 0)
2397          {
2398            if (*option == '+')
2399              {
2400                quantize_info->colorspace=UndefinedColorspace;
2401                break;
2402              }
2403            quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
2404              MagickColorspaceOptions,MagickFalse,argv[i+1]);
2405            break;
2406          }
2407        break;
2408      }
2409      case 'r':
2410      {
2411        if (LocaleCompare("radial-blur",option+1) == 0)
2412          {
2413            /*
2414              Radial blur image.
2415            */
2416            (void) SyncImageSettings(mogrify_info,*image,exception);
2417            flags=ParseGeometry(argv[i+1],&geometry_info);
2418            mogrify_image=RadialBlurImage(*image,geometry_info.rho,exception);
2419            break;
2420          }
2421        if (LocaleCompare("raise",option+1) == 0)
2422          {
2423            /*
2424              Surround image with a raise of solid color.
2425            */
2426            flags=ParsePageGeometry(*image,argv[i+1],&geometry,exception);
2427            if ((flags & SigmaValue) == 0)
2428              geometry.height=geometry.width;
2429            (void) RaiseImage(*image,&geometry,*option == '-' ? MagickTrue :
2430              MagickFalse,exception);
2431            break;
2432          }
2433        if (LocaleCompare("random-threshold",option+1) == 0)
2434          {
2435            /*
2436              Threshold image.
2437            */
2438            (void) SyncImageSettings(mogrify_info,*image,exception);
2439            (void) RandomThresholdImage(*image,argv[i+1],exception);
2440            break;
2441          }
2442        if (LocaleCompare("region",option+1) == 0)
2443          {
2444            (void) SyncImageSettings(mogrify_info,*image,exception);
2445            if (region_image != (Image *) NULL)
2446              {
2447                /*
2448                  Composite region.
2449                */
2450                (void) CompositeImage(region_image,*image,region_image->matte !=
2451                   MagickFalse ? CopyCompositeOp : OverCompositeOp,MagickTrue,
2452                   region_geometry.x,region_geometry.y,exception);
2453                *image=DestroyImage(*image);
2454                *image=region_image;
2455                region_image = (Image *) NULL;
2456              }
2457            if (*option == '+')
2458              break;
2459            /*
2460              Apply transformations to a selected region of the image.
2461            */
2462            (void) ParseGravityGeometry(*image,argv[i+1],&region_geometry,
2463              exception);
2464            mogrify_image=CropImage(*image,&region_geometry,exception);
2465            if (mogrify_image == (Image *) NULL)
2466              break;
2467            region_image=(*image);
2468            *image=mogrify_image;
2469            mogrify_image=(Image *) NULL;
2470            break;
2471          }
2472        if (LocaleCompare("render",option+1) == 0)
2473          {
2474            (void) SyncImageSettings(mogrify_info,*image,exception);
2475            draw_info->render=(*option == '+') ? MagickTrue : MagickFalse;
2476            break;
2477          }
2478        if (LocaleCompare("remap",option+1) == 0)
2479          {
2480            Image
2481              *remap_image;
2482
2483            /*
2484              Transform image colors to match this set of colors.
2485            */
2486            (void) SyncImageSettings(mogrify_info,*image,exception);
2487            if (*option == '+')
2488              break;
2489            remap_image=GetImageCache(mogrify_info,argv[i+1],exception);
2490            if (remap_image == (Image *) NULL)
2491              break;
2492            (void) RemapImage(quantize_info,*image,remap_image,exception);
2493            remap_image=DestroyImage(remap_image);
2494            break;
2495          }
2496        if (LocaleCompare("repage",option+1) == 0)
2497          {
2498            if (*option == '+')
2499              {
2500                (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
2501                break;
2502              }
2503            (void) ResetImagePage(*image,argv[i+1]);
2504            break;
2505          }
2506        if (LocaleCompare("resample",option+1) == 0)
2507          {
2508            /*
2509              Resample image.
2510            */
2511            (void) SyncImageSettings(mogrify_info,*image,exception);
2512            flags=ParseGeometry(argv[i+1],&geometry_info);
2513            if ((flags & SigmaValue) == 0)
2514              geometry_info.sigma=geometry_info.rho;
2515            mogrify_image=ResampleImage(*image,geometry_info.rho,
2516              geometry_info.sigma,(*image)->filter,exception);
2517            break;
2518          }
2519        if (LocaleCompare("resize",option+1) == 0)
2520          {
2521            /*
2522              Resize image.
2523            */
2524            (void) SyncImageSettings(mogrify_info,*image,exception);
2525            (void) ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
2526            mogrify_image=ResizeImage(*image,geometry.width,geometry.height,
2527              (*image)->filter,exception);
2528            break;
2529          }
2530        if (LocaleCompare("roll",option+1) == 0)
2531          {
2532            /*
2533              Roll image.
2534            */
2535            (void) SyncImageSettings(mogrify_info,*image,exception);
2536            (void) ParsePageGeometry(*image,argv[i+1],&geometry,exception);
2537            mogrify_image=RollImage(*image,geometry.x,geometry.y,exception);
2538            break;
2539          }
2540        if (LocaleCompare("rotate",option+1) == 0)
2541          {
2542            char
2543              *geometry;
2544
2545            /*
2546              Check for conditional image rotation.
2547            */
2548            (void) SyncImageSettings(mogrify_info,*image,exception);
2549            if (strchr(argv[i+1],'>') != (char *) NULL)
2550              if ((*image)->columns <= (*image)->rows)
2551                break;
2552            if (strchr(argv[i+1],'<') != (char *) NULL)
2553              if ((*image)->columns >= (*image)->rows)
2554                break;
2555            /*
2556              Rotate image.
2557            */
2558            geometry=ConstantString(argv[i+1]);
2559            (void) SubstituteString(&geometry,">","");
2560            (void) SubstituteString(&geometry,"<","");
2561            (void) ParseGeometry(geometry,&geometry_info);
2562            geometry=DestroyString(geometry);
2563            mogrify_image=RotateImage(*image,geometry_info.rho,exception);
2564            break;
2565          }
2566        break;
2567      }
2568      case 's':
2569      {
2570        if (LocaleCompare("sample",option+1) == 0)
2571          {
2572            /*
2573              Sample image with pixel replication.
2574            */
2575            (void) SyncImageSettings(mogrify_info,*image,exception);
2576            (void) ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
2577            mogrify_image=SampleImage(*image,geometry.width,geometry.height,
2578              exception);
2579            break;
2580          }
2581        if (LocaleCompare("scale",option+1) == 0)
2582          {
2583            /*
2584              Resize image.
2585            */
2586            (void) SyncImageSettings(mogrify_info,*image,exception);
2587            (void) ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
2588            mogrify_image=ScaleImage(*image,geometry.width,geometry.height,
2589              exception);
2590            break;
2591          }
2592        if (LocaleCompare("selective-blur",option+1) == 0)
2593          {
2594            /*
2595              Selectively blur pixels within a contrast threshold.
2596            */
2597            (void) SyncImageSettings(mogrify_info,*image,exception);
2598            flags=ParseGeometry(argv[i+1],&geometry_info);
2599            if ((flags & PercentValue) != 0)
2600              geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2601            mogrify_image=SelectiveBlurImage(*image,geometry_info.rho,
2602              geometry_info.sigma,geometry_info.xi,exception);
2603            break;
2604          }
2605        if (LocaleCompare("separate",option+1) == 0)
2606          {
2607            /*
2608              Break channels into separate images.
2609            */
2610            (void) SyncImageSettings(mogrify_info,*image,exception);
2611            mogrify_image=SeparateImages(*image,exception);
2612            break;
2613          }
2614        if (LocaleCompare("sepia-tone",option+1) == 0)
2615          {
2616            double
2617              threshold;
2618
2619            /*
2620              Sepia-tone image.
2621            */
2622            (void) SyncImageSettings(mogrify_info,*image,exception);
2623            threshold=StringToDoubleInterval(argv[i+1],(double) QuantumRange+
2624              1.0);
2625            mogrify_image=SepiaToneImage(*image,threshold,exception);
2626            break;
2627          }
2628        if (LocaleCompare("segment",option+1) == 0)
2629          {
2630            /*
2631              Segment image.
2632            */
2633            (void) SyncImageSettings(mogrify_info,*image,exception);
2634            flags=ParseGeometry(argv[i+1],&geometry_info);
2635            if ((flags & SigmaValue) == 0)
2636              geometry_info.sigma=1.0;
2637            (void) SegmentImage(*image,(*image)->colorspace,
2638              mogrify_info->verbose,geometry_info.rho,geometry_info.sigma,
2639              exception);
2640            break;
2641          }
2642        if (LocaleCompare("set",option+1) == 0)
2643          {
2644            char
2645              *value;
2646
2647            /*
2648              Set image option.
2649            */
2650            if (*option == '+')
2651              {
2652                if (LocaleNCompare(argv[i+1],"registry:",9) == 0)
2653                  (void) DeleteImageRegistry(argv[i+1]+9);
2654                else
2655                  if (LocaleNCompare(argv[i+1],"option:",7) == 0)
2656                    {
2657                      (void) DeleteImageOption(mogrify_info,argv[i+1]+7);
2658                      (void) DeleteImageArtifact(*image,argv[i+1]+7);
2659                    }
2660                  else
2661                    (void) DeleteImageProperty(*image,argv[i+1]);
2662                break;
2663              }
2664            value=InterpretImageProperties(mogrify_info,*image,argv[i+2],
2665              exception);
2666            if (value == (char *) NULL)
2667              break;
2668            if (LocaleNCompare(argv[i+1],"registry:",9) == 0)
2669              (void) SetImageRegistry(StringRegistryType,argv[i+1]+9,value,
2670                exception);
2671            else
2672              if (LocaleNCompare(argv[i+1],"option:",7) == 0)
2673                {
2674                  (void) SetImageOption(image_info,argv[i+1]+7,value);
2675                  (void) SetImageOption(mogrify_info,argv[i+1]+7,value);
2676                  (void) SetImageArtifact(*image,argv[i+1]+7,value);
2677                }
2678              else
2679                (void) SetImageProperty(*image,argv[i+1],value,exception);
2680            value=DestroyString(value);
2681            break;
2682          }
2683        if (LocaleCompare("shade",option+1) == 0)
2684          {
2685            /*
2686              Shade image.
2687            */
2688            (void) SyncImageSettings(mogrify_info,*image,exception);
2689            flags=ParseGeometry(argv[i+1],&geometry_info);
2690            if ((flags & SigmaValue) == 0)
2691              geometry_info.sigma=1.0;
2692            mogrify_image=ShadeImage(*image,(*option == '-') ? MagickTrue :
2693              MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
2694            break;
2695          }
2696        if (LocaleCompare("shadow",option+1) == 0)
2697          {
2698            /*
2699              Shadow image.
2700            */
2701            (void) SyncImageSettings(mogrify_info,*image,exception);
2702            flags=ParseGeometry(argv[i+1],&geometry_info);
2703            if ((flags & SigmaValue) == 0)
2704              geometry_info.sigma=1.0;
2705            if ((flags & XiValue) == 0)
2706              geometry_info.xi=4.0;
2707            if ((flags & PsiValue) == 0)
2708              geometry_info.psi=4.0;
2709            mogrify_image=ShadowImage(*image,geometry_info.rho,
2710              geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),
2711              (ssize_t) ceil(geometry_info.psi-0.5),exception);
2712            break;
2713          }
2714        if (LocaleCompare("sharpen",option+1) == 0)
2715          {
2716            /*
2717              Sharpen image.
2718            */
2719            (void) SyncImageSettings(mogrify_info,*image,exception);
2720            flags=ParseGeometry(argv[i+1],&geometry_info);
2721            if ((flags & SigmaValue) == 0)
2722              geometry_info.sigma=1.0;
2723            if ((flags & XiValue) == 0)
2724              geometry_info.xi=0.0;
2725            mogrify_image=SharpenImage(*image,geometry_info.rho,
2726              geometry_info.sigma,exception);
2727            break;
2728          }
2729        if (LocaleCompare("shave",option+1) == 0)
2730          {
2731            /*
2732              Shave the image edges.
2733            */
2734            (void) SyncImageSettings(mogrify_info,*image,exception);
2735            flags=ParsePageGeometry(*image,argv[i+1],&geometry,exception);
2736            mogrify_image=ShaveImage(*image,&geometry,exception);
2737            break;
2738          }
2739        if (LocaleCompare("shear",option+1) == 0)
2740          {
2741            /*
2742              Shear image.
2743            */
2744            (void) SyncImageSettings(mogrify_info,*image,exception);
2745            flags=ParseGeometry(argv[i+1],&geometry_info);
2746            if ((flags & SigmaValue) == 0)
2747              geometry_info.sigma=geometry_info.rho;
2748            mogrify_image=ShearImage(*image,geometry_info.rho,
2749              geometry_info.sigma,exception);
2750            break;
2751          }
2752        if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
2753          {
2754            /*
2755              Sigmoidal non-linearity contrast control.
2756            */
2757            (void) SyncImageSettings(mogrify_info,*image,exception);
2758            flags=ParseGeometry(argv[i+1],&geometry_info);
2759            if ((flags & SigmaValue) == 0)
2760              geometry_info.sigma=(double) QuantumRange/2.0;
2761            if ((flags & PercentValue) != 0)
2762              geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
2763                100.0;
2764            (void) SigmoidalContrastImage(*image,(*option == '-') ?
2765              MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
2766              exception);
2767            break;
2768          }
2769        if (LocaleCompare("sketch",option+1) == 0)
2770          {
2771            /*
2772              Sketch image.
2773            */
2774            (void) SyncImageSettings(mogrify_info,*image,exception);
2775            flags=ParseGeometry(argv[i+1],&geometry_info);
2776            if ((flags & SigmaValue) == 0)
2777              geometry_info.sigma=1.0;
2778            mogrify_image=SketchImage(*image,geometry_info.rho,
2779              geometry_info.sigma,geometry_info.xi,exception);
2780            break;
2781          }
2782        if (LocaleCompare("solarize",option+1) == 0)
2783          {
2784            double
2785              threshold;
2786
2787            (void) SyncImageSettings(mogrify_info,*image,exception);
2788            threshold=StringToDoubleInterval(argv[i+1],(double) QuantumRange+
2789              1.0);
2790            (void) SolarizeImage(*image,threshold,exception);
2791            break;
2792          }
2793        if (LocaleCompare("sparse-color",option+1) == 0)
2794          {
2795            SparseColorMethod
2796              method;
2797
2798            char
2799              *arguments;
2800
2801            /*
2802              Sparse Color Interpolated Gradient
2803            */
2804            (void) SyncImageSettings(mogrify_info,*image,exception);
2805            method=(SparseColorMethod) ParseCommandOption(
2806              MagickSparseColorOptions,MagickFalse,argv[i+1]);
2807            arguments=InterpretImageProperties(mogrify_info,*image,argv[i+2],
2808              exception);
2809            if (arguments == (char *) NULL)
2810              break;
2811            mogrify_image=SparseColorOption(*image,method,arguments,
2812              option[0] == '+' ? MagickTrue : MagickFalse,exception);
2813            arguments=DestroyString(arguments);
2814            break;
2815          }
2816        if (LocaleCompare("splice",option+1) == 0)
2817          {
2818            /*
2819              Splice a solid color into the image.
2820            */
2821            (void) SyncImageSettings(mogrify_info,*image,exception);
2822            (void) ParseGravityGeometry(*image,argv[i+1],&geometry,exception);
2823            mogrify_image=SpliceImage(*image,&geometry,exception);
2824            break;
2825          }
2826        if (LocaleCompare("spread",option+1) == 0)
2827          {
2828            /*
2829              Spread an image.
2830            */
2831            (void) SyncImageSettings(mogrify_info,*image,exception);
2832            (void) ParseGeometry(argv[i+1],&geometry_info);
2833            mogrify_image=SpreadImage(*image,geometry_info.rho,
2834              interpolate_method,exception);
2835            break;
2836          }
2837        if (LocaleCompare("statistic",option+1) == 0)
2838          {
2839            StatisticType
2840              type;
2841
2842            (void) SyncImageSettings(mogrify_info,*image,exception);
2843            type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
2844              MagickFalse,argv[i+1]);
2845            (void) ParseGeometry(argv[i+2],&geometry_info);
2846            mogrify_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
2847              (size_t) geometry_info.sigma,exception);
2848            break;
2849          }
2850        if (LocaleCompare("stretch",option+1) == 0)
2851          {
2852            if (*option == '+')
2853              {
2854                draw_info->stretch=UndefinedStretch;
2855                break;
2856              }
2857            draw_info->stretch=(StretchType) ParseCommandOption(
2858              MagickStretchOptions,MagickFalse,argv[i+1]);
2859            break;
2860          }
2861        if (LocaleCompare("strip",option+1) == 0)
2862          {
2863            /*
2864              Strip image of profiles and comments.
2865            */
2866            (void) SyncImageSettings(mogrify_info,*image,exception);
2867            (void) StripImage(*image,exception);
2868            break;
2869          }
2870        if (LocaleCompare("stroke",option+1) == 0)
2871          {
2872            ExceptionInfo
2873              *sans;
2874
2875            PixelInfo
2876              color;
2877
2878            if (*option == '+')
2879              {
2880                (void) QueryColorCompliance("none",AllCompliance,
2881                  &draw_info->stroke,exception);
2882                if (draw_info->stroke_pattern != (Image *) NULL)
2883                  draw_info->stroke_pattern=DestroyImage(
2884                    draw_info->stroke_pattern);
2885                break;
2886              }
2887            sans=AcquireExceptionInfo();
2888            status=QueryColorCompliance(argv[i+1],AllCompliance,&color,sans);
2889            sans=DestroyExceptionInfo(sans);
2890            if (status == MagickFalse)
2891              draw_info->stroke_pattern=GetImageCache(mogrify_info,argv[i+1],
2892                exception);
2893            else
2894              draw_info->stroke=color;
2895            break;
2896          }
2897        if (LocaleCompare("strokewidth",option+1) == 0)
2898          {
2899            draw_info->stroke_width=StringToDouble(argv[i+1],(char **) NULL);
2900            break;
2901          }
2902        if (LocaleCompare("style",option+1) == 0)
2903          {
2904            if (*option == '+')
2905              {
2906                draw_info->style=UndefinedStyle;
2907                break;
2908              }
2909            draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
2910              MagickFalse,argv[i+1]);
2911            break;
2912          }
2913        if (LocaleCompare("swirl",option+1) == 0)
2914          {
2915            /*
2916              Swirl image.
2917            */
2918            (void) SyncImageSettings(mogrify_info,*image,exception);
2919            (void) ParseGeometry(argv[i+1],&geometry_info);
2920            mogrify_image=SwirlImage(*image,geometry_info.rho,
2921              interpolate_method,exception);
2922            break;
2923          }
2924        break;
2925      }
2926      case 't':
2927      {
2928        if (LocaleCompare("threshold",option+1) == 0)
2929          {
2930            double
2931              threshold;
2932
2933            /*
2934              Threshold image.
2935            */
2936            (void) SyncImageSettings(mogrify_info,*image,exception);
2937            if (*option == '+')
2938              threshold=(double) QuantumRange/2;
2939            else
2940              threshold=StringToDoubleInterval(argv[i+1],(double) QuantumRange+
2941                1.0);
2942            (void) BilevelImage(*image,threshold,exception);
2943            break;
2944          }
2945        if (LocaleCompare("thumbnail",option+1) == 0)
2946          {
2947            /*
2948              Thumbnail image.
2949            */
2950            (void) SyncImageSettings(mogrify_info,*image,exception);
2951            (void) ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
2952            mogrify_image=ThumbnailImage(*image,geometry.width,geometry.height,
2953              exception);
2954            break;
2955          }
2956        if (LocaleCompare("tile",option+1) == 0)
2957          {
2958            if (*option == '+')
2959              {
2960                if (draw_info->fill_pattern != (Image *) NULL)
2961                  draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
2962                break;
2963              }
2964            draw_info->fill_pattern=GetImageCache(mogrify_info,argv[i+1],
2965              exception);
2966            break;
2967          }
2968        if (LocaleCompare("tint",option+1) == 0)
2969          {
2970            /*
2971              Tint the image.
2972            */
2973            (void) SyncImageSettings(mogrify_info,*image,exception);
2974            mogrify_image=TintImage(*image,argv[i+1],&fill,exception);
2975            break;
2976          }
2977        if (LocaleCompare("transform",option+1) == 0)
2978          {
2979            /*
2980              Affine transform image.
2981            */
2982            (void) SyncImageSettings(mogrify_info,*image,exception);
2983            mogrify_image=AffineTransformImage(*image,&draw_info->affine,
2984              exception);
2985            break;
2986          }
2987        if (LocaleCompare("transparent",option+1) == 0)
2988          {
2989            PixelInfo
2990              target;
2991
2992            (void) SyncImageSettings(mogrify_info,*image,exception);
2993            (void) QueryColorCompliance(argv[i+1],AllCompliance,&target,
2994              exception);
2995            (void) TransparentPaintImage(*image,&target,(Quantum)
2996              TransparentAlpha,*option == '-' ? MagickFalse : MagickTrue,
2997              exception);
2998            break;
2999          }
3000        if (LocaleCompare("transpose",option+1) == 0)
3001          {
3002            /*
3003              Transpose image scanlines.
3004            */
3005            (void) SyncImageSettings(mogrify_info,*image,exception);
3006            mogrify_image=TransposeImage(*image,exception);
3007            break;
3008          }
3009        if (LocaleCompare("transverse",option+1) == 0)
3010          {
3011            /*
3012              Transverse image scanlines.
3013            */
3014            (void) SyncImageSettings(mogrify_info,*image,exception);
3015            mogrify_image=TransverseImage(*image,exception);
3016            break;
3017          }
3018        if (LocaleCompare("treedepth",option+1) == 0)
3019          {
3020            quantize_info->tree_depth=StringToUnsignedLong(argv[i+1]);
3021            break;
3022          }
3023        if (LocaleCompare("trim",option+1) == 0)
3024          {
3025            /*
3026              Trim image.
3027            */
3028            (void) SyncImageSettings(mogrify_info,*image,exception);
3029            mogrify_image=TrimImage(*image,exception);
3030            break;
3031          }
3032        if (LocaleCompare("type",option+1) == 0)
3033          {
3034            ImageType
3035              type;
3036
3037            (void) SyncImageSettings(mogrify_info,*image,exception);
3038            if (*option == '+')
3039              type=UndefinedType;
3040            else
3041              type=(ImageType) ParseCommandOption(MagickTypeOptions,MagickFalse,
3042                argv[i+1]);
3043            (*image)->type=UndefinedType;
3044            (void) SetImageType(*image,type,exception);
3045            break;
3046          }
3047        break;
3048      }
3049      case 'u':
3050      {
3051        if (LocaleCompare("undercolor",option+1) == 0)
3052          {
3053            (void) QueryColorCompliance(argv[i+1],AllCompliance,
3054              &draw_info->undercolor,exception);
3055            break;
3056          }
3057        if (LocaleCompare("unique",option+1) == 0)
3058          {
3059            if (*option == '+')
3060              {
3061                (void) DeleteImageArtifact(*image,"identify:unique-colors");
3062                break;
3063              }
3064            (void) SetImageArtifact(*image,"identify:unique-colors","true");
3065            (void) SetImageArtifact(*image,"verbose","true");
3066            break;
3067          }
3068        if (LocaleCompare("unique-colors",option+1) == 0)
3069          {
3070            /*
3071              Unique image colors.
3072            */
3073            (void) SyncImageSettings(mogrify_info,*image,exception);
3074            mogrify_image=UniqueImageColors(*image,exception);
3075            break;
3076          }
3077        if (LocaleCompare("unsharp",option+1) == 0)
3078          {
3079            /*
3080              Unsharp mask image.
3081            */
3082            (void) SyncImageSettings(mogrify_info,*image,exception);
3083            flags=ParseGeometry(argv[i+1],&geometry_info);
3084            if ((flags & SigmaValue) == 0)
3085              geometry_info.sigma=1.0;
3086            if ((flags & XiValue) == 0)
3087              geometry_info.xi=1.0;
3088            if ((flags & PsiValue) == 0)
3089              geometry_info.psi=0.05;
3090            mogrify_image=UnsharpMaskImage(*image,geometry_info.rho,
3091              geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3092            break;
3093          }
3094        break;
3095      }
3096      case 'v':
3097      {
3098        if (LocaleCompare("verbose",option+1) == 0)
3099          {
3100            (void) SetImageArtifact(*image,option+1,
3101              *option == '+' ? "false" : "true");
3102            break;
3103          }
3104        if (LocaleCompare("vignette",option+1) == 0)
3105          {
3106            /*
3107              Vignette image.
3108            */
3109            (void) SyncImageSettings(mogrify_info,*image,exception);
3110            flags=ParseGeometry(argv[i+1],&geometry_info);
3111            if ((flags & SigmaValue) == 0)
3112              geometry_info.sigma=1.0;
3113            if ((flags & XiValue) == 0)
3114              geometry_info.xi=0.1*(*image)->columns;
3115            if ((flags & PsiValue) == 0)
3116              geometry_info.psi=0.1*(*image)->rows;
3117            mogrify_image=VignetteImage(*image,geometry_info.rho,
3118              geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),
3119              (ssize_t) ceil(geometry_info.psi-0.5),exception);
3120            break;
3121          }
3122        if (LocaleCompare("virtual-pixel",option+1) == 0)
3123          {
3124            if (*option == '+')
3125              {
3126                (void) SetImageVirtualPixelMethod(*image,
3127                  UndefinedVirtualPixelMethod,exception);
3128                break;
3129              }
3130            (void) SetImageVirtualPixelMethod(*image,(VirtualPixelMethod)
3131              ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
3132              argv[i+1]),exception);
3133            break;
3134          }
3135        break;
3136      }
3137      case 'w':
3138      {
3139        if (LocaleCompare("wave",option+1) == 0)
3140          {
3141            /*
3142              Wave image.
3143            */
3144            (void) SyncImageSettings(mogrify_info,*image,exception);
3145            flags=ParseGeometry(argv[i+1],&geometry_info);
3146            if ((flags & SigmaValue) == 0)
3147              geometry_info.sigma=1.0;
3148            mogrify_image=WaveImage(*image,geometry_info.rho,
3149              geometry_info.sigma,interpolate_method,exception);
3150            break;
3151          }
3152        if (LocaleCompare("weight",option+1) == 0)
3153          {
3154            draw_info->weight=StringToUnsignedLong(argv[i+1]);
3155            if (LocaleCompare(argv[i+1],"all") == 0)
3156              draw_info->weight=0;
3157            if (LocaleCompare(argv[i+1],"bold") == 0)
3158              draw_info->weight=700;
3159            if (LocaleCompare(argv[i+1],"bolder") == 0)
3160              if (draw_info->weight <= 800)
3161                draw_info->weight+=100;
3162            if (LocaleCompare(argv[i+1],"lighter") == 0)
3163              if (draw_info->weight >= 100)
3164                draw_info->weight-=100;
3165            if (LocaleCompare(argv[i+1],"normal") == 0)
3166              draw_info->weight=400;
3167            break;
3168          }
3169        if (LocaleCompare("white-threshold",option+1) == 0)
3170          {
3171            /*
3172              White threshold image.
3173            */
3174            (void) SyncImageSettings(mogrify_info,*image,exception);
3175            (void) WhiteThresholdImage(*image,argv[i+1],exception);
3176            break;
3177          }
3178        break;
3179      }
3180      default:
3181        break;
3182    }
3183    /*
3184       Replace current image with any image that was generated
3185    */
3186    if (mogrify_image != (Image *) NULL)
3187      ReplaceImageInListReturnLast(image,mogrify_image);
3188    i+=count;
3189  }
3190  if (region_image != (Image *) NULL)
3191    {
3192      /*
3193        Composite transformed region onto image.
3194      */
3195      (void) SyncImageSettings(mogrify_info,*image,exception);
3196      (void) CompositeImage(region_image,*image,region_image->matte !=
3197         MagickFalse ? CopyCompositeOp : OverCompositeOp,MagickTrue,
3198         region_geometry.x,region_geometry.y,exception);
3199      *image=DestroyImage(*image);
3200      *image=region_image;
3201      region_image = (Image *) NULL;
3202    }
3203  /*
3204    Free resources.
3205  */
3206  quantize_info=DestroyQuantizeInfo(quantize_info);
3207  draw_info=DestroyDrawInfo(draw_info);
3208  mogrify_info=DestroyImageInfo(mogrify_info);
3209  status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
3210  return(status == 0 ? MagickFalse : MagickTrue);
3211}
3212
3213/*
3214%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3215%                                                                             %
3216%                                                                             %
3217%                                                                             %
3218+    M o g r i f y I m a g e C o m m a n d                                    %
3219%                                                                             %
3220%                                                                             %
3221%                                                                             %
3222%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3223%
3224%  MogrifyImageCommand() transforms an image or a sequence of images. These
3225%  transforms include image scaling, image rotation, color reduction, and
3226%  others. The transmogrified image overwrites the original image.
3227%
3228%  The format of the MogrifyImageCommand method is:
3229%
3230%      MagickBooleanType MogrifyImageCommand(ImageInfo *image_info,int argc,
3231%        const char **argv,char **metadata,ExceptionInfo *exception)
3232%
3233%  A description of each parameter follows:
3234%
3235%    o image_info: the image info.
3236%
3237%    o argc: the number of elements in the argument vector.
3238%
3239%    o argv: A text array containing the command line arguments.
3240%
3241%    o metadata: any metadata is returned here.
3242%
3243%    o exception: return any errors or warnings in this structure.
3244%
3245*/
3246
3247static MagickBooleanType MogrifyUsage(void)
3248{
3249  static const char
3250    *channel_operators[]=
3251    {
3252      "-channel-fx expression",
3253      "                     exchange, extract, or transfer one or more image channels",
3254      "-separate            separate an image channel into a grayscale image",
3255      (char *) NULL
3256    },
3257    *miscellaneous[]=
3258    {
3259      "-debug events        display copious debugging information",
3260      "-help                print program options",
3261      "-list type           print a list of supported option arguments",
3262      "-log format          format of debugging information",
3263      "-version             print version information",
3264      (char *) NULL
3265    },
3266    *operators[]=
3267    {
3268      "-adaptive-blur geometry",
3269      "                     adaptively blur pixels; decrease effect near edges",
3270      "-adaptive-resize geometry",
3271      "                     adaptively resize image using 'mesh' interpolation",
3272      "-adaptive-sharpen geometry",
3273      "                     adaptively sharpen pixels; increase effect near edges",
3274      "-alpha option        on, activate, off, deactivate, set, opaque, copy",
3275      "                     transparent, extract, background, or shape",
3276      "-annotate geometry text",
3277      "                     annotate the image with text",
3278      "-auto-gamma          automagically adjust gamma level of image",
3279      "-auto-level          automagically adjust color levels of image",
3280      "-auto-orient         automagically orient (rotate) image",
3281      "-bench iterations    measure performance",
3282      "-black-threshold value",
3283      "                     force all pixels below the threshold into black",
3284      "-blue-shift          simulate a scene at nighttime in the moonlight",
3285      "-blur geometry       reduce image noise and reduce detail levels",
3286      "-border geometry     surround image with a border of color",
3287      "-bordercolor color   border color",
3288      "-brightness-contrast geometry",
3289      "                     improve brightness / contrast of the image",
3290      "-cdl filename        color correct with a color decision list",
3291      "-charcoal geometry   simulate a charcoal drawing",
3292      "-chop geometry       remove pixels from the image interior",
3293      "-clamp               restrict pixel range from 0 to the quantum depth",
3294      "-clip                clip along the first path from the 8BIM profile",
3295      "-clip-mask filename  associate a clip mask with the image",
3296      "-clip-path id        clip along a named path from the 8BIM profile",
3297      "-colorize value      colorize the image with the fill color",
3298      "-color-matrix matrix apply color correction to the image",
3299      "-contrast            enhance or reduce the image contrast",
3300      "-contrast-stretch geometry",
3301      "                     improve contrast by 'stretching' the intensity range",
3302      "-convolve coefficients",
3303      "                     apply a convolution kernel to the image",
3304      "-cycle amount        cycle the image colormap",
3305      "-decipher filename   convert cipher pixels to plain pixels",
3306      "-deskew threshold    straighten an image",
3307      "-despeckle           reduce the speckles within an image",
3308      "-distort method args",
3309      "                     distort images according to given method ad args",
3310      "-draw string         annotate the image with a graphic primitive",
3311      "-edge radius         apply a filter to detect edges in the image",
3312      "-encipher filename   convert plain pixels to cipher pixels",
3313      "-emboss radius       emboss an image",
3314      "-enhance             apply a digital filter to enhance a noisy image",
3315      "-equalize            perform histogram equalization to an image",
3316      "-evaluate operator value",
3317      "                     evaluate an arithmetic, relational, or logical expression",
3318      "-extent geometry     set the image size",
3319      "-extract geometry    extract area from image",
3320      "-fft                 implements the discrete Fourier transform (DFT)",
3321      "-flip                flip image vertically",
3322      "-floodfill geometry color",
3323      "                     floodfill the image with color",
3324      "-flop                flop image horizontally",
3325      "-frame geometry      surround image with an ornamental border",
3326      "-function name parameters",
3327      "                     apply function over image values",
3328      "-gamma value         level of gamma correction",
3329      "-gaussian-blur geometry",
3330      "                     reduce image noise and reduce detail levels",
3331      "-geometry geometry   preferred size or location of the image",
3332      "-identify            identify the format and characteristics of the image",
3333      "-ift                 implements the inverse discrete Fourier transform (DFT)",
3334      "-implode amount      implode image pixels about the center",
3335      "-interpolative-resize geometry",
3336      "                     resize image using interpolation",
3337      "-lat geometry        local adaptive thresholding",
3338      "-layers method       optimize, merge,  or compare image layers",
3339      "-level value         adjust the level of image contrast",
3340      "-level-colors color,color",
3341      "                     level image with the given colors",
3342      "-linear-stretch geometry",
3343      "                     improve contrast by 'stretching with saturation'",
3344      "-liquid-rescale geometry",
3345      "                     rescale image with seam-carving",
3346      "-median geometry     apply a median filter to the image",
3347      "-mode geometry       make each pixel the 'predominant color' of the neighborhood",
3348      "-modulate value      vary the brightness, saturation, and hue",
3349      "-monochrome          transform image to black and white",
3350      "-morphology method kernel",
3351      "                     apply a morphology method to the image",
3352      "-motion-blur geometry",
3353      "                     simulate motion blur",
3354      "-negate              replace every pixel with its complementary color ",
3355      "-noise geometry      add or reduce noise in an image",
3356      "-normalize           transform image to span the full range of colors",
3357      "-opaque color        change this color to the fill color",
3358      "-ordered-dither NxN",
3359      "                     add a noise pattern to the image with specific",
3360      "                     amplitudes",
3361      "-paint radius        simulate an oil painting",
3362      "-polaroid angle      simulate a Polaroid picture",
3363      "-posterize levels    reduce the image to a limited number of color levels",
3364      "-profile filename    add, delete, or apply an image profile",
3365      "-quantize colorspace reduce colors in this colorspace",
3366      "-radial-blur angle   radial blur the image",
3367      "-raise value         lighten/darken image edges to create a 3-D effect",
3368      "-random-threshold low,high",
3369      "                     random threshold the image",
3370      "-region geometry     apply options to a portion of the image",
3371      "-render              render vector graphics",
3372      "-repage geometry     size and location of an image canvas",
3373      "-resample geometry   change the resolution of an image",
3374      "-resize geometry     resize the image",
3375      "-roll geometry       roll an image vertically or horizontally",
3376      "-rotate degrees      apply Paeth rotation to the image",
3377      "-sample geometry     scale image with pixel sampling",
3378      "-scale geometry      scale the image",
3379      "-segment values      segment an image",
3380      "-selective-blur geometry",
3381      "                     selectively blur pixels within a contrast threshold",
3382      "-sepia-tone threshold",
3383      "                     simulate a sepia-toned photo",
3384      "-set property value  set an image property",
3385      "-shade degrees       shade the image using a distant light source",
3386      "-shadow geometry     simulate an image shadow",
3387      "-sharpen geometry    sharpen the image",
3388      "-shave geometry      shave pixels from the image edges",
3389      "-shear geometry      slide one edge of the image along the X or Y axis",
3390      "-sigmoidal-contrast geometry",
3391      "                     increase the contrast without saturating highlights or shadows",
3392      "-sketch geometry     simulate a pencil sketch",
3393      "-solarize threshold  negate all pixels above the threshold level",
3394      "-sparse-color method args",
3395      "                     fill in a image based on a few color points",
3396      "-splice geometry     splice the background color into the image",
3397      "-spread radius       displace image pixels by a random amount",
3398      "-statistic type radius",
3399      "                     replace each pixel with corresponding statistic from the neighborhood",
3400      "-strip               strip image of all profiles and comments",
3401      "-swirl degrees       swirl image pixels about the center",
3402      "-threshold value     threshold the image",
3403      "-thumbnail geometry  create a thumbnail of the image",
3404      "-tile filename       tile image when filling a graphic primitive",
3405      "-tint value          tint the image with the fill color",
3406      "-transform           affine transform image",
3407      "-transparent color   make this color transparent within the image",
3408      "-transpose           flip image vertically and rotate 90 degrees",
3409      "-transverse          flop image horizontally and rotate 270 degrees",
3410      "-trim                trim image edges",
3411      "-type type           image type",
3412      "-unique-colors       discard all but one of any pixel color",
3413      "-unsharp geometry    sharpen the image",
3414      "-vignette geometry   soften the edges of the image in vignette style",
3415      "-wave geometry       alter an image along a sine wave",
3416      "-white-threshold value",
3417      "                     force all pixels above the threshold into white",
3418      (char *) NULL
3419    },
3420    *sequence_operators[]=
3421    {
3422      "-append              append an image sequence",
3423      "-clut                apply a color lookup table to the image",
3424      "-coalesce            merge a sequence of images",
3425      "-combine             combine a sequence of images",
3426      "-composite           composite image",
3427      "-crop geometry       cut out a rectangular region of the image",
3428      "-deconstruct         break down an image sequence into constituent parts",
3429      "-evaluate-sequence operator",
3430      "                     evaluate an arithmetic, relational, or logical expression",
3431      "-flatten             flatten a sequence of images",
3432      "-fx expression       apply mathematical expression to an image channel(s)",
3433      "-hald-clut           apply a Hald color lookup table to the image",
3434      "-morph value         morph an image sequence",
3435      "-mosaic              create a mosaic from an image sequence",
3436      "-print string        interpret string and print to console",
3437      "-process arguments   process the image with a custom image filter",
3438      "-smush geometry      smush an image sequence together",
3439      "-write filename      write images to this file",
3440      (char *) NULL
3441    },
3442    *settings[]=
3443    {
3444      "-adjoin              join images into a single multi-image file",
3445      "-affine matrix       affine transform matrix",
3446      "-alpha option        activate, deactivate, reset, or set the alpha channel",
3447      "-antialias           remove pixel-aliasing",
3448      "-authenticate password",
3449      "                     decipher image with this password",
3450      "-attenuate value     lessen (or intensify) when adding noise to an image",
3451      "-background color    background color",
3452      "-bias value          add bias when convolving an image",
3453      "-black-point-compensation",
3454      "                     use black point compensation",
3455      "-blue-primary point  chromaticity blue primary point",
3456      "-bordercolor color   border color",
3457      "-caption string      assign a caption to an image",
3458      "-channel type        apply option to select image channels",
3459      "-colors value        preferred number of colors in the image",
3460      "-colorspace type     alternate image colorspace",
3461      "-comment string      annotate image with comment",
3462      "-compose operator    set image composite operator",
3463      "-compress type       type of pixel compression when writing the image",
3464      "-define format:option=value",
3465      "                     define one or more image format options",
3466      "-delay value         display the next image after pausing",
3467      "-density geometry    horizontal and vertical density of the image",
3468      "-depth value         image depth",
3469      "-direction type      render text right-to-left or left-to-right",
3470      "-display server      get image or font from this X server",
3471      "-dispose method      layer disposal method",
3472      "-dither method       apply error diffusion to image",
3473      "-encoding type       text encoding type",
3474      "-endian type         endianness (MSB or LSB) of the image",
3475      "-family name         render text with this font family",
3476      "-features distance   analyze image features (e.g. contrast, correlation)",
3477      "-fill color          color to use when filling a graphic primitive",
3478      "-filter type         use this filter when resizing an image",
3479      "-font name           render text with this font",
3480      "-format \"string\"   output formatted image characteristics",
3481      "-fuzz distance       colors within this distance are considered equal",
3482      "-gravity type        horizontal and vertical text placement",
3483      "-green-primary point chromaticity green primary point",
3484      "-intent type         type of rendering intent when managing the image color",
3485      "-interlace type      type of image interlacing scheme",
3486      "-interline-spacing value",
3487      "                     set the space between two text lines",
3488      "-interpolate method  pixel color interpolation method",
3489      "-interword-spacing value",
3490      "                     set the space between two words",
3491      "-kerning value       set the space between two letters",
3492      "-label string        assign a label to an image",
3493      "-limit type value    pixel cache resource limit",
3494      "-loop iterations     add Netscape loop extension to your GIF animation",
3495      "-mask filename       associate a mask with the image",
3496      "-mattecolor color    frame color",
3497      "-monitor             monitor progress",
3498      "-orient type         image orientation",
3499      "-page geometry       size and location of an image canvas (setting)",
3500      "-ping                efficiently determine image attributes",
3501      "-pointsize value     font point size",
3502      "-precision value     maximum number of significant digits to print",
3503      "-preview type        image preview type",
3504      "-quality value       JPEG/MIFF/PNG compression level",
3505      "-quiet               suppress all warning messages",
3506      "-red-primary point   chromaticity red primary point",
3507      "-regard-warnings     pay attention to warning messages",
3508      "-remap filename      transform image colors to match this set of colors",
3509      "-respect-parentheses settings remain in effect until parenthesis boundary",
3510      "-sampling-factor geometry",
3511      "                     horizontal and vertical sampling factor",
3512      "-scene value         image scene number",
3513      "-seed value          seed a new sequence of pseudo-random numbers",
3514      "-size geometry       width and height of image",
3515      "-stretch type        render text with this font stretch",
3516      "-stroke color        graphic primitive stroke color",
3517      "-strokewidth value   graphic primitive stroke width",
3518      "-style type          render text with this font style",
3519      "-synchronize         synchronize image to storage device",
3520      "-taint               declare the image as modified",
3521      "-texture filename    name of texture to tile onto the image background",
3522      "-tile-offset geometry",
3523      "                     tile offset",
3524      "-treedepth value     color tree depth",
3525      "-transparent-color color",
3526      "                     transparent color",
3527      "-undercolor color    annotation bounding box color",
3528      "-units type          the units of image resolution",
3529      "-verbose             print detailed information about the image",
3530      "-view                FlashPix viewing transforms",
3531      "-virtual-pixel method",
3532      "                     virtual pixel access method",
3533      "-weight type         render text with this font weight",
3534      "-white-point point   chromaticity white point",
3535      (char *) NULL
3536    },
3537    *stack_operators[]=
3538    {
3539      "-delete indexes      delete the image from the image sequence",
3540      "-duplicate count,indexes",
3541      "                     duplicate an image one or more times",
3542      "-insert index        insert last image into the image sequence",
3543      "-reverse             reverse image sequence",
3544      "-swap indexes        swap two images in the image sequence",
3545      (char *) NULL
3546    };
3547
3548  const char
3549    **p;
3550
3551  (void) printf("Version: %s\n",GetMagickVersion((size_t *) NULL));
3552  (void) printf("Copyright: %s\n",GetMagickCopyright());
3553  (void) printf("Features: %s\n\n",GetMagickFeatures());
3554  (void) printf("Usage: %s [options ...] file [ [options ...] file ...]\n",
3555    GetClientName());
3556  (void) printf("\nImage Settings:\n");
3557  for (p=settings; *p != (char *) NULL; p++)
3558    (void) printf("  %s\n",*p);
3559  (void) printf("\nImage Operators:\n");
3560  for (p=operators; *p != (char *) NULL; p++)
3561    (void) printf("  %s\n",*p);
3562  (void) printf("\nImage Channel Operators:\n");
3563  for (p=channel_operators; *p != (char *) NULL; p++)
3564    (void) printf("  %s\n",*p);
3565  (void) printf("\nImage Sequence Operators:\n");
3566  for (p=sequence_operators; *p != (char *) NULL; p++)
3567    (void) printf("  %s\n",*p);
3568  (void) printf("\nImage Stack Operators:\n");
3569  for (p=stack_operators; *p != (char *) NULL; p++)
3570    (void) printf("  %s\n",*p);
3571  (void) printf("\nMiscellaneous Options:\n");
3572  for (p=miscellaneous; *p != (char *) NULL; p++)
3573    (void) printf("  %s\n",*p);
3574  (void) printf(
3575    "\nBy default, the image format of 'file' is determined by its magic\n");
3576  (void) printf(
3577    "number.  To specify a particular image format, precede the filename\n");
3578  (void) printf(
3579    "with an image format name and a colon (i.e. ps:image) or specify the\n");
3580  (void) printf(
3581    "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
3582  (void) printf("'-' for standard input or output.\n");
3583  return(MagickFalse);
3584}
3585
3586WandExport MagickBooleanType MogrifyImageCommand(ImageInfo *image_info,
3587  int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception)
3588{
3589#define DestroyMogrify() \
3590{ \
3591  if (format != (char *) NULL) \
3592    format=DestroyString(format); \
3593  if (path != (char *) NULL) \
3594    path=DestroyString(path); \
3595  DestroyImageStack(); \
3596  for (i=0; i < (ssize_t) argc; i++) \
3597    argv[i]=DestroyString(argv[i]); \
3598  argv=(char **) RelinquishMagickMemory(argv); \
3599}
3600#define ThrowMogrifyException(asperity,tag,option) \
3601{ \
3602  (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"'%s'", \
3603    option); \
3604  DestroyMogrify(); \
3605  return(MagickFalse); \
3606}
3607#define ThrowMogrifyInvalidArgumentException(option,argument) \
3608{ \
3609  (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
3610    "InvalidArgument","'%s': %s",argument,option); \
3611  DestroyMogrify(); \
3612  return(MagickFalse); \
3613}
3614
3615  char
3616    *format,
3617    *option,
3618    *path;
3619
3620  Image
3621    *image;
3622
3623  ImageStack
3624    image_stack[MaxImageStackDepth+1];
3625
3626  MagickBooleanType
3627    global_colormap;
3628
3629  MagickBooleanType
3630    fire,
3631    pend,
3632    respect_parenthesis;
3633
3634  MagickStatusType
3635    status;
3636
3637  register ssize_t
3638    i;
3639
3640  ssize_t
3641    j,
3642    k;
3643
3644  /*
3645    Set defaults.
3646  */
3647  assert(image_info != (ImageInfo *) NULL);
3648  assert(image_info->signature == MagickSignature);
3649  if (image_info->debug != MagickFalse)
3650    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3651  assert(exception != (ExceptionInfo *) NULL);
3652  if (argc == 2)
3653    {
3654      option=argv[1];
3655      if ((LocaleCompare("version",option+1) == 0) ||
3656          (LocaleCompare("-version",option+1) == 0))
3657        {
3658          (void) FormatLocaleFile(stdout,"Version: %s\n",
3659            GetMagickVersion((size_t *) NULL));
3660          (void) FormatLocaleFile(stdout,"Copyright: %s\n",
3661            GetMagickCopyright());
3662          (void) FormatLocaleFile(stdout,"Features: %s\n\n",
3663            GetMagickFeatures());
3664          return(MagickFalse);
3665        }
3666    }
3667  if (argc < 2)
3668    return(MogrifyUsage());
3669  format=(char *) NULL;
3670  path=(char *) NULL;
3671  global_colormap=MagickFalse;
3672  k=0;
3673  j=1;
3674  NewImageStack();
3675  option=(char *) NULL;
3676  pend=MagickFalse;
3677  respect_parenthesis=MagickFalse;
3678  status=MagickTrue;
3679  /*
3680    Parse command line.
3681  */
3682  ReadCommandlLine(argc,&argv);
3683  status=ExpandFilenames(&argc,&argv);
3684  if (status == MagickFalse)
3685    ThrowMogrifyException(ResourceLimitError,"MemoryAllocationFailed",
3686      GetExceptionMessage(errno));
3687  for (i=1; i < (ssize_t) argc; i++)
3688  {
3689    option=argv[i];
3690    if (LocaleCompare(option,"(") == 0)
3691      {
3692        FireImageStack(MagickFalse,MagickTrue,pend);
3693        if (k == MaxImageStackDepth)
3694          ThrowMogrifyException(OptionError,"ParenthesisNestedTooDeeply",
3695            option);
3696        PushImageStack();
3697        continue;
3698      }
3699    if (LocaleCompare(option,")") == 0)
3700      {
3701        FireImageStack(MagickFalse,MagickTrue,MagickTrue);
3702        if (k == 0)
3703          ThrowMogrifyException(OptionError,"UnableToParseExpression",option);
3704        PopImageStack();
3705        continue;
3706      }
3707    if (IsCommandOption(option) == MagickFalse)
3708      {
3709        char
3710          backup_filename[MaxTextExtent],
3711          *filename;
3712
3713        Image
3714          *images;
3715
3716        /*
3717          Option is a file name: begin by reading image from specified file.
3718        */
3719        FireImageStack(MagickFalse,MagickFalse,pend);
3720        filename=argv[i];
3721        if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1)))
3722          filename=argv[++i];
3723        images=ReadImages(image_info,filename,exception);
3724        status&=(images != (Image *) NULL) &&
3725          (exception->severity < ErrorException);
3726        if (images == (Image *) NULL)
3727          continue;
3728        if (format != (char *) NULL)
3729          (void) CopyMagickString(images->filename,images->magick_filename,
3730            MaxTextExtent);
3731        if (path != (char *) NULL)
3732          {
3733            GetPathComponent(option,TailPath,filename);
3734            (void) FormatLocaleString(images->filename,MaxTextExtent,"%s%c%s",
3735              path,*DirectorySeparator,filename);
3736          }
3737        if (format != (char *) NULL)
3738          AppendImageFormat(format,images->filename);
3739        AppendImageStack(images);
3740        FinalizeImageSettings(image_info,image,MagickFalse);
3741        if (global_colormap != MagickFalse)
3742          {
3743            QuantizeInfo
3744              *quantize_info;
3745
3746            quantize_info=AcquireQuantizeInfo(image_info);
3747            (void) RemapImages(quantize_info,images,(Image *) NULL,exception);
3748            quantize_info=DestroyQuantizeInfo(quantize_info);
3749          }
3750        *backup_filename='\0';
3751        if ((LocaleCompare(image->filename,"-") != 0) &&
3752            (IsPathWritable(image->filename) != MagickFalse))
3753          {
3754            register ssize_t
3755              i;
3756
3757            /*
3758              Rename image file as backup.
3759            */
3760            (void) CopyMagickString(backup_filename,image->filename,
3761              MaxTextExtent);
3762            for (i=0; i < 6; i++)
3763            {
3764              (void) ConcatenateMagickString(backup_filename,"~",MaxTextExtent);
3765              if (IsPathAccessible(backup_filename) == MagickFalse)
3766                break;
3767            }
3768            if ((IsPathAccessible(backup_filename) != MagickFalse) ||
3769                (rename_utf8(image->filename,backup_filename) != 0))
3770              *backup_filename='\0';
3771          }
3772        /*
3773          Write transmogrified image to disk.
3774        */
3775        image_info->synchronize=MagickTrue;
3776        status&=WriteImages(image_info,image,image->filename,exception);
3777        if ((status == MagickFalse) && (*backup_filename != '\0'))
3778          (void) remove_utf8(backup_filename);
3779        RemoveAllImageStack();
3780        continue;
3781      }
3782    pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
3783    switch (*(option+1))
3784    {
3785      case 'a':
3786      {
3787        if (LocaleCompare("adaptive-blur",option+1) == 0)
3788          {
3789            i++;
3790            if (i == (ssize_t) argc)
3791              ThrowMogrifyException(OptionError,"MissingArgument",option);
3792            if (IsGeometry(argv[i]) == MagickFalse)
3793              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3794            break;
3795          }
3796        if (LocaleCompare("adaptive-resize",option+1) == 0)
3797          {
3798            i++;
3799            if (i == (ssize_t) argc)
3800              ThrowMogrifyException(OptionError,"MissingArgument",option);
3801            if (IsGeometry(argv[i]) == MagickFalse)
3802              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3803            break;
3804          }
3805        if (LocaleCompare("adaptive-sharpen",option+1) == 0)
3806          {
3807            i++;
3808            if (i == (ssize_t) argc)
3809              ThrowMogrifyException(OptionError,"MissingArgument",option);
3810            if (IsGeometry(argv[i]) == MagickFalse)
3811              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3812            break;
3813          }
3814        if (LocaleCompare("affine",option+1) == 0)
3815          {
3816            if (*option == '+')
3817              break;
3818            i++;
3819            if (i == (ssize_t) argc)
3820              ThrowMogrifyException(OptionError,"MissingArgument",option);
3821            break;
3822          }
3823        if (LocaleCompare("alpha",option+1) == 0)
3824          {
3825            ssize_t
3826              type;
3827
3828            if (*option == '+')
3829              break;
3830            i++;
3831            if (i == (ssize_t) argc)
3832              ThrowMogrifyException(OptionError,"MissingArgument",option);
3833            type=ParseCommandOption(MagickAlphaOptions,MagickFalse,argv[i]);
3834            if (type < 0)
3835              ThrowMogrifyException(OptionError,"UnrecognizedAlphaChannelType",
3836                argv[i]);
3837            break;
3838          }
3839        if (LocaleCompare("annotate",option+1) == 0)
3840          {
3841            if (*option == '+')
3842              break;
3843            i++;
3844            if (i == (ssize_t) argc)
3845              ThrowMogrifyException(OptionError,"MissingArgument",option);
3846            if (IsGeometry(argv[i]) == MagickFalse)
3847              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3848            if (i == (ssize_t) argc)
3849              ThrowMogrifyException(OptionError,"MissingArgument",option);
3850            i++;
3851            break;
3852          }
3853        if (LocaleCompare("antialias",option+1) == 0)
3854          break;
3855        if (LocaleCompare("append",option+1) == 0)
3856          break;
3857        if (LocaleCompare("attenuate",option+1) == 0)
3858          {
3859            if (*option == '+')
3860              break;
3861            i++;
3862            if (i == (ssize_t) (argc-1))
3863              ThrowMogrifyException(OptionError,"MissingArgument",option);
3864            if (IsGeometry(argv[i]) == MagickFalse)
3865              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3866            break;
3867          }
3868        if (LocaleCompare("authenticate",option+1) == 0)
3869          {
3870            if (*option == '+')
3871              break;
3872            i++;
3873            if (i == (ssize_t) argc)
3874              ThrowMogrifyException(OptionError,"MissingArgument",option);
3875            break;
3876          }
3877        if (LocaleCompare("auto-gamma",option+1) == 0)
3878          break;
3879        if (LocaleCompare("auto-level",option+1) == 0)
3880          break;
3881        if (LocaleCompare("auto-orient",option+1) == 0)
3882          break;
3883        if (LocaleCompare("average",option+1) == 0)
3884          break;
3885        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
3886      }
3887      case 'b':
3888      {
3889        if (LocaleCompare("background",option+1) == 0)
3890          {
3891            if (*option == '+')
3892              break;
3893            i++;
3894            if (i == (ssize_t) argc)
3895              ThrowMogrifyException(OptionError,"MissingArgument",option);
3896            break;
3897          }
3898        if (LocaleCompare("bias",option+1) == 0)
3899          {
3900            if (*option == '+')
3901              break;
3902            i++;
3903            if (i == (ssize_t) (argc-1))
3904              ThrowMogrifyException(OptionError,"MissingArgument",option);
3905            if (IsGeometry(argv[i]) == MagickFalse)
3906              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3907            break;
3908          }
3909        if (LocaleCompare("black-point-compensation",option+1) == 0)
3910          break;
3911        if (LocaleCompare("black-threshold",option+1) == 0)
3912          {
3913            if (*option == '+')
3914              break;
3915            i++;
3916            if (i == (ssize_t) argc)
3917              ThrowMogrifyException(OptionError,"MissingArgument",option);
3918            if (IsGeometry(argv[i]) == MagickFalse)
3919              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3920            break;
3921          }
3922        if (LocaleCompare("blue-primary",option+1) == 0)
3923          {
3924            if (*option == '+')
3925              break;
3926            i++;
3927            if (i == (ssize_t) argc)
3928              ThrowMogrifyException(OptionError,"MissingArgument",option);
3929            if (IsGeometry(argv[i]) == MagickFalse)
3930              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3931            break;
3932          }
3933        if (LocaleCompare("blue-shift",option+1) == 0)
3934          {
3935            i++;
3936            if (i == (ssize_t) argc)
3937              ThrowMogrifyException(OptionError,"MissingArgument",option);
3938            if (IsGeometry(argv[i]) == MagickFalse)
3939              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3940            break;
3941          }
3942        if (LocaleCompare("blur",option+1) == 0)
3943          {
3944            i++;
3945            if (i == (ssize_t) argc)
3946              ThrowMogrifyException(OptionError,"MissingArgument",option);
3947            if (IsGeometry(argv[i]) == MagickFalse)
3948              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3949            break;
3950          }
3951        if (LocaleCompare("border",option+1) == 0)
3952          {
3953            if (*option == '+')
3954              break;
3955            i++;
3956            if (i == (ssize_t) argc)
3957              ThrowMogrifyException(OptionError,"MissingArgument",option);
3958            if (IsGeometry(argv[i]) == MagickFalse)
3959              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3960            break;
3961          }
3962        if (LocaleCompare("bordercolor",option+1) == 0)
3963          {
3964            if (*option == '+')
3965              break;
3966            i++;
3967            if (i == (ssize_t) argc)
3968              ThrowMogrifyException(OptionError,"MissingArgument",option);
3969            break;
3970          }
3971        if (LocaleCompare("box",option+1) == 0)
3972          {
3973            if (*option == '+')
3974              break;
3975            i++;
3976            if (i == (ssize_t) argc)
3977              ThrowMogrifyException(OptionError,"MissingArgument",option);
3978            break;
3979          }
3980        if (LocaleCompare("brightness-contrast",option+1) == 0)
3981          {
3982            i++;
3983            if (i == (ssize_t) argc)
3984              ThrowMogrifyException(OptionError,"MissingArgument",option);
3985            if (IsGeometry(argv[i]) == MagickFalse)
3986              ThrowMogrifyInvalidArgumentException(option,argv[i]);
3987            break;
3988          }
3989        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
3990      }
3991      case 'c':
3992      {
3993        if (LocaleCompare("cache",option+1) == 0)
3994          {
3995            if (*option == '+')
3996              break;
3997            i++;
3998            if (i == (ssize_t) argc)
3999              ThrowMogrifyException(OptionError,"MissingArgument",option);
4000            if (IsGeometry(argv[i]) == MagickFalse)
4001              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4002            break;
4003          }
4004        if (LocaleCompare("caption",option+1) == 0)
4005          {
4006            if (*option == '+')
4007              break;
4008            i++;
4009            if (i == (ssize_t) argc)
4010              ThrowMogrifyException(OptionError,"MissingArgument",option);
4011            break;
4012          }
4013        if (LocaleCompare("channel",option+1) == 0)
4014          {
4015            ssize_t
4016              channel;
4017
4018            if (*option == '+')
4019              break;
4020            i++;
4021            if (i == (ssize_t) (argc-1))
4022              ThrowMogrifyException(OptionError,"MissingArgument",option);
4023            channel=ParseChannelOption(argv[i]);
4024            if (channel < 0)
4025              ThrowMogrifyException(OptionError,"UnrecognizedChannelType",
4026                argv[i]);
4027            break;
4028          }
4029        if (LocaleCompare("channel-fx",option+1) == 0)
4030          {
4031            ssize_t
4032              channel;
4033
4034            if (*option == '+')
4035              break;
4036            i++;
4037            if (i == (ssize_t) (argc-1))
4038              ThrowMogrifyException(OptionError,"MissingArgument",option);
4039            channel=ParsePixelChannelOption(argv[i]);
4040            if (channel < 0)
4041              ThrowMogrifyException(OptionError,"UnrecognizedChannelType",
4042                argv[i]);
4043            break;
4044          }
4045        if (LocaleCompare("cdl",option+1) == 0)
4046          {
4047            if (*option == '+')
4048              break;
4049            i++;
4050            if (i == (ssize_t) (argc-1))
4051              ThrowMogrifyException(OptionError,"MissingArgument",option);
4052            break;
4053          }
4054        if (LocaleCompare("charcoal",option+1) == 0)
4055          {
4056            if (*option == '+')
4057              break;
4058            i++;
4059            if (i == (ssize_t) argc)
4060              ThrowMogrifyException(OptionError,"MissingArgument",option);
4061            if (IsGeometry(argv[i]) == MagickFalse)
4062              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4063            break;
4064          }
4065        if (LocaleCompare("chop",option+1) == 0)
4066          {
4067            if (*option == '+')
4068              break;
4069            i++;
4070            if (i == (ssize_t) argc)
4071              ThrowMogrifyException(OptionError,"MissingArgument",option);
4072            if (IsGeometry(argv[i]) == MagickFalse)
4073              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4074            break;
4075          }
4076        if (LocaleCompare("clamp",option+1) == 0)
4077          break;
4078        if (LocaleCompare("clip",option+1) == 0)
4079          break;
4080        if (LocaleCompare("clip-mask",option+1) == 0)
4081          {
4082            if (*option == '+')
4083              break;
4084            i++;
4085            if (i == (ssize_t) argc)
4086              ThrowMogrifyException(OptionError,"MissingArgument",option);
4087            break;
4088          }
4089        if (LocaleCompare("clut",option+1) == 0)
4090          break;
4091        if (LocaleCompare("coalesce",option+1) == 0)
4092          break;
4093        if (LocaleCompare("colorize",option+1) == 0)
4094          {
4095            if (*option == '+')
4096              break;
4097            i++;
4098            if (i == (ssize_t) argc)
4099              ThrowMogrifyException(OptionError,"MissingArgument",option);
4100            if (IsGeometry(argv[i]) == MagickFalse)
4101              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4102            break;
4103          }
4104        if (LocaleCompare("color-matrix",option+1) == 0)
4105          {
4106            KernelInfo
4107              *kernel_info;
4108
4109            if (*option == '+')
4110              break;
4111            i++;
4112            if (i == (ssize_t) (argc-1))
4113              ThrowMogrifyException(OptionError,"MissingArgument",option);
4114            kernel_info=AcquireKernelInfo(argv[i]);
4115            if (kernel_info == (KernelInfo *) NULL)
4116              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4117            kernel_info=DestroyKernelInfo(kernel_info);
4118            break;
4119          }
4120        if (LocaleCompare("colors",option+1) == 0)
4121          {
4122            if (*option == '+')
4123              break;
4124            i++;
4125            if (i == (ssize_t) argc)
4126              ThrowMogrifyException(OptionError,"MissingArgument",option);
4127            if (IsGeometry(argv[i]) == MagickFalse)
4128              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4129            break;
4130          }
4131        if (LocaleCompare("colorspace",option+1) == 0)
4132          {
4133            ssize_t
4134              colorspace;
4135
4136            if (*option == '+')
4137              break;
4138            i++;
4139            if (i == (ssize_t) argc)
4140              ThrowMogrifyException(OptionError,"MissingArgument",option);
4141            colorspace=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
4142              argv[i]);
4143            if (colorspace < 0)
4144              ThrowMogrifyException(OptionError,"UnrecognizedColorspace",
4145                argv[i]);
4146            break;
4147          }
4148        if (LocaleCompare("combine",option+1) == 0)
4149          break;
4150        if (LocaleCompare("comment",option+1) == 0)
4151          {
4152            if (*option == '+')
4153              break;
4154            i++;
4155            if (i == (ssize_t) argc)
4156              ThrowMogrifyException(OptionError,"MissingArgument",option);
4157            break;
4158          }
4159        if (LocaleCompare("composite",option+1) == 0)
4160          break;
4161        if (LocaleCompare("compress",option+1) == 0)
4162          {
4163            ssize_t
4164              compress;
4165
4166            if (*option == '+')
4167              break;
4168            i++;
4169            if (i == (ssize_t) argc)
4170              ThrowMogrifyException(OptionError,"MissingArgument",option);
4171            compress=ParseCommandOption(MagickCompressOptions,MagickFalse,
4172              argv[i]);
4173            if (compress < 0)
4174              ThrowMogrifyException(OptionError,"UnrecognizedImageCompression",
4175                argv[i]);
4176            break;
4177          }
4178        if (LocaleCompare("concurrent",option+1) == 0)
4179          break;
4180        if (LocaleCompare("contrast",option+1) == 0)
4181          break;
4182        if (LocaleCompare("contrast-stretch",option+1) == 0)
4183          {
4184            i++;
4185            if (i == (ssize_t) argc)
4186              ThrowMogrifyException(OptionError,"MissingArgument",option);
4187            if (IsGeometry(argv[i]) == MagickFalse)
4188              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4189            break;
4190          }
4191        if (LocaleCompare("convolve",option+1) == 0)
4192          {
4193            KernelInfo
4194              *kernel_info;
4195
4196            if (*option == '+')
4197              break;
4198            i++;
4199            if (i == (ssize_t) argc)
4200              ThrowMogrifyException(OptionError,"MissingArgument",option);
4201            kernel_info=AcquireKernelInfo(argv[i]);
4202            if (kernel_info == (KernelInfo *) NULL)
4203              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4204            kernel_info=DestroyKernelInfo(kernel_info);
4205            break;
4206          }
4207        if (LocaleCompare("crop",option+1) == 0)
4208          {
4209            if (*option == '+')
4210              break;
4211            i++;
4212            if (i == (ssize_t) argc)
4213              ThrowMogrifyException(OptionError,"MissingArgument",option);
4214            if (IsGeometry(argv[i]) == MagickFalse)
4215              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4216            break;
4217          }
4218        if (LocaleCompare("cycle",option+1) == 0)
4219          {
4220            if (*option == '+')
4221              break;
4222            i++;
4223            if (i == (ssize_t) argc)
4224              ThrowMogrifyException(OptionError,"MissingArgument",option);
4225            if (IsGeometry(argv[i]) == MagickFalse)
4226              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4227            break;
4228          }
4229        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4230      }
4231      case 'd':
4232      {
4233        if (LocaleCompare("decipher",option+1) == 0)
4234          {
4235            if (*option == '+')
4236              break;
4237            i++;
4238            if (i == (ssize_t) (argc-1))
4239              ThrowMogrifyException(OptionError,"MissingArgument",option);
4240            break;
4241          }
4242        if (LocaleCompare("deconstruct",option+1) == 0)
4243          break;
4244        if (LocaleCompare("debug",option+1) == 0)
4245          {
4246            ssize_t
4247              event;
4248
4249            if (*option == '+')
4250              break;
4251            i++;
4252            if (i == (ssize_t) argc)
4253              ThrowMogrifyException(OptionError,"MissingArgument",option);
4254            event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]);
4255            if (event < 0)
4256              ThrowMogrifyException(OptionError,"UnrecognizedEventType",
4257                argv[i]);
4258            (void) SetLogEventMask(argv[i]);
4259            break;
4260          }
4261        if (LocaleCompare("define",option+1) == 0)
4262          {
4263            i++;
4264            if (i == (ssize_t) argc)
4265              ThrowMogrifyException(OptionError,"MissingArgument",option);
4266            if (*option == '+')
4267              {
4268                const char
4269                  *define;
4270
4271                define=GetImageOption(image_info,argv[i]);
4272                if (define == (const char *) NULL)
4273                  ThrowMogrifyException(OptionError,"NoSuchOption",argv[i]);
4274                break;
4275              }
4276            break;
4277          }
4278        if (LocaleCompare("delay",option+1) == 0)
4279          {
4280            if (*option == '+')
4281              break;
4282            i++;
4283            if (i == (ssize_t) argc)
4284              ThrowMogrifyException(OptionError,"MissingArgument",option);
4285            if (IsGeometry(argv[i]) == MagickFalse)
4286              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4287            break;
4288          }
4289        if (LocaleCompare("delete",option+1) == 0)
4290          {
4291            if (*option == '+')
4292              break;
4293            i++;
4294            if (i == (ssize_t) (argc-1))
4295              ThrowMogrifyException(OptionError,"MissingArgument",option);
4296            if (IsGeometry(argv[i]) == MagickFalse)
4297              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4298            break;
4299          }
4300        if (LocaleCompare("density",option+1) == 0)
4301          {
4302            if (*option == '+')
4303              break;
4304            i++;
4305            if (i == (ssize_t) argc)
4306              ThrowMogrifyException(OptionError,"MissingArgument",option);
4307            if (IsGeometry(argv[i]) == MagickFalse)
4308              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4309            break;
4310          }
4311        if (LocaleCompare("depth",option+1) == 0)
4312          {
4313            if (*option == '+')
4314              break;
4315            i++;
4316            if (i == (ssize_t) argc)
4317              ThrowMogrifyException(OptionError,"MissingArgument",option);
4318            if (IsGeometry(argv[i]) == MagickFalse)
4319              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4320            break;
4321          }
4322        if (LocaleCompare("deskew",option+1) == 0)
4323          {
4324            if (*option == '+')
4325              break;
4326            i++;
4327            if (i == (ssize_t) argc)
4328              ThrowMogrifyException(OptionError,"MissingArgument",option);
4329            if (IsGeometry(argv[i]) == MagickFalse)
4330              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4331            break;
4332          }
4333        if (LocaleCompare("despeckle",option+1) == 0)
4334          break;
4335        if (LocaleCompare("dft",option+1) == 0)
4336          break;
4337        if (LocaleCompare("direction",option+1) == 0)
4338          {
4339            ssize_t
4340              direction;
4341
4342            if (*option == '+')
4343              break;
4344            i++;
4345            if (i == (ssize_t) argc)
4346              ThrowMogrifyException(OptionError,"MissingArgument",option);
4347            direction=ParseCommandOption(MagickDirectionOptions,MagickFalse,
4348              argv[i]);
4349            if (direction < 0)
4350              ThrowMogrifyException(OptionError,"UnrecognizedDirectionType",
4351                argv[i]);
4352            break;
4353          }
4354        if (LocaleCompare("display",option+1) == 0)
4355          {
4356            if (*option == '+')
4357              break;
4358            i++;
4359            if (i == (ssize_t) argc)
4360              ThrowMogrifyException(OptionError,"MissingArgument",option);
4361            break;
4362          }
4363        if (LocaleCompare("dispose",option+1) == 0)
4364          {
4365            ssize_t
4366              dispose;
4367
4368            if (*option == '+')
4369              break;
4370            i++;
4371            if (i == (ssize_t) argc)
4372              ThrowMogrifyException(OptionError,"MissingArgument",option);
4373            dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,argv[i]);
4374            if (dispose < 0)
4375              ThrowMogrifyException(OptionError,"UnrecognizedDisposeMethod",
4376                argv[i]);
4377            break;
4378          }
4379        if (LocaleCompare("distort",option+1) == 0)
4380          {
4381            ssize_t
4382              op;
4383
4384            i++;
4385            if (i == (ssize_t) argc)
4386              ThrowMogrifyException(OptionError,"MissingArgument",option);
4387            op=ParseCommandOption(MagickDistortOptions,MagickFalse,argv[i]);
4388            if (op < 0)
4389              ThrowMogrifyException(OptionError,"UnrecognizedDistortMethod",
4390                argv[i]);
4391            i++;
4392            if (i == (ssize_t) (argc-1))
4393              ThrowMogrifyException(OptionError,"MissingArgument",option);
4394            break;
4395          }
4396        if (LocaleCompare("dither",option+1) == 0)
4397          {
4398            ssize_t
4399              method;
4400
4401            if (*option == '+')
4402              break;
4403            i++;
4404            if (i == (ssize_t) argc)
4405              ThrowMogrifyException(OptionError,"MissingArgument",option);
4406            method=ParseCommandOption(MagickDitherOptions,MagickFalse,argv[i]);
4407            if (method < 0)
4408              ThrowMogrifyException(OptionError,"UnrecognizedDitherMethod",
4409                argv[i]);
4410            break;
4411          }
4412        if (LocaleCompare("draw",option+1) == 0)
4413          {
4414            if (*option == '+')
4415              break;
4416            i++;
4417            if (i == (ssize_t) argc)
4418              ThrowMogrifyException(OptionError,"MissingArgument",option);
4419            break;
4420          }
4421        if (LocaleCompare("duplicate",option+1) == 0)
4422          {
4423            if (*option == '+')
4424              break;
4425            i++;
4426            if (i == (ssize_t) (argc-1))
4427              ThrowMogrifyException(OptionError,"MissingArgument",option);
4428            if (IsGeometry(argv[i]) == MagickFalse)
4429              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4430            break;
4431          }
4432        if (LocaleCompare("duration",option+1) == 0)
4433          {
4434            if (*option == '+')
4435              break;
4436            i++;
4437            if (i == (ssize_t) (argc-1))
4438              ThrowMogrifyException(OptionError,"MissingArgument",option);
4439            if (IsGeometry(argv[i]) == MagickFalse)
4440              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4441            break;
4442          }
4443        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4444      }
4445      case 'e':
4446      {
4447        if (LocaleCompare("edge",option+1) == 0)
4448          {
4449            if (*option == '+')
4450              break;
4451            i++;
4452            if (i == (ssize_t) argc)
4453              ThrowMogrifyException(OptionError,"MissingArgument",option);
4454            if (IsGeometry(argv[i]) == MagickFalse)
4455              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4456            break;
4457          }
4458        if (LocaleCompare("emboss",option+1) == 0)
4459          {
4460            if (*option == '+')
4461              break;
4462            i++;
4463            if (i == (ssize_t) argc)
4464              ThrowMogrifyException(OptionError,"MissingArgument",option);
4465            if (IsGeometry(argv[i]) == MagickFalse)
4466              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4467            break;
4468          }
4469        if (LocaleCompare("encipher",option+1) == 0)
4470          {
4471            if (*option == '+')
4472              break;
4473            i++;
4474            if (i == (ssize_t) argc)
4475              ThrowMogrifyException(OptionError,"MissingArgument",option);
4476            break;
4477          }
4478        if (LocaleCompare("encoding",option+1) == 0)
4479          {
4480            if (*option == '+')
4481              break;
4482            i++;
4483            if (i == (ssize_t) argc)
4484              ThrowMogrifyException(OptionError,"MissingArgument",option);
4485            break;
4486          }
4487        if (LocaleCompare("endian",option+1) == 0)
4488          {
4489            ssize_t
4490              endian;
4491
4492            if (*option == '+')
4493              break;
4494            i++;
4495            if (i == (ssize_t) argc)
4496              ThrowMogrifyException(OptionError,"MissingArgument",option);
4497            endian=ParseCommandOption(MagickEndianOptions,MagickFalse,argv[i]);
4498            if (endian < 0)
4499              ThrowMogrifyException(OptionError,"UnrecognizedEndianType",
4500                argv[i]);
4501            break;
4502          }
4503        if (LocaleCompare("enhance",option+1) == 0)
4504          break;
4505        if (LocaleCompare("equalize",option+1) == 0)
4506          break;
4507        if (LocaleCompare("evaluate",option+1) == 0)
4508          {
4509            ssize_t
4510              op;
4511
4512            if (*option == '+')
4513              break;
4514            i++;
4515            if (i == (ssize_t) argc)
4516              ThrowMogrifyException(OptionError,"MissingArgument",option);
4517            op=ParseCommandOption(MagickEvaluateOptions,MagickFalse,argv[i]);
4518            if (op < 0)
4519              ThrowMogrifyException(OptionError,"UnrecognizedEvaluateOperator",
4520                argv[i]);
4521            i++;
4522            if (i == (ssize_t) (argc-1))
4523              ThrowMogrifyException(OptionError,"MissingArgument",option);
4524            if (IsGeometry(argv[i]) == MagickFalse)
4525              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4526            break;
4527          }
4528        if (LocaleCompare("evaluate-sequence",option+1) == 0)
4529          {
4530            ssize_t
4531              op;
4532
4533            if (*option == '+')
4534              break;
4535            i++;
4536            if (i == (ssize_t) argc)
4537              ThrowMogrifyException(OptionError,"MissingArgument",option);
4538            op=ParseCommandOption(MagickEvaluateOptions,MagickFalse,argv[i]);
4539            if (op < 0)
4540              ThrowMogrifyException(OptionError,"UnrecognizedEvaluateOperator",
4541                argv[i]);
4542            break;
4543          }
4544        if (LocaleCompare("extent",option+1) == 0)
4545          {
4546            if (*option == '+')
4547              break;
4548            i++;
4549            if (i == (ssize_t) argc)
4550              ThrowMogrifyException(OptionError,"MissingArgument",option);
4551            if (IsGeometry(argv[i]) == MagickFalse)
4552              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4553            break;
4554          }
4555        if (LocaleCompare("extract",option+1) == 0)
4556          {
4557            if (*option == '+')
4558              break;
4559            i++;
4560            if (i == (ssize_t) argc)
4561              ThrowMogrifyException(OptionError,"MissingArgument",option);
4562            if (IsGeometry(argv[i]) == MagickFalse)
4563              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4564            break;
4565          }
4566        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4567      }
4568      case 'f':
4569      {
4570        if (LocaleCompare("family",option+1) == 0)
4571          {
4572            if (*option == '+')
4573              break;
4574            i++;
4575            if (i == (ssize_t) (argc-1))
4576              ThrowMogrifyException(OptionError,"MissingArgument",option);
4577            break;
4578          }
4579        if (LocaleCompare("features",option+1) == 0)
4580          {
4581            if (*option == '+')
4582              break;
4583            i++;
4584            if (i == (ssize_t) (argc-1))
4585              ThrowMogrifyException(OptionError,"MissingArgument",option);
4586            if (IsGeometry(argv[i]) == MagickFalse)
4587              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4588            break;
4589          }
4590        if (LocaleCompare("fill",option+1) == 0)
4591          {
4592            if (*option == '+')
4593              break;
4594            i++;
4595            if (i == (ssize_t) argc)
4596              ThrowMogrifyException(OptionError,"MissingArgument",option);
4597            break;
4598          }
4599        if (LocaleCompare("filter",option+1) == 0)
4600          {
4601            ssize_t
4602              filter;
4603
4604            if (*option == '+')
4605              break;
4606            i++;
4607            if (i == (ssize_t) argc)
4608              ThrowMogrifyException(OptionError,"MissingArgument",option);
4609            filter=ParseCommandOption(MagickFilterOptions,MagickFalse,argv[i]);
4610            if (filter < 0)
4611              ThrowMogrifyException(OptionError,"UnrecognizedImageFilter",
4612                argv[i]);
4613            break;
4614          }
4615        if (LocaleCompare("flatten",option+1) == 0)
4616          break;
4617        if (LocaleCompare("flip",option+1) == 0)
4618          break;
4619        if (LocaleCompare("flop",option+1) == 0)
4620          break;
4621        if (LocaleCompare("floodfill",option+1) == 0)
4622          {
4623            if (*option == '+')
4624              break;
4625            i++;
4626            if (i == (ssize_t) argc)
4627              ThrowMogrifyException(OptionError,"MissingArgument",option);
4628            if (IsGeometry(argv[i]) == MagickFalse)
4629              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4630            i++;
4631            if (i == (ssize_t) argc)
4632              ThrowMogrifyException(OptionError,"MissingArgument",option);
4633            break;
4634          }
4635        if (LocaleCompare("font",option+1) == 0)
4636          {
4637            if (*option == '+')
4638              break;
4639            i++;
4640            if (i == (ssize_t) argc)
4641              ThrowMogrifyException(OptionError,"MissingArgument",option);
4642            break;
4643          }
4644        if (LocaleCompare("format",option+1) == 0)
4645          {
4646            (void) CopyMagickString(argv[i]+1,"sans",MaxTextExtent);
4647            (void) CloneString(&format,(char *) NULL);
4648            if (*option == '+')
4649              break;
4650            i++;
4651            if (i == (ssize_t) argc)
4652              ThrowMogrifyException(OptionError,"MissingArgument",option);
4653            (void) CloneString(&format,argv[i]);
4654            (void) CopyMagickString(image_info->filename,format,MaxTextExtent);
4655            (void) ConcatenateMagickString(image_info->filename,":",
4656              MaxTextExtent);
4657            (void) SetImageInfo(image_info,0,exception);
4658            if (*image_info->magick == '\0')
4659              ThrowMogrifyException(OptionError,"UnrecognizedImageFormat",
4660                format);
4661            break;
4662          }
4663        if (LocaleCompare("frame",option+1) == 0)
4664          {
4665            if (*option == '+')
4666              break;
4667            i++;
4668            if (i == (ssize_t) argc)
4669              ThrowMogrifyException(OptionError,"MissingArgument",option);
4670            if (IsGeometry(argv[i]) == MagickFalse)
4671              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4672            break;
4673          }
4674        if (LocaleCompare("function",option+1) == 0)
4675          {
4676            ssize_t
4677              op;
4678
4679            if (*option == '+')
4680              break;
4681            i++;
4682            if (i == (ssize_t) argc)
4683              ThrowMogrifyException(OptionError,"MissingArgument",option);
4684            op=ParseCommandOption(MagickFunctionOptions,MagickFalse,argv[i]);
4685            if (op < 0)
4686              ThrowMogrifyException(OptionError,"UnrecognizedFunction",argv[i]);
4687             i++;
4688             if (i == (ssize_t) (argc-1))
4689               ThrowMogrifyException(OptionError,"MissingArgument",option);
4690            break;
4691          }
4692        if (LocaleCompare("fuzz",option+1) == 0)
4693          {
4694            if (*option == '+')
4695              break;
4696            i++;
4697            if (i == (ssize_t) argc)
4698              ThrowMogrifyException(OptionError,"MissingArgument",option);
4699            if (IsGeometry(argv[i]) == MagickFalse)
4700              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4701            break;
4702          }
4703        if (LocaleCompare("fx",option+1) == 0)
4704          {
4705            if (*option == '+')
4706              break;
4707            i++;
4708            if (i == (ssize_t) (argc-1))
4709              ThrowMogrifyException(OptionError,"MissingArgument",option);
4710            break;
4711          }
4712        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4713      }
4714      case 'g':
4715      {
4716        if (LocaleCompare("gamma",option+1) == 0)
4717          {
4718            i++;
4719            if (i == (ssize_t) argc)
4720              ThrowMogrifyException(OptionError,"MissingArgument",option);
4721            if (IsGeometry(argv[i]) == MagickFalse)
4722              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4723            break;
4724          }
4725        if ((LocaleCompare("gaussian-blur",option+1) == 0) ||
4726            (LocaleCompare("gaussian",option+1) == 0))
4727          {
4728            i++;
4729            if (i == (ssize_t) argc)
4730              ThrowMogrifyException(OptionError,"MissingArgument",option);
4731            if (IsGeometry(argv[i]) == MagickFalse)
4732              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4733            break;
4734          }
4735        if (LocaleCompare("geometry",option+1) == 0)
4736          {
4737            if (*option == '+')
4738              break;
4739            i++;
4740            if (i == (ssize_t) argc)
4741              ThrowMogrifyException(OptionError,"MissingArgument",option);
4742            if (IsGeometry(argv[i]) == MagickFalse)
4743              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4744            break;
4745          }
4746        if (LocaleCompare("gravity",option+1) == 0)
4747          {
4748            ssize_t
4749              gravity;
4750
4751            if (*option == '+')
4752              break;
4753            i++;
4754            if (i == (ssize_t) argc)
4755              ThrowMogrifyException(OptionError,"MissingArgument",option);
4756            gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,argv[i]);
4757            if (gravity < 0)
4758              ThrowMogrifyException(OptionError,"UnrecognizedGravityType",
4759                argv[i]);
4760            break;
4761          }
4762        if (LocaleCompare("green-primary",option+1) == 0)
4763          {
4764            if (*option == '+')
4765              break;
4766            i++;
4767            if (i == (ssize_t) argc)
4768              ThrowMogrifyException(OptionError,"MissingArgument",option);
4769            if (IsGeometry(argv[i]) == MagickFalse)
4770              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4771            break;
4772          }
4773        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4774      }
4775      case 'h':
4776      {
4777        if (LocaleCompare("hald-clut",option+1) == 0)
4778          break;
4779        if ((LocaleCompare("help",option+1) == 0) ||
4780            (LocaleCompare("-help",option+1) == 0))
4781          return(MogrifyUsage());
4782        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4783      }
4784      case 'i':
4785      {
4786        if (LocaleCompare("identify",option+1) == 0)
4787          break;
4788        if (LocaleCompare("idft",option+1) == 0)
4789          break;
4790        if (LocaleCompare("implode",option+1) == 0)
4791          {
4792            if (*option == '+')
4793              break;
4794            i++;
4795            if (i == (ssize_t) argc)
4796              ThrowMogrifyException(OptionError,"MissingArgument",option);
4797            if (IsGeometry(argv[i]) == MagickFalse)
4798              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4799            break;
4800          }
4801        if (LocaleCompare("intent",option+1) == 0)
4802          {
4803            ssize_t
4804              intent;
4805
4806            if (*option == '+')
4807              break;
4808            i++;
4809            if (i == (ssize_t) (argc-1))
4810              ThrowMogrifyException(OptionError,"MissingArgument",option);
4811            intent=ParseCommandOption(MagickIntentOptions,MagickFalse,argv[i]);
4812            if (intent < 0)
4813              ThrowMogrifyException(OptionError,"UnrecognizedIntentType",
4814                argv[i]);
4815            break;
4816          }
4817        if (LocaleCompare("interlace",option+1) == 0)
4818          {
4819            ssize_t
4820              interlace;
4821
4822            if (*option == '+')
4823              break;
4824            i++;
4825            if (i == (ssize_t) argc)
4826              ThrowMogrifyException(OptionError,"MissingArgument",option);
4827            interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
4828              argv[i]);
4829            if (interlace < 0)
4830              ThrowMogrifyException(OptionError,"UnrecognizedInterlaceType",
4831                argv[i]);
4832            break;
4833          }
4834        if (LocaleCompare("interline-spacing",option+1) == 0)
4835          {
4836            if (*option == '+')
4837              break;
4838            i++;
4839            if (i == (ssize_t) (argc-1))
4840              ThrowMogrifyException(OptionError,"MissingArgument",option);
4841            if (IsGeometry(argv[i]) == MagickFalse)
4842              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4843            break;
4844          }
4845        if (LocaleCompare("interpolate",option+1) == 0)
4846          {
4847            ssize_t
4848              interpolate;
4849
4850            if (*option == '+')
4851              break;
4852            i++;
4853            if (i == (ssize_t) argc)
4854              ThrowMogrifyException(OptionError,"MissingArgument",option);
4855            interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
4856              argv[i]);
4857            if (interpolate < 0)
4858              ThrowMogrifyException(OptionError,"UnrecognizedInterpolateMethod",
4859                argv[i]);
4860            break;
4861          }
4862        if (LocaleCompare("interword-spacing",option+1) == 0)
4863          {
4864            if (*option == '+')
4865              break;
4866            i++;
4867            if (i == (ssize_t) (argc-1))
4868              ThrowMogrifyException(OptionError,"MissingArgument",option);
4869            if (IsGeometry(argv[i]) == MagickFalse)
4870              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4871            break;
4872          }
4873        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4874      }
4875      case 'k':
4876      {
4877        if (LocaleCompare("kerning",option+1) == 0)
4878          {
4879            if (*option == '+')
4880              break;
4881            i++;
4882            if (i == (ssize_t) (argc-1))
4883              ThrowMogrifyException(OptionError,"MissingArgument",option);
4884            if (IsGeometry(argv[i]) == MagickFalse)
4885              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4886            break;
4887          }
4888        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4889      }
4890      case 'l':
4891      {
4892        if (LocaleCompare("label",option+1) == 0)
4893          {
4894            if (*option == '+')
4895              break;
4896            i++;
4897            if (i == (ssize_t) argc)
4898              ThrowMogrifyException(OptionError,"MissingArgument",option);
4899            break;
4900          }
4901        if (LocaleCompare("lat",option+1) == 0)
4902          {
4903            if (*option == '+')
4904              break;
4905            i++;
4906            if (i == (ssize_t) argc)
4907              ThrowMogrifyException(OptionError,"MissingArgument",option);
4908            if (IsGeometry(argv[i]) == MagickFalse)
4909              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4910          }
4911        if (LocaleCompare("layers",option+1) == 0)
4912          {
4913            ssize_t
4914              type;
4915
4916            if (*option == '+')
4917              break;
4918            i++;
4919            if (i == (ssize_t) (argc-1))
4920              ThrowMogrifyException(OptionError,"MissingArgument",option);
4921            type=ParseCommandOption(MagickLayerOptions,MagickFalse,argv[i]);
4922            if (type < 0)
4923              ThrowMogrifyException(OptionError,"UnrecognizedLayerMethod",
4924                argv[i]);
4925            break;
4926          }
4927        if (LocaleCompare("level",option+1) == 0)
4928          {
4929            i++;
4930            if (i == (ssize_t) argc)
4931              ThrowMogrifyException(OptionError,"MissingArgument",option);
4932            if (IsGeometry(argv[i]) == MagickFalse)
4933              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4934            break;
4935          }
4936        if (LocaleCompare("level-colors",option+1) == 0)
4937          {
4938            i++;
4939            if (i == (ssize_t) argc)
4940              ThrowMogrifyException(OptionError,"MissingArgument",option);
4941            break;
4942          }
4943        if (LocaleCompare("limit",option+1) == 0)
4944          {
4945            char
4946              *p;
4947
4948            double
4949              value;
4950
4951            ssize_t
4952              resource;
4953
4954            if (*option == '+')
4955              break;
4956            i++;
4957            if (i == (ssize_t) argc)
4958              ThrowMogrifyException(OptionError,"MissingArgument",option);
4959            resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
4960              argv[i]);
4961            if (resource < 0)
4962              ThrowMogrifyException(OptionError,"UnrecognizedResourceType",
4963                argv[i]);
4964            i++;
4965            if (i == (ssize_t) argc)
4966              ThrowMogrifyException(OptionError,"MissingArgument",option);
4967            value=StringToDouble(argv[i],&p);
4968            (void) value;
4969            if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
4970              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4971            break;
4972          }
4973        if (LocaleCompare("liquid-rescale",option+1) == 0)
4974          {
4975            i++;
4976            if (i == (ssize_t) argc)
4977              ThrowMogrifyException(OptionError,"MissingArgument",option);
4978            if (IsGeometry(argv[i]) == MagickFalse)
4979              ThrowMogrifyInvalidArgumentException(option,argv[i]);
4980            break;
4981          }
4982        if (LocaleCompare("list",option+1) == 0)
4983          {
4984            ssize_t
4985              list;
4986
4987            if (*option == '+')
4988              break;
4989            i++;
4990            if (i == (ssize_t) argc)
4991              ThrowMogrifyException(OptionError,"MissingArgument",option);
4992            list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
4993            if (list < 0)
4994              ThrowMogrifyException(OptionError,"UnrecognizedListType",argv[i]);
4995            status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
4996              argv+j,exception);
4997            return(status != 0 ? MagickFalse : MagickTrue);
4998          }
4999        if (LocaleCompare("log",option+1) == 0)
5000          {
5001            if (*option == '+')
5002              break;
5003            i++;
5004            if ((i == (ssize_t) argc) ||
5005                (strchr(argv[i],'%') == (char *) NULL))
5006              ThrowMogrifyException(OptionError,"MissingArgument",option);
5007            break;
5008          }
5009        if (LocaleCompare("loop",option+1) == 0)
5010          {
5011            if (*option == '+')
5012              break;
5013            i++;
5014            if (i == (ssize_t) argc)
5015              ThrowMogrifyException(OptionError,"MissingArgument",option);
5016            if (IsGeometry(argv[i]) == MagickFalse)
5017              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5018            break;
5019          }
5020        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5021      }
5022      case 'm':
5023      {
5024        if (LocaleCompare("map",option+1) == 0)
5025          {
5026            global_colormap=(*option == '+') ? MagickTrue : MagickFalse;
5027            if (*option == '+')
5028              break;
5029            i++;
5030            if (i == (ssize_t) argc)
5031              ThrowMogrifyException(OptionError,"MissingArgument",option);
5032            break;
5033          }
5034        if (LocaleCompare("mask",option+1) == 0)
5035          {
5036            if (*option == '+')
5037              break;
5038            i++;
5039            if (i == (ssize_t) argc)
5040              ThrowMogrifyException(OptionError,"MissingArgument",option);
5041            break;
5042          }
5043        if (LocaleCompare("matte",option+1) == 0)
5044          break;
5045        if (LocaleCompare("mattecolor",option+1) == 0)
5046          {
5047            if (*option == '+')
5048              break;
5049            i++;
5050            if (i == (ssize_t) argc)
5051              ThrowMogrifyException(OptionError,"MissingArgument",option);
5052            break;
5053          }
5054        if (LocaleCompare("maximum",option+1) == 0)
5055          break;
5056        if (LocaleCompare("minimum",option+1) == 0)
5057          break;
5058        if (LocaleCompare("modulate",option+1) == 0)
5059          {
5060            if (*option == '+')
5061              break;
5062            i++;
5063            if (i == (ssize_t) argc)
5064              ThrowMogrifyException(OptionError,"MissingArgument",option);
5065            if (IsGeometry(argv[i]) == MagickFalse)
5066              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5067            break;
5068          }
5069        if (LocaleCompare("median",option+1) == 0)
5070          {
5071            if (*option == '+')
5072              break;
5073            i++;
5074            if (i == (ssize_t) argc)
5075              ThrowMogrifyException(OptionError,"MissingArgument",option);
5076            if (IsGeometry(argv[i]) == MagickFalse)
5077              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5078            break;
5079          }
5080        if (LocaleCompare("mode",option+1) == 0)
5081          {
5082            if (*option == '+')
5083              break;
5084            i++;
5085            if (i == (ssize_t) argc)
5086              ThrowMogrifyException(OptionError,"MissingArgument",option);
5087            if (IsGeometry(argv[i]) == MagickFalse)
5088              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5089            break;
5090          }
5091        if (LocaleCompare("monitor",option+1) == 0)
5092          break;
5093        if (LocaleCompare("monochrome",option+1) == 0)
5094          break;
5095        if (LocaleCompare("morph",option+1) == 0)
5096          {
5097            if (*option == '+')
5098              break;
5099            i++;
5100            if (i == (ssize_t) (argc-1))
5101              ThrowMogrifyException(OptionError,"MissingArgument",option);
5102            if (IsGeometry(argv[i]) == MagickFalse)
5103              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5104            break;
5105          }
5106        if (LocaleCompare("morphology",option+1) == 0)
5107          {
5108            char
5109              token[MaxTextExtent];
5110
5111            KernelInfo
5112              *kernel_info;
5113
5114            ssize_t
5115              op;
5116
5117            i++;
5118            if (i == (ssize_t) argc)
5119              ThrowMogrifyException(OptionError,"MissingArgument",option);
5120            GetMagickToken(argv[i],NULL,token);
5121            op=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
5122            if (op < 0)
5123              ThrowMogrifyException(OptionError,"UnrecognizedMorphologyMethod",
5124                token);
5125            i++;
5126            if (i == (ssize_t) (argc-1))
5127              ThrowMogrifyException(OptionError,"MissingArgument",option);
5128            kernel_info=AcquireKernelInfo(argv[i]);
5129            if (kernel_info == (KernelInfo *) NULL)
5130              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5131            kernel_info=DestroyKernelInfo(kernel_info);
5132            break;
5133          }
5134        if (LocaleCompare("mosaic",option+1) == 0)
5135          break;
5136        if (LocaleCompare("motion-blur",option+1) == 0)
5137          {
5138            if (*option == '+')
5139              break;
5140            i++;
5141            if (i == (ssize_t) argc)
5142              ThrowMogrifyException(OptionError,"MissingArgument",option);
5143            if (IsGeometry(argv[i]) == MagickFalse)
5144              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5145            break;
5146          }
5147        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5148      }
5149      case 'n':
5150      {
5151        if (LocaleCompare("negate",option+1) == 0)
5152          break;
5153        if (LocaleCompare("noise",option+1) == 0)
5154          {
5155            i++;
5156            if (i == (ssize_t) argc)
5157              ThrowMogrifyException(OptionError,"MissingArgument",option);
5158            if (*option == '+')
5159              {
5160                ssize_t
5161                  noise;
5162
5163                noise=ParseCommandOption(MagickNoiseOptions,MagickFalse,argv[i]);
5164                if (noise < 0)
5165                  ThrowMogrifyException(OptionError,"UnrecognizedNoiseType",
5166                    argv[i]);
5167                break;
5168              }
5169            if (IsGeometry(argv[i]) == MagickFalse)
5170              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5171            break;
5172          }
5173        if (LocaleCompare("noop",option+1) == 0)
5174          break;
5175        if (LocaleCompare("normalize",option+1) == 0)
5176          break;
5177        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5178      }
5179      case 'o':
5180      {
5181        if (LocaleCompare("opaque",option+1) == 0)
5182          {
5183            i++;
5184            if (i == (ssize_t) argc)
5185              ThrowMogrifyException(OptionError,"MissingArgument",option);
5186            break;
5187          }
5188        if (LocaleCompare("ordered-dither",option+1) == 0)
5189          {
5190            if (*option == '+')
5191              break;
5192            i++;
5193            if (i == (ssize_t) argc)
5194              ThrowMogrifyException(OptionError,"MissingArgument",option);
5195            break;
5196          }
5197        if (LocaleCompare("orient",option+1) == 0)
5198          {
5199            ssize_t
5200              orientation;
5201
5202            orientation=UndefinedOrientation;
5203            if (*option == '+')
5204              break;
5205            i++;
5206            if (i == (ssize_t) (argc-1))
5207              ThrowMogrifyException(OptionError,"MissingArgument",option);
5208            orientation=ParseCommandOption(MagickOrientationOptions,MagickFalse,
5209              argv[i]);
5210            if (orientation < 0)
5211              ThrowMogrifyException(OptionError,"UnrecognizedImageOrientation",
5212                argv[i]);
5213            break;
5214          }
5215        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5216      }
5217      case 'p':
5218      {
5219        if (LocaleCompare("page",option+1) == 0)
5220          {
5221            if (*option == '+')
5222              break;
5223            i++;
5224            if (i == (ssize_t) argc)
5225              ThrowMogrifyException(OptionError,"MissingArgument",option);
5226            break;
5227          }
5228        if (LocaleCompare("paint",option+1) == 0)
5229          {
5230            if (*option == '+')
5231              break;
5232            i++;
5233            if (i == (ssize_t) argc)
5234              ThrowMogrifyException(OptionError,"MissingArgument",option);
5235            if (IsGeometry(argv[i]) == MagickFalse)
5236              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5237            break;
5238          }
5239        if (LocaleCompare("path",option+1) == 0)
5240          {
5241            (void) CloneString(&path,(char *) NULL);
5242            if (*option == '+')
5243              break;
5244            i++;
5245            if (i == (ssize_t) argc)
5246              ThrowMogrifyException(OptionError,"MissingArgument",option);
5247            (void) CloneString(&path,argv[i]);
5248            break;
5249          }
5250        if (LocaleCompare("pointsize",option+1) == 0)
5251          {
5252            if (*option == '+')
5253              break;
5254            i++;
5255            if (i == (ssize_t) argc)
5256              ThrowMogrifyException(OptionError,"MissingArgument",option);
5257            if (IsGeometry(argv[i]) == MagickFalse)
5258              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5259            break;
5260          }
5261        if (LocaleCompare("polaroid",option+1) == 0)
5262          {
5263            if (*option == '+')
5264              break;
5265            i++;
5266            if (i == (ssize_t) argc)
5267              ThrowMogrifyException(OptionError,"MissingArgument",option);
5268            if (IsGeometry(argv[i]) == MagickFalse)
5269              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5270            break;
5271          }
5272        if (LocaleCompare("posterize",option+1) == 0)
5273          {
5274            if (*option == '+')
5275              break;
5276            i++;
5277            if (i == (ssize_t) argc)
5278              ThrowMogrifyException(OptionError,"MissingArgument",option);
5279            if (IsGeometry(argv[i]) == MagickFalse)
5280              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5281            break;
5282          }
5283        if (LocaleCompare("precision",option+1) == 0)
5284          {
5285            if (*option == '+')
5286              break;
5287            i++;
5288            if (i == (ssize_t) argc)
5289              ThrowMogrifyException(OptionError,"MissingArgument",option);
5290            if (IsGeometry(argv[i]) == MagickFalse)
5291              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5292            break;
5293          }
5294        if (LocaleCompare("print",option+1) == 0)
5295          {
5296            if (*option == '+')
5297              break;
5298            i++;
5299            if (i == (ssize_t) argc)
5300              ThrowMogrifyException(OptionError,"MissingArgument",option);
5301            break;
5302          }
5303        if (LocaleCompare("process",option+1) == 0)
5304          {
5305            if (*option == '+')
5306              break;
5307            i++;
5308            if (i == (ssize_t) (argc-1))
5309              ThrowMogrifyException(OptionError,"MissingArgument",option);
5310            break;
5311          }
5312        if (LocaleCompare("profile",option+1) == 0)
5313          {
5314            i++;
5315            if (i == (ssize_t) argc)
5316              ThrowMogrifyException(OptionError,"MissingArgument",option);
5317            break;
5318          }
5319        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5320      }
5321      case 'q':
5322      {
5323        if (LocaleCompare("quality",option+1) == 0)
5324          {
5325            if (*option == '+')
5326              break;
5327            i++;
5328            if (i == (ssize_t) argc)
5329              ThrowMogrifyException(OptionError,"MissingArgument",option);
5330            if (IsGeometry(argv[i]) == MagickFalse)
5331              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5332            break;
5333          }
5334        if (LocaleCompare("quantize",option+1) == 0)
5335          {
5336            ssize_t
5337              colorspace;
5338
5339            if (*option == '+')
5340              break;
5341            i++;
5342            if (i == (ssize_t) (argc-1))
5343              ThrowMogrifyException(OptionError,"MissingArgument",option);
5344            colorspace=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
5345              argv[i]);
5346            if (colorspace < 0)
5347              ThrowMogrifyException(OptionError,"UnrecognizedColorspace",
5348                argv[i]);
5349            break;
5350          }
5351        if (LocaleCompare("quiet",option+1) == 0)
5352          break;
5353        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5354      }
5355      case 'r':
5356      {
5357        if (LocaleCompare("radial-blur",option+1) == 0)
5358          {
5359            i++;
5360            if (i == (ssize_t) argc)
5361              ThrowMogrifyException(OptionError,"MissingArgument",option);
5362            if (IsGeometry(argv[i]) == MagickFalse)
5363              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5364            break;
5365          }
5366        if (LocaleCompare("raise",option+1) == 0)
5367          {
5368            i++;
5369            if (i == (ssize_t) argc)
5370              ThrowMogrifyException(OptionError,"MissingArgument",option);
5371            if (IsGeometry(argv[i]) == MagickFalse)
5372              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5373            break;
5374          }
5375        if (LocaleCompare("random-threshold",option+1) == 0)
5376          {
5377            if (*option == '+')
5378              break;
5379            i++;
5380            if (i == (ssize_t) argc)
5381              ThrowMogrifyException(OptionError,"MissingArgument",option);
5382            if (IsGeometry(argv[i]) == MagickFalse)
5383              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5384            break;
5385          }
5386        if (LocaleCompare("red-primary",option+1) == 0)
5387          {
5388            if (*option == '+')
5389              break;
5390            i++;
5391            if (i == (ssize_t) argc)
5392              ThrowMogrifyException(OptionError,"MissingArgument",option);
5393            if (IsGeometry(argv[i]) == MagickFalse)
5394              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5395          }
5396        if (LocaleCompare("regard-warnings",option+1) == 0)
5397          break;
5398        if (LocaleCompare("region",option+1) == 0)
5399          {
5400            if (*option == '+')
5401              break;
5402            i++;
5403            if (i == (ssize_t) argc)
5404              ThrowMogrifyException(OptionError,"MissingArgument",option);
5405            if (IsGeometry(argv[i]) == MagickFalse)
5406              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5407            break;
5408          }
5409        if (LocaleCompare("remap",option+1) == 0)
5410          {
5411            if (*option == '+')
5412              break;
5413            i++;
5414            if (i == (ssize_t) (argc-1))
5415              ThrowMogrifyException(OptionError,"MissingArgument",option);
5416            break;
5417          }
5418        if (LocaleCompare("render",option+1) == 0)
5419          break;
5420        if (LocaleCompare("repage",option+1) == 0)
5421          {
5422            if (*option == '+')
5423              break;
5424            i++;
5425            if (i == (ssize_t) argc)
5426              ThrowMogrifyException(OptionError,"MissingArgument",option);
5427            if (IsGeometry(argv[i]) == MagickFalse)
5428              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5429            break;
5430          }
5431        if (LocaleCompare("resample",option+1) == 0)
5432          {
5433            if (*option == '+')
5434              break;
5435            i++;
5436            if (i == (ssize_t) argc)
5437              ThrowMogrifyException(OptionError,"MissingArgument",option);
5438            if (IsGeometry(argv[i]) == MagickFalse)
5439              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5440            break;
5441          }
5442        if (LocaleCompare("resize",option+1) == 0)
5443          {
5444            if (*option == '+')
5445              break;
5446            i++;
5447            if (i == (ssize_t) argc)
5448              ThrowMogrifyException(OptionError,"MissingArgument",option);
5449            if (IsGeometry(argv[i]) == MagickFalse)
5450              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5451            break;
5452          }
5453        if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
5454          {
5455            respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
5456            break;
5457          }
5458        if (LocaleCompare("reverse",option+1) == 0)
5459          break;
5460        if (LocaleCompare("roll",option+1) == 0)
5461          {
5462            if (*option == '+')
5463              break;
5464            i++;
5465            if (i == (ssize_t) argc)
5466              ThrowMogrifyException(OptionError,"MissingArgument",option);
5467            if (IsGeometry(argv[i]) == MagickFalse)
5468              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5469            break;
5470          }
5471        if (LocaleCompare("rotate",option+1) == 0)
5472          {
5473            i++;
5474            if (i == (ssize_t) argc)
5475              ThrowMogrifyException(OptionError,"MissingArgument",option);
5476            if (IsGeometry(argv[i]) == MagickFalse)
5477              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5478            break;
5479          }
5480        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5481      }
5482      case 's':
5483      {
5484        if (LocaleCompare("sample",option+1) == 0)
5485          {
5486            if (*option == '+')
5487              break;
5488            i++;
5489            if (i == (ssize_t) argc)
5490              ThrowMogrifyException(OptionError,"MissingArgument",option);
5491            if (IsGeometry(argv[i]) == MagickFalse)
5492              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5493            break;
5494          }
5495        if (LocaleCompare("sampling-factor",option+1) == 0)
5496          {
5497            if (*option == '+')
5498              break;
5499            i++;
5500            if (i == (ssize_t) argc)
5501              ThrowMogrifyException(OptionError,"MissingArgument",option);
5502            if (IsGeometry(argv[i]) == MagickFalse)
5503              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5504            break;
5505          }
5506        if (LocaleCompare("scale",option+1) == 0)
5507          {
5508            if (*option == '+')
5509              break;
5510            i++;
5511            if (i == (ssize_t) argc)
5512              ThrowMogrifyException(OptionError,"MissingArgument",option);
5513            if (IsGeometry(argv[i]) == MagickFalse)
5514              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5515            break;
5516          }
5517        if (LocaleCompare("scene",option+1) == 0)
5518          {
5519            if (*option == '+')
5520              break;
5521            i++;
5522            if (i == (ssize_t) argc)
5523              ThrowMogrifyException(OptionError,"MissingArgument",option);
5524            if (IsGeometry(argv[i]) == MagickFalse)
5525              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5526            break;
5527          }
5528        if (LocaleCompare("seed",option+1) == 0)
5529          {
5530            if (*option == '+')
5531              break;
5532            i++;
5533            if (i == (ssize_t) argc)
5534              ThrowMogrifyException(OptionError,"MissingArgument",option);
5535            if (IsGeometry(argv[i]) == MagickFalse)
5536              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5537            break;
5538          }
5539        if (LocaleCompare("segment",option+1) == 0)
5540          {
5541            if (*option == '+')
5542              break;
5543            i++;
5544            if (i == (ssize_t) argc)
5545              ThrowMogrifyException(OptionError,"MissingArgument",option);
5546            if (IsGeometry(argv[i]) == MagickFalse)
5547              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5548            break;
5549          }
5550        if (LocaleCompare("selective-blur",option+1) == 0)
5551          {
5552            i++;
5553            if (i == (ssize_t) argc)
5554              ThrowMogrifyException(OptionError,"MissingArgument",option);
5555            if (IsGeometry(argv[i]) == MagickFalse)
5556              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5557            break;
5558          }
5559        if (LocaleCompare("separate",option+1) == 0)
5560          break;
5561        if (LocaleCompare("sepia-tone",option+1) == 0)
5562          {
5563            if (*option == '+')
5564              break;
5565            i++;
5566            if (i == (ssize_t) argc)
5567              ThrowMogrifyException(OptionError,"MissingArgument",option);
5568            if (IsGeometry(argv[i]) == MagickFalse)
5569              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5570            break;
5571          }
5572        if (LocaleCompare("set",option+1) == 0)
5573          {
5574            i++;
5575            if (i == (ssize_t) argc)
5576              ThrowMogrifyException(OptionError,"MissingArgument",option);
5577            if (*option == '+')
5578              break;
5579            i++;
5580            if (i == (ssize_t) argc)
5581              ThrowMogrifyException(OptionError,"MissingArgument",option);
5582            break;
5583          }
5584        if (LocaleCompare("shade",option+1) == 0)
5585          {
5586            i++;
5587            if (i == (ssize_t) argc)
5588              ThrowMogrifyException(OptionError,"MissingArgument",option);
5589            if (IsGeometry(argv[i]) == MagickFalse)
5590              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5591            break;
5592          }
5593        if (LocaleCompare("shadow",option+1) == 0)
5594          {
5595            if (*option == '+')
5596              break;
5597            i++;
5598            if (i == (ssize_t) argc)
5599              ThrowMogrifyException(OptionError,"MissingArgument",option);
5600            if (IsGeometry(argv[i]) == MagickFalse)
5601              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5602            break;
5603          }
5604        if (LocaleCompare("sharpen",option+1) == 0)
5605          {
5606            i++;
5607            if (i == (ssize_t) argc)
5608              ThrowMogrifyException(OptionError,"MissingArgument",option);
5609            if (IsGeometry(argv[i]) == MagickFalse)
5610              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5611            break;
5612          }
5613        if (LocaleCompare("shave",option+1) == 0)
5614          {
5615            if (*option == '+')
5616              break;
5617            i++;
5618            if (i == (ssize_t) argc)
5619              ThrowMogrifyException(OptionError,"MissingArgument",option);
5620            if (IsGeometry(argv[i]) == MagickFalse)
5621              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5622            break;
5623          }
5624        if (LocaleCompare("shear",option+1) == 0)
5625          {
5626            i++;
5627            if (i == (ssize_t) argc)
5628              ThrowMogrifyException(OptionError,"MissingArgument",option);
5629            if (IsGeometry(argv[i]) == MagickFalse)
5630              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5631            break;
5632          }
5633        if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
5634          {
5635            i++;
5636            if (i == (ssize_t) (argc-1))
5637              ThrowMogrifyException(OptionError,"MissingArgument",option);
5638            if (IsGeometry(argv[i]) == MagickFalse)
5639              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5640            break;
5641          }
5642        if (LocaleCompare("size",option+1) == 0)
5643          {
5644            if (*option == '+')
5645              break;
5646            i++;
5647            if (i == (ssize_t) argc)
5648              ThrowMogrifyException(OptionError,"MissingArgument",option);
5649            if (IsGeometry(argv[i]) == MagickFalse)
5650              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5651            break;
5652          }
5653        if (LocaleCompare("sketch",option+1) == 0)
5654          {
5655            if (*option == '+')
5656              break;
5657            i++;
5658            if (i == (ssize_t) argc)
5659              ThrowMogrifyException(OptionError,"MissingArgument",option);
5660            if (IsGeometry(argv[i]) == MagickFalse)
5661              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5662            break;
5663          }
5664        if (LocaleCompare("smush",option+1) == 0)
5665          {
5666            i++;
5667            if (i == (ssize_t) argc)
5668              ThrowMogrifyException(OptionError,"MissingArgument",option);
5669            if (IsGeometry(argv[i]) == MagickFalse)
5670              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5671            i++;
5672            break;
5673          }
5674        if (LocaleCompare("solarize",option+1) == 0)
5675          {
5676            if (*option == '+')
5677              break;
5678            i++;
5679            if (i == (ssize_t) argc)
5680              ThrowMogrifyException(OptionError,"MissingArgument",option);
5681            if (IsGeometry(argv[i]) == MagickFalse)
5682              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5683            break;
5684          }
5685        if (LocaleCompare("sparse-color",option+1) == 0)
5686          {
5687            ssize_t
5688              op;
5689
5690            i++;
5691            if (i == (ssize_t) argc)
5692              ThrowMogrifyException(OptionError,"MissingArgument",option);
5693            op=ParseCommandOption(MagickSparseColorOptions,MagickFalse,argv[i]);
5694            if (op < 0)
5695              ThrowMogrifyException(OptionError,"UnrecognizedSparseColorMethod",
5696                argv[i]);
5697            i++;
5698            if (i == (ssize_t) (argc-1))
5699              ThrowMogrifyException(OptionError,"MissingArgument",option);
5700            break;
5701          }
5702        if (LocaleCompare("spread",option+1) == 0)
5703          {
5704            if (*option == '+')
5705              break;
5706            i++;
5707            if (i == (ssize_t) argc)
5708              ThrowMogrifyException(OptionError,"MissingArgument",option);
5709            if (IsGeometry(argv[i]) == MagickFalse)
5710              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5711            break;
5712          }
5713        if (LocaleCompare("statistic",option+1) == 0)
5714          {
5715            ssize_t
5716              op;
5717
5718            if (*option == '+')
5719              break;
5720            i++;
5721            if (i == (ssize_t) argc)
5722              ThrowMogrifyException(OptionError,"MissingArgument",option);
5723            op=ParseCommandOption(MagickStatisticOptions,MagickFalse,argv[i]);
5724            if (op < 0)
5725              ThrowMogrifyException(OptionError,"UnrecognizedStatisticType",
5726                argv[i]);
5727            i++;
5728            if (i == (ssize_t) (argc-1))
5729              ThrowMogrifyException(OptionError,"MissingArgument",option);
5730            if (IsGeometry(argv[i]) == MagickFalse)
5731              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5732            break;
5733          }
5734        if (LocaleCompare("stretch",option+1) == 0)
5735          {
5736            ssize_t
5737              stretch;
5738
5739            if (*option == '+')
5740              break;
5741            i++;
5742            if (i == (ssize_t) (argc-1))
5743              ThrowMogrifyException(OptionError,"MissingArgument",option);
5744            stretch=ParseCommandOption(MagickStretchOptions,MagickFalse,argv[i]);
5745            if (stretch < 0)
5746              ThrowMogrifyException(OptionError,"UnrecognizedStyleType",
5747                argv[i]);
5748            break;
5749          }
5750        if (LocaleCompare("strip",option+1) == 0)
5751          break;
5752        if (LocaleCompare("stroke",option+1) == 0)
5753          {
5754            if (*option == '+')
5755              break;
5756            i++;
5757            if (i == (ssize_t) argc)
5758              ThrowMogrifyException(OptionError,"MissingArgument",option);
5759            break;
5760          }
5761        if (LocaleCompare("strokewidth",option+1) == 0)
5762          {
5763            if (*option == '+')
5764              break;
5765            i++;
5766            if (i == (ssize_t) argc)
5767              ThrowMogrifyException(OptionError,"MissingArgument",option);
5768            if (IsGeometry(argv[i]) == MagickFalse)
5769              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5770            break;
5771          }
5772        if (LocaleCompare("style",option+1) == 0)
5773          {
5774            ssize_t
5775              style;
5776
5777            if (*option == '+')
5778              break;
5779            i++;
5780            if (i == (ssize_t) (argc-1))
5781              ThrowMogrifyException(OptionError,"MissingArgument",option);
5782            style=ParseCommandOption(MagickStyleOptions,MagickFalse,argv[i]);
5783            if (style < 0)
5784              ThrowMogrifyException(OptionError,"UnrecognizedStyleType",
5785                argv[i]);
5786            break;
5787          }
5788        if (LocaleCompare("swap",option+1) == 0)
5789          {
5790            if (*option == '+')
5791              break;
5792            i++;
5793            if (i == (ssize_t) (argc-1))
5794              ThrowMogrifyException(OptionError,"MissingArgument",option);
5795            if (IsGeometry(argv[i]) == MagickFalse)
5796              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5797            break;
5798          }
5799        if (LocaleCompare("swirl",option+1) == 0)
5800          {
5801            if (*option == '+')
5802              break;
5803            i++;
5804            if (i == (ssize_t) argc)
5805              ThrowMogrifyException(OptionError,"MissingArgument",option);
5806            if (IsGeometry(argv[i]) == MagickFalse)
5807              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5808            break;
5809          }
5810        if (LocaleCompare("synchronize",option+1) == 0)
5811          break;
5812        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5813      }
5814      case 't':
5815      {
5816        if (LocaleCompare("taint",option+1) == 0)
5817          break;
5818        if (LocaleCompare("texture",option+1) == 0)
5819          {
5820            if (*option == '+')
5821              break;
5822            i++;
5823            if (i == (ssize_t) argc)
5824              ThrowMogrifyException(OptionError,"MissingArgument",option);
5825            break;
5826          }
5827        if (LocaleCompare("tile",option+1) == 0)
5828          {
5829            if (*option == '+')
5830              break;
5831            i++;
5832            if (i == (ssize_t) (argc-1))
5833              ThrowMogrifyException(OptionError,"MissingArgument",option);
5834            break;
5835          }
5836        if (LocaleCompare("tile-offset",option+1) == 0)
5837          {
5838            if (*option == '+')
5839              break;
5840            i++;
5841            if (i == (ssize_t) argc)
5842              ThrowMogrifyException(OptionError,"MissingArgument",option);
5843            if (IsGeometry(argv[i]) == MagickFalse)
5844              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5845            break;
5846          }
5847        if (LocaleCompare("tint",option+1) == 0)
5848          {
5849            if (*option == '+')
5850              break;
5851            i++;
5852            if (i == (ssize_t) (argc-1))
5853              ThrowMogrifyException(OptionError,"MissingArgument",option);
5854            if (IsGeometry(argv[i]) == MagickFalse)
5855              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5856            break;
5857          }
5858        if (LocaleCompare("transform",option+1) == 0)
5859          break;
5860        if (LocaleCompare("transpose",option+1) == 0)
5861          break;
5862        if (LocaleCompare("transverse",option+1) == 0)
5863          break;
5864        if (LocaleCompare("threshold",option+1) == 0)
5865          {
5866            if (*option == '+')
5867              break;
5868            i++;
5869            if (i == (ssize_t) argc)
5870              ThrowMogrifyException(OptionError,"MissingArgument",option);
5871            if (IsGeometry(argv[i]) == MagickFalse)
5872              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5873            break;
5874          }
5875        if (LocaleCompare("thumbnail",option+1) == 0)
5876          {
5877            if (*option == '+')
5878              break;
5879            i++;
5880            if (i == (ssize_t) argc)
5881              ThrowMogrifyException(OptionError,"MissingArgument",option);
5882            if (IsGeometry(argv[i]) == MagickFalse)
5883              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5884            break;
5885          }
5886        if (LocaleCompare("transparent",option+1) == 0)
5887          {
5888            i++;
5889            if (i == (ssize_t) argc)
5890              ThrowMogrifyException(OptionError,"MissingArgument",option);
5891            break;
5892          }
5893        if (LocaleCompare("transparent-color",option+1) == 0)
5894          {
5895            if (*option == '+')
5896              break;
5897            i++;
5898            if (i == (ssize_t) (argc-1))
5899              ThrowMogrifyException(OptionError,"MissingArgument",option);
5900            break;
5901          }
5902        if (LocaleCompare("treedepth",option+1) == 0)
5903          {
5904            if (*option == '+')
5905              break;
5906            i++;
5907            if (i == (ssize_t) argc)
5908              ThrowMogrifyException(OptionError,"MissingArgument",option);
5909            if (IsGeometry(argv[i]) == MagickFalse)
5910              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5911            break;
5912          }
5913        if (LocaleCompare("trim",option+1) == 0)
5914          break;
5915        if (LocaleCompare("type",option+1) == 0)
5916          {
5917            ssize_t
5918              type;
5919
5920            if (*option == '+')
5921              break;
5922            i++;
5923            if (i == (ssize_t) argc)
5924              ThrowMogrifyException(OptionError,"MissingArgument",option);
5925            type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]);
5926            if (type < 0)
5927              ThrowMogrifyException(OptionError,"UnrecognizedImageType",
5928                argv[i]);
5929            break;
5930          }
5931        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5932      }
5933      case 'u':
5934      {
5935        if (LocaleCompare("undercolor",option+1) == 0)
5936          {
5937            if (*option == '+')
5938              break;
5939            i++;
5940            if (i == (ssize_t) argc)
5941              ThrowMogrifyException(OptionError,"MissingArgument",option);
5942            break;
5943          }
5944        if (LocaleCompare("unique-colors",option+1) == 0)
5945          break;
5946        if (LocaleCompare("units",option+1) == 0)
5947          {
5948            ssize_t
5949              units;
5950
5951            if (*option == '+')
5952              break;
5953            i++;
5954            if (i == (ssize_t) argc)
5955              ThrowMogrifyException(OptionError,"MissingArgument",option);
5956            units=ParseCommandOption(MagickResolutionOptions,MagickFalse,
5957              argv[i]);
5958            if (units < 0)
5959              ThrowMogrifyException(OptionError,"UnrecognizedUnitsType",
5960                argv[i]);
5961            break;
5962          }
5963        if (LocaleCompare("unsharp",option+1) == 0)
5964          {
5965            i++;
5966            if (i == (ssize_t) argc)
5967              ThrowMogrifyException(OptionError,"MissingArgument",option);
5968            if (IsGeometry(argv[i]) == MagickFalse)
5969              ThrowMogrifyInvalidArgumentException(option,argv[i]);
5970            break;
5971          }
5972        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5973      }
5974      case 'v':
5975      {
5976        if (LocaleCompare("verbose",option+1) == 0)
5977          {
5978            image_info->verbose=(*option == '-') ? MagickTrue : MagickFalse;
5979            break;
5980          }
5981        if ((LocaleCompare("version",option+1) == 0) ||
5982            (LocaleCompare("-version",option+1) == 0))
5983          {
5984            (void) FormatLocaleFile(stdout,"Version: %s\n",
5985              GetMagickVersion((size_t *) NULL));
5986            (void) FormatLocaleFile(stdout,"Copyright: %s\n",
5987              GetMagickCopyright());
5988            (void) FormatLocaleFile(stdout,"Features: %s\n\n",
5989              GetMagickFeatures());
5990            break;
5991          }
5992        if (LocaleCompare("view",option+1) == 0)
5993          {
5994            if (*option == '+')
5995              break;
5996            i++;
5997            if (i == (ssize_t) argc)
5998              ThrowMogrifyException(OptionError,"MissingArgument",option);
5999            break;
6000          }
6001        if (LocaleCompare("vignette",option+1) == 0)
6002          {
6003            if (*option == '+')
6004              break;
6005            i++;
6006            if (i == (ssize_t) argc)
6007              ThrowMogrifyException(OptionError,"MissingArgument",option);
6008            if (IsGeometry(argv[i]) == MagickFalse)
6009              ThrowMogrifyInvalidArgumentException(option,argv[i]);
6010            break;
6011          }
6012        if (LocaleCompare("virtual-pixel",option+1) == 0)
6013          {
6014            ssize_t
6015              method;
6016
6017            if (*option == '+')
6018              break;
6019            i++;
6020            if (i == (ssize_t) argc)
6021              ThrowMogrifyException(OptionError,"MissingArgument",option);
6022            method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
6023              argv[i]);
6024            if (method < 0)
6025              ThrowMogrifyException(OptionError,
6026                "UnrecognizedVirtualPixelMethod",argv[i]);
6027            break;
6028          }
6029        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
6030      }
6031      case 'w':
6032      {
6033        if (LocaleCompare("wave",option+1) == 0)
6034          {
6035            i++;
6036            if (i == (ssize_t) argc)
6037              ThrowMogrifyException(OptionError,"MissingArgument",option);
6038            if (IsGeometry(argv[i]) == MagickFalse)
6039              ThrowMogrifyInvalidArgumentException(option,argv[i]);
6040            break;
6041          }
6042        if (LocaleCompare("weight",option+1) == 0)
6043          {
6044            if (*option == '+')
6045              break;
6046            i++;
6047            if (i == (ssize_t) (argc-1))
6048              ThrowMogrifyException(OptionError,"MissingArgument",option);
6049            break;
6050          }
6051        if (LocaleCompare("white-point",option+1) == 0)
6052          {
6053            if (*option == '+')
6054              break;
6055            i++;
6056            if (i == (ssize_t) argc)
6057              ThrowMogrifyException(OptionError,"MissingArgument",option);
6058            if (IsGeometry(argv[i]) == MagickFalse)
6059              ThrowMogrifyInvalidArgumentException(option,argv[i]);
6060            break;
6061          }
6062        if (LocaleCompare("white-threshold",option+1) == 0)
6063          {
6064            if (*option == '+')
6065              break;
6066            i++;
6067            if (i == (ssize_t) argc)
6068              ThrowMogrifyException(OptionError,"MissingArgument",option);
6069            if (IsGeometry(argv[i]) == MagickFalse)
6070              ThrowMogrifyInvalidArgumentException(option,argv[i]);
6071            break;
6072          }
6073        if (LocaleCompare("write",option+1) == 0)
6074          {
6075            i++;
6076            if (i == (ssize_t) (argc-1))
6077              ThrowMogrifyException(OptionError,"MissingArgument",option);
6078            break;
6079          }
6080        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
6081      }
6082      case '?':
6083        break;
6084      default:
6085        ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
6086    }
6087    fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
6088      FireOptionFlag) == 0 ?  MagickFalse : MagickTrue;
6089    if (fire != MagickFalse)
6090      FireImageStack(MagickFalse,MagickTrue,MagickTrue);
6091  }
6092  if (k != 0)
6093    ThrowMogrifyException(OptionError,"UnbalancedParenthesis",argv[i]);
6094  if (i != (ssize_t) argc)
6095    ThrowMogrifyException(OptionError,"MissingAnImageFilename",argv[i]);
6096  DestroyMogrify();
6097  return(status != 0 ? MagickTrue : MagickFalse);
6098}
6099
6100/*
6101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6102%                                                                             %
6103%                                                                             %
6104%                                                                             %
6105+     M o g r i f y I m a g e I n f o                                         %
6106%                                                                             %
6107%                                                                             %
6108%                                                                             %
6109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6110%
6111%  MogrifyImageInfo() applies image processing settings to the image as
6112%  prescribed by command line options.
6113%
6114%  The format of the MogrifyImageInfo method is:
6115%
6116%      MagickBooleanType MogrifyImageInfo(ImageInfo *image_info,const int argc,
6117%        const char **argv,ExceptionInfo *exception)
6118%
6119%  A description of each parameter follows:
6120%
6121%    o image_info: the image info..
6122%
6123%    o argc: Specifies a pointer to an integer describing the number of
6124%      elements in the argument vector.
6125%
6126%    o argv: Specifies a pointer to a text array containing the command line
6127%      arguments.
6128%
6129%    o exception: return any errors or warnings in this structure.
6130%
6131*/
6132WandExport MagickBooleanType MogrifyImageInfo(ImageInfo *image_info,
6133  const int argc,const char **argv,ExceptionInfo *exception)
6134{
6135  const char
6136    *option;
6137
6138  GeometryInfo
6139    geometry_info;
6140
6141  ssize_t
6142    count;
6143
6144  register ssize_t
6145    i;
6146
6147  /*
6148    Initialize method variables.
6149  */
6150  assert(image_info != (ImageInfo *) NULL);
6151  assert(image_info->signature == MagickSignature);
6152  if (image_info->debug != MagickFalse)
6153    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
6154      image_info->filename);
6155  if (argc < 0)
6156    return(MagickTrue);
6157  /*
6158    Set the image settings.
6159  */
6160  for (i=0; i < (ssize_t) argc; i++)
6161  {
6162    option=argv[i];
6163    if (IsCommandOption(option) == MagickFalse)
6164      continue;
6165    count=ParseCommandOption(MagickCommandOptions,MagickFalse,option);
6166    count=MagickMax(count,0L);
6167    if ((i+count) >= (ssize_t) argc)
6168      break;
6169    switch (*(option+1))
6170    {
6171      case 'a':
6172      {
6173        if (LocaleCompare("adjoin",option+1) == 0)
6174          {
6175            image_info->adjoin=(*option == '-') ? MagickTrue : MagickFalse;
6176            break;
6177          }
6178        if (LocaleCompare("antialias",option+1) == 0)
6179          {
6180            image_info->antialias=(*option == '-') ? MagickTrue : MagickFalse;
6181            break;
6182          }
6183        if (LocaleCompare("authenticate",option+1) == 0)
6184          {
6185            if (*option == '+')
6186              (void) DeleteImageOption(image_info,option+1);
6187            else
6188              (void) SetImageOption(image_info,option+1,argv[i+1]);
6189            break;
6190          }
6191        break;
6192      }
6193      case 'b':
6194      {
6195        if (LocaleCompare("background",option+1) == 0)
6196          {
6197            if (*option == '+')
6198              {
6199                (void) DeleteImageOption(image_info,option+1);
6200                (void) QueryColorCompliance(MogrifyBackgroundColor,
6201                  AllCompliance,&image_info->background_color,exception);
6202                break;
6203              }
6204            (void) SetImageOption(image_info,option+1,argv[i+1]);
6205            (void) QueryColorCompliance(argv[i+1],AllCompliance,
6206              &image_info->background_color,exception);
6207            break;
6208          }
6209        if (LocaleCompare("bias",option+1) == 0)
6210          {
6211            if (*option == '+')
6212              {
6213                (void) SetImageOption(image_info,option+1,"0.0");
6214                break;
6215              }
6216            (void) SetImageOption(image_info,option+1,argv[i+1]);
6217            break;
6218          }
6219        if (LocaleCompare("black-point-compensation",option+1) == 0)
6220          {
6221            if (*option == '+')
6222              {
6223                (void) SetImageOption(image_info,option+1,"false");
6224                break;
6225              }
6226            (void) SetImageOption(image_info,option+1,"true");
6227            break;
6228          }
6229        if (LocaleCompare("blue-primary",option+1) == 0)
6230          {
6231            if (*option == '+')
6232              {
6233                (void) SetImageOption(image_info,option+1,"0.0");
6234                break;
6235              }
6236            (void) SetImageOption(image_info,option+1,argv[i+1]);
6237            break;
6238          }
6239        if (LocaleCompare("bordercolor",option+1) == 0)
6240          {
6241            if (*option == '+')
6242              {
6243                (void) DeleteImageOption(image_info,option+1);
6244                (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
6245                  &image_info->border_color,exception);
6246                break;
6247              }
6248            (void) QueryColorCompliance(argv[i+1],AllCompliance,
6249              &image_info->border_color,exception);
6250            (void) SetImageOption(image_info,option+1,argv[i+1]);
6251            break;
6252          }
6253        if (LocaleCompare("box",option+1) == 0)
6254          {
6255            if (*option == '+')
6256              {
6257                (void) SetImageOption(image_info,"undercolor","none");
6258                break;
6259              }
6260            (void) SetImageOption(image_info,"undercolor",argv[i+1]);
6261            break;
6262          }
6263        break;
6264      }
6265      case 'c':
6266      {
6267        if (LocaleCompare("cache",option+1) == 0)
6268          {
6269            MagickSizeType
6270              limit;
6271
6272            limit=MagickResourceInfinity;
6273            if (LocaleCompare("unlimited",argv[i+1]) != 0)
6274              limit=(MagickSizeType) SiPrefixToDoubleInterval(argv[i+1],
6275                100.0);
6276            (void) SetMagickResourceLimit(MemoryResource,limit);
6277            (void) SetMagickResourceLimit(MapResource,2*limit);
6278            break;
6279          }
6280        if (LocaleCompare("caption",option+1) == 0)
6281          {
6282            if (*option == '+')
6283              {
6284                (void) DeleteImageOption(image_info,option+1);
6285                break;
6286              }
6287            (void) SetImageOption(image_info,option+1,argv[i+1]);
6288            break;
6289          }
6290        if (LocaleCompare("channel",option+1) == 0)
6291          {
6292            if (*option == '+')
6293              {
6294                image_info->channel=DefaultChannels;
6295                (void) SetImageOption(image_info,option+1,"default");
6296                break;
6297              }
6298            image_info->channel=(ChannelType) ParseChannelOption(argv[i+1]);
6299            (void) SetImageOption(image_info,option+1,argv[i+1]);
6300            break;
6301          }
6302        if (LocaleCompare("colorspace",option+1) == 0)
6303          {
6304            if (*option == '+')
6305              {
6306                image_info->colorspace=UndefinedColorspace;
6307                (void) SetImageOption(image_info,option+1,"undefined");
6308                break;
6309              }
6310            image_info->colorspace=(ColorspaceType) ParseCommandOption(
6311              MagickColorspaceOptions,MagickFalse,argv[i+1]);
6312            (void) SetImageOption(image_info,option+1,argv[i+1]);
6313            break;
6314          }
6315        if (LocaleCompare("comment",option+1) == 0)
6316          {
6317            if (*option == '+')
6318              {
6319                (void) DeleteImageOption(image_info,option+1);
6320                break;
6321              }
6322            (void) SetImageOption(image_info,option+1,argv[i+1]);
6323            break;
6324          }
6325        if (LocaleCompare("compose",option+1) == 0)
6326          {
6327            if (*option == '+')
6328              {
6329                (void) SetImageOption(image_info,option+1,"undefined");
6330                break;
6331              }
6332            (void) SetImageOption(image_info,option+1,argv[i+1]);
6333            break;
6334          }
6335        if (LocaleCompare("compress",option+1) == 0)
6336          {
6337            if (*option == '+')
6338              {
6339                image_info->compression=UndefinedCompression;
6340                (void) SetImageOption(image_info,option+1,"undefined");
6341                break;
6342              }
6343            image_info->compression=(CompressionType) ParseCommandOption(
6344              MagickCompressOptions,MagickFalse,argv[i+1]);
6345            (void) SetImageOption(image_info,option+1,argv[i+1]);
6346            break;
6347          }
6348        break;
6349      }
6350      case 'd':
6351      {
6352        if (LocaleCompare("debug",option+1) == 0)
6353          {
6354            if (*option == '+')
6355              (void) SetLogEventMask("none");
6356            else
6357              (void) SetLogEventMask(argv[i+1]);
6358            image_info->debug=IsEventLogging();
6359            break;
6360          }
6361        if (LocaleCompare("define",option+1) == 0)
6362          {
6363            if (*option == '+')
6364              {
6365                if (LocaleNCompare(argv[i+1],"registry:",9) == 0)
6366                  (void) DeleteImageRegistry(argv[i+1]+9);
6367                else
6368                  (void) DeleteImageOption(image_info,argv[i+1]);
6369                break;
6370              }
6371            if (LocaleNCompare(argv[i+1],"registry:",9) == 0)
6372              {
6373                (void) DefineImageRegistry(StringRegistryType,argv[i+1]+9,
6374                  exception);
6375                break;
6376              }
6377            (void) DefineImageOption(image_info,argv[i+1]);
6378            break;
6379          }
6380        if (LocaleCompare("delay",option+1) == 0)
6381          {
6382            if (*option == '+')
6383              {
6384                (void) SetImageOption(image_info,option+1,"0");
6385                break;
6386              }
6387            (void) SetImageOption(image_info,option+1,argv[i+1]);
6388            break;
6389          }
6390        if (LocaleCompare("density",option+1) == 0)
6391          {
6392            /*
6393              Set image density.
6394            */
6395            if (*option == '+')
6396              {
6397                if (image_info->density != (char *) NULL)
6398                  image_info->density=DestroyString(image_info->density);
6399                (void) SetImageOption(image_info,option+1,"72");
6400                break;
6401              }
6402            (void) CloneString(&image_info->density,argv[i+1]);
6403            (void) SetImageOption(image_info,option+1,argv[i+1]);
6404            break;
6405          }
6406        if (LocaleCompare("depth",option+1) == 0)
6407          {
6408            if (*option == '+')
6409              {
6410                image_info->depth=MAGICKCORE_QUANTUM_DEPTH;
6411                break;
6412              }
6413            image_info->depth=StringToUnsignedLong(argv[i+1]);
6414            break;
6415          }
6416        if (LocaleCompare("direction",option+1) == 0)
6417          {
6418            if (*option == '+')
6419              {
6420                (void) SetImageOption(image_info,option+1,"undefined");
6421                break;
6422              }
6423            (void) SetImageOption(image_info,option+1,argv[i+1]);
6424            break;
6425          }
6426        if (LocaleCompare("display",option+1) == 0)
6427          {
6428            if (*option == '+')
6429              {
6430                if (image_info->server_name != (char *) NULL)
6431                  image_info->server_name=DestroyString(
6432                    image_info->server_name);
6433                break;
6434              }
6435            (void) CloneString(&image_info->server_name,argv[i+1]);
6436            break;
6437          }
6438        if (LocaleCompare("dispose",option+1) == 0)
6439          {
6440            if (*option == '+')
6441              {
6442                (void) SetImageOption(image_info,option+1,"undefined");
6443                break;
6444              }
6445            (void) SetImageOption(image_info,option+1,argv[i+1]);
6446            break;
6447          }
6448        if (LocaleCompare("dither",option+1) == 0)
6449          {
6450            if (*option == '+')
6451              {
6452                image_info->dither=MagickFalse;
6453                (void) SetImageOption(image_info,option+1,"none");
6454                break;
6455              }
6456            (void) SetImageOption(image_info,option+1,argv[i+1]);
6457            image_info->dither=MagickTrue;
6458            break;
6459          }
6460        break;
6461      }
6462      case 'e':
6463      {
6464        if (LocaleCompare("encoding",option+1) == 0)
6465          {
6466            if (*option == '+')
6467              {
6468                (void) SetImageOption(image_info,option+1,"undefined");
6469                break;
6470              }
6471            (void) SetImageOption(image_info,option+1,argv[i+1]);
6472            break;
6473          }
6474        if (LocaleCompare("endian",option+1) == 0)
6475          {
6476            if (*option == '+')
6477              {
6478                image_info->endian=UndefinedEndian;
6479                (void) SetImageOption(image_info,option+1,"undefined");
6480                break;
6481              }
6482            image_info->endian=(EndianType) ParseCommandOption(
6483              MagickEndianOptions,MagickFalse,argv[i+1]);
6484            (void) SetImageOption(image_info,option+1,argv[i+1]);
6485            break;
6486          }
6487        if (LocaleCompare("extract",option+1) == 0)
6488          {
6489            /*
6490              Set image extract geometry.
6491            */
6492            if (*option == '+')
6493              {
6494                if (image_info->extract != (char *) NULL)
6495                  image_info->extract=DestroyString(image_info->extract);
6496                break;
6497              }
6498            (void) CloneString(&image_info->extract,argv[i+1]);
6499            break;
6500          }
6501        break;
6502      }
6503      case 'f':
6504      {
6505        if (LocaleCompare("fill",option+1) == 0)
6506          {
6507            if (*option == '+')
6508              {
6509                (void) SetImageOption(image_info,option+1,"none");
6510                break;
6511              }
6512            (void) SetImageOption(image_info,option+1,argv[i+1]);
6513            break;
6514          }
6515        if (LocaleCompare("filter",option+1) == 0)
6516          {
6517            if (*option == '+')
6518              {
6519                (void) SetImageOption(image_info,option+1,"undefined");
6520                break;
6521              }
6522            (void) SetImageOption(image_info,option+1,argv[i+1]);
6523            break;
6524          }
6525        if (LocaleCompare("font",option+1) == 0)
6526          {
6527            if (*option == '+')
6528              {
6529                if (image_info->font != (char *) NULL)
6530                  image_info->font=DestroyString(image_info->font);
6531                break;
6532              }
6533            (void) CloneString(&image_info->font,argv[i+1]);
6534            break;
6535          }
6536        if (LocaleCompare("format",option+1) == 0)
6537          {
6538            register const char
6539              *q;
6540
6541            for (q=strchr(argv[i+1],'%'); q != (char *) NULL; q=strchr(q+1,'%'))
6542              if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
6543                image_info->ping=MagickFalse;
6544            (void) SetImageOption(image_info,option+1,argv[i+1]);
6545            break;
6546          }
6547        if (LocaleCompare("fuzz",option+1) == 0)
6548          {
6549            if (*option == '+')
6550              {
6551                image_info->fuzz=0.0;
6552                (void) SetImageOption(image_info,option+1,"0");
6553                break;
6554              }
6555            image_info->fuzz=StringToDoubleInterval(argv[i+1],(double)
6556              QuantumRange+1.0);
6557            (void) SetImageOption(image_info,option+1,argv[i+1]);
6558            break;
6559          }
6560        break;
6561      }
6562      case 'g':
6563      {
6564        if (LocaleCompare("gravity",option+1) == 0)
6565          {
6566            if (*option == '+')
6567              {
6568                (void) SetImageOption(image_info,option+1,"undefined");
6569                break;
6570              }
6571            (void) SetImageOption(image_info,option+1,argv[i+1]);
6572            break;
6573          }
6574        if (LocaleCompare("green-primary",option+1) == 0)
6575          {
6576            if (*option == '+')
6577              {
6578                (void) SetImageOption(image_info,option+1,"0.0");
6579                break;
6580              }
6581            (void) SetImageOption(image_info,option+1,argv[i+1]);
6582            break;
6583          }
6584        break;
6585      }
6586      case 'i':
6587      {
6588        if (LocaleCompare("intent",option+1) == 0)
6589          {
6590            if (*option == '+')
6591              {
6592                (void) SetImageOption(image_info,option+1,"undefined");
6593                break;
6594              }
6595            (void) SetImageOption(image_info,option+1,argv[i+1]);
6596            break;
6597          }
6598        if (LocaleCompare("interlace",option+1) == 0)
6599          {
6600            if (*option == '+')
6601              {
6602                image_info->interlace=UndefinedInterlace;
6603                (void) SetImageOption(image_info,option+1,"undefined");
6604                break;
6605              }
6606            image_info->interlace=(InterlaceType) ParseCommandOption(
6607              MagickInterlaceOptions,MagickFalse,argv[i+1]);
6608            (void) SetImageOption(image_info,option+1,argv[i+1]);
6609            break;
6610          }
6611        if (LocaleCompare("interline-spacing",option+1) == 0)
6612          {
6613            if (*option == '+')
6614              {
6615                (void) SetImageOption(image_info,option+1,"undefined");
6616                break;
6617              }
6618            (void) SetImageOption(image_info,option+1,argv[i+1]);
6619            break;
6620          }
6621        if (LocaleCompare("interpolate",option+1) == 0)
6622          {
6623            if (*option == '+')
6624              {
6625                (void) SetImageOption(image_info,option+1,"undefined");
6626                break;
6627              }
6628            (void) SetImageOption(image_info,option+1,argv[i+1]);
6629            break;
6630          }
6631        if (LocaleCompare("interword-spacing",option+1) == 0)
6632          {
6633            if (*option == '+')
6634              {
6635                (void) SetImageOption(image_info,option+1,"undefined");
6636                break;
6637              }
6638            (void) SetImageOption(image_info,option+1,argv[i+1]);
6639            break;
6640          }
6641        break;
6642      }
6643      case 'k':
6644      {
6645        if (LocaleCompare("kerning",option+1) == 0)
6646          {
6647            if (*option == '+')
6648              {
6649                (void) SetImageOption(image_info,option+1,"undefined");
6650                break;
6651              }
6652            (void) SetImageOption(image_info,option+1,argv[i+1]);
6653            break;
6654          }
6655        break;
6656      }
6657      case 'l':
6658      {
6659        if (LocaleCompare("label",option+1) == 0)
6660          {
6661            if (*option == '+')
6662              {
6663                (void) DeleteImageOption(image_info,option+1);
6664                break;
6665              }
6666            (void) SetImageOption(image_info,option+1,argv[i+1]);
6667            break;
6668          }
6669        if (LocaleCompare("limit",option+1) == 0)
6670          {
6671            MagickSizeType
6672              limit;
6673
6674            ResourceType
6675              type;
6676
6677            if (*option == '+')
6678              break;
6679            type=(ResourceType) ParseCommandOption(MagickResourceOptions,
6680              MagickFalse,argv[i+1]);
6681            limit=MagickResourceInfinity;
6682            if (LocaleCompare("unlimited",argv[i+2]) != 0)
6683              limit=(MagickSizeType) SiPrefixToDoubleInterval(argv[i+2],100.0);
6684            (void) SetMagickResourceLimit(type,limit);
6685            break;
6686          }
6687        if (LocaleCompare("list",option+1) == 0)
6688          {
6689            ssize_t
6690              list;
6691
6692            /*
6693              Display configuration list.
6694            */
6695            list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i+1]);
6696            switch (list)
6697            {
6698              case MagickCoderOptions:
6699              {
6700                (void) ListCoderInfo((FILE *) NULL,exception);
6701                break;
6702              }
6703              case MagickColorOptions:
6704              {
6705                (void) ListColorInfo((FILE *) NULL,exception);
6706                break;
6707              }
6708              case MagickConfigureOptions:
6709              {
6710                (void) ListConfigureInfo((FILE *) NULL,exception);
6711                break;
6712              }
6713              case MagickDelegateOptions:
6714              {
6715                (void) ListDelegateInfo((FILE *) NULL,exception);
6716                break;
6717              }
6718              case MagickFontOptions:
6719              {
6720                (void) ListTypeInfo((FILE *) NULL,exception);
6721                break;
6722              }
6723              case MagickFormatOptions:
6724              {
6725                (void) ListMagickInfo((FILE *) NULL,exception);
6726                break;
6727              }
6728              case MagickLocaleOptions:
6729              {
6730                (void) ListLocaleInfo((FILE *) NULL,exception);
6731                break;
6732              }
6733              case MagickLogOptions:
6734              {
6735                (void) ListLogInfo((FILE *) NULL,exception);
6736                break;
6737              }
6738              case MagickMagicOptions:
6739              {
6740                (void) ListMagicInfo((FILE *) NULL,exception);
6741                break;
6742              }
6743              case MagickMimeOptions:
6744              {
6745                (void) ListMimeInfo((FILE *) NULL,exception);
6746                break;
6747              }
6748              case MagickModuleOptions:
6749              {
6750                (void) ListModuleInfo((FILE *) NULL,exception);
6751                break;
6752              }
6753              case MagickPolicyOptions:
6754              {
6755                (void) ListPolicyInfo((FILE *) NULL,exception);
6756                break;
6757              }
6758              case MagickResourceOptions:
6759              {
6760                (void) ListMagickResourceInfo((FILE *) NULL,exception);
6761                break;
6762              }
6763              case MagickThresholdOptions:
6764              {
6765                (void) ListThresholdMaps((FILE *) NULL,exception);
6766                break;
6767              }
6768              default:
6769              {
6770                (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
6771                  exception);
6772                break;
6773              }
6774            }
6775            break;
6776          }
6777        if (LocaleCompare("log",option+1) == 0)
6778          {
6779            if (*option == '+')
6780              break;
6781            (void) SetLogFormat(argv[i+1]);
6782            break;
6783          }
6784        if (LocaleCompare("loop",option+1) == 0)
6785          {
6786            if (*option == '+')
6787              {
6788                (void) SetImageOption(image_info,option+1,"0");
6789                break;
6790              }
6791            (void) SetImageOption(image_info,option+1,argv[i+1]);
6792            break;
6793          }
6794        break;
6795      }
6796      case 'm':
6797      {
6798        if (LocaleCompare("matte",option+1) == 0)
6799          {
6800            if (*option == '+')
6801              {
6802                (void) SetImageOption(image_info,option+1,"false");
6803                break;
6804              }
6805            (void) SetImageOption(image_info,option+1,"true");
6806            break;
6807          }
6808        if (LocaleCompare("mattecolor",option+1) == 0)
6809          {
6810            if (*option == '+')
6811              {
6812                (void) SetImageOption(image_info,option+1,argv[i+1]);
6813                (void) QueryColorCompliance(MogrifyMatteColor,AllCompliance,
6814                  &image_info->matte_color,exception);
6815                break;
6816              }
6817            (void) SetImageOption(image_info,option+1,argv[i+1]);
6818            (void) QueryColorCompliance(argv[i+1],AllCompliance,
6819              &image_info->matte_color,exception);
6820            break;
6821          }
6822        if (LocaleCompare("monitor",option+1) == 0)
6823          {
6824            (void) SetImageInfoProgressMonitor(image_info,MonitorProgress,
6825              (void *) NULL);
6826            break;
6827          }
6828        if (LocaleCompare("monochrome",option+1) == 0)
6829          {
6830            image_info->monochrome=(*option == '-') ? MagickTrue : MagickFalse;
6831            break;
6832          }
6833        break;
6834      }
6835      case 'o':
6836      {
6837        if (LocaleCompare("orient",option+1) == 0)
6838          {
6839            if (*option == '+')
6840              {
6841                image_info->orientation=UndefinedOrientation;
6842                (void) SetImageOption(image_info,option+1,"undefined");
6843                break;
6844              }
6845            image_info->orientation=(OrientationType) ParseCommandOption(
6846              MagickOrientationOptions,MagickFalse,argv[i+1]);
6847            (void) SetImageOption(image_info,option+1,argv[i+1]);
6848            break;
6849          }
6850      }
6851      case 'p':
6852      {
6853        if (LocaleCompare("page",option+1) == 0)
6854          {
6855            char
6856              *canonical_page,
6857              page[MaxTextExtent];
6858
6859            const char
6860              *image_option;
6861
6862            MagickStatusType
6863              flags;
6864
6865            RectangleInfo
6866              geometry;
6867
6868            if (*option == '+')
6869              {
6870                (void) DeleteImageOption(image_info,option+1);
6871                (void) CloneString(&image_info->page,(char *) NULL);
6872                break;
6873              }
6874            (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6875            image_option=GetImageOption(image_info,"page");
6876            if (image_option != (const char *) NULL)
6877              flags=ParseAbsoluteGeometry(image_option,&geometry);
6878            canonical_page=GetPageGeometry(argv[i+1]);
6879            flags=ParseAbsoluteGeometry(canonical_page,&geometry);
6880            canonical_page=DestroyString(canonical_page);
6881            (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
6882              (unsigned long) geometry.width,(unsigned long) geometry.height);
6883            if (((flags & XValue) != 0) || ((flags & YValue) != 0))
6884              (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
6885                (unsigned long) geometry.width,(unsigned long) geometry.height,
6886                (long) geometry.x,(long) geometry.y);
6887            (void) SetImageOption(image_info,option+1,page);
6888            (void) CloneString(&image_info->page,page);
6889            break;
6890          }
6891        if (LocaleCompare("ping",option+1) == 0)
6892          {
6893            image_info->ping=(*option == '-') ? MagickTrue : MagickFalse;
6894            break;
6895          }
6896        if (LocaleCompare("pointsize",option+1) == 0)
6897          {
6898            if (*option == '+')
6899              geometry_info.rho=0.0;
6900            else
6901              (void) ParseGeometry(argv[i+1],&geometry_info);
6902            image_info->pointsize=geometry_info.rho;
6903            break;
6904          }
6905        if (LocaleCompare("precision",option+1) == 0)
6906          {
6907            (void) SetMagickPrecision(StringToInteger(argv[i+1]));
6908            break;
6909          }
6910        if (LocaleCompare("preview",option+1) == 0)
6911          {
6912            /*
6913              Preview image.
6914            */
6915            if (*option == '+')
6916              {
6917                image_info->preview_type=UndefinedPreview;
6918                break;
6919              }
6920            image_info->preview_type=(PreviewType) ParseCommandOption(
6921              MagickPreviewOptions,MagickFalse,argv[i+1]);
6922            break;
6923          }
6924        break;
6925      }
6926      case 'q':
6927      {
6928        if (LocaleCompare("quality",option+1) == 0)
6929          {
6930            /*
6931              Set image compression quality.
6932            */
6933            if (*option == '+')
6934              {
6935                image_info->quality=UndefinedCompressionQuality;
6936                (void) SetImageOption(image_info,option+1,"0");
6937                break;
6938              }
6939            image_info->quality=StringToUnsignedLong(argv[i+1]);
6940            (void) SetImageOption(image_info,option+1,argv[i+1]);
6941            break;
6942          }
6943        if (LocaleCompare("quiet",option+1) == 0)
6944          {
6945            static WarningHandler
6946              warning_handler = (WarningHandler) NULL;
6947
6948            if (*option == '+')
6949              {
6950                /*
6951                  Restore error or warning messages.
6952                */
6953                warning_handler=SetWarningHandler(warning_handler);
6954                break;
6955              }
6956            /*
6957              Suppress error or warning messages.
6958            */
6959            warning_handler=SetWarningHandler((WarningHandler) NULL);
6960            break;
6961          }
6962        break;
6963      }
6964      case 'r':
6965      {
6966        if (LocaleCompare("red-primary",option+1) == 0)
6967          {
6968            if (*option == '+')
6969              {
6970                (void) SetImageOption(image_info,option+1,"0.0");
6971                break;
6972              }
6973            (void) SetImageOption(image_info,option+1,argv[i+1]);
6974            break;
6975          }
6976        break;
6977      }
6978      case 's':
6979      {
6980        if (LocaleCompare("sampling-factor",option+1) == 0)
6981          {
6982            /*
6983              Set image sampling factor.
6984            */
6985            if (*option == '+')
6986              {
6987                if (image_info->sampling_factor != (char *) NULL)
6988                  image_info->sampling_factor=DestroyString(
6989                    image_info->sampling_factor);
6990                break;
6991              }
6992            (void) CloneString(&image_info->sampling_factor,argv[i+1]);
6993            break;
6994          }
6995        if (LocaleCompare("scene",option+1) == 0)
6996          {
6997            /*
6998              Set image scene.
6999            */
7000            if (*option == '+')
7001              {
7002                image_info->scene=0;
7003                (void) SetImageOption(image_info,option+1,"0");
7004                break;
7005              }
7006            image_info->scene=StringToUnsignedLong(argv[i+1]);
7007            (void) SetImageOption(image_info,option+1,argv[i+1]);
7008            break;
7009          }
7010        if (LocaleCompare("seed",option+1) == 0)
7011          {
7012            size_t
7013              seed;
7014
7015            if (*option == '+')
7016              {
7017                seed=(size_t) time((time_t *) NULL);
7018                SetRandomSecretKey(seed);
7019                break;
7020              }
7021            seed=StringToUnsignedLong(argv[i+1]);
7022            SetRandomSecretKey(seed);
7023            break;
7024          }
7025        if (LocaleCompare("size",option+1) == 0)
7026          {
7027            if (*option == '+')
7028              {
7029                if (image_info->size != (char *) NULL)
7030                  image_info->size=DestroyString(image_info->size);
7031                break;
7032              }
7033            (void) CloneString(&image_info->size,argv[i+1]);
7034            break;
7035          }
7036        if (LocaleCompare("stroke",option+1) == 0)
7037          {
7038            if (*option == '+')
7039              {
7040                (void) SetImageOption(image_info,option+1,"none");
7041                break;
7042              }
7043            (void) SetImageOption(image_info,option+1,argv[i+1]);
7044            break;
7045          }
7046        if (LocaleCompare("strokewidth",option+1) == 0)
7047          {
7048            if (*option == '+')
7049              {
7050                (void) SetImageOption(image_info,option+1,"0");
7051                break;
7052              }
7053            (void) SetImageOption(image_info,option+1,argv[i+1]);
7054            break;
7055          }
7056        if (LocaleCompare("synchronize",option+1) == 0)
7057          {
7058            if (*option == '+')
7059              {
7060                image_info->synchronize=MagickFalse;
7061                break;
7062              }
7063            image_info->synchronize=MagickTrue;
7064            break;
7065          }
7066        break;
7067      }
7068      case 't':
7069      {
7070        if (LocaleCompare("taint",option+1) == 0)
7071          {
7072            if (*option == '+')
7073              {
7074                (void) SetImageOption(image_info,option+1,"false");
7075                break;
7076              }
7077            (void) SetImageOption(image_info,option+1,"true");
7078            break;
7079          }
7080        if (LocaleCompare("texture",option+1) == 0)
7081          {
7082            if (*option == '+')
7083              {
7084                if (image_info->texture != (char *) NULL)
7085                  image_info->texture=DestroyString(image_info->texture);
7086                break;
7087              }
7088            (void) CloneString(&image_info->texture,argv[i+1]);
7089            break;
7090          }
7091        if (LocaleCompare("tile-offset",option+1) == 0)
7092          {
7093            if (*option == '+')
7094              (void) SetImageOption(image_info,option+1,"0");
7095            else
7096              (void) SetImageOption(image_info,option+1,argv[i+1]);
7097            break;
7098          }
7099        if (LocaleCompare("transparent-color",option+1) == 0)
7100          {
7101            if (*option == '+')
7102              {
7103                (void) QueryColorCompliance("none",AllCompliance,
7104                  &image_info->transparent_color,exception);
7105                (void) SetImageOption(image_info,option+1,"none");
7106                break;
7107              }
7108            (void) QueryColorCompliance(argv[i+1],AllCompliance,
7109              &image_info->transparent_color,exception);
7110            (void) SetImageOption(image_info,option+1,argv[i+1]);
7111            break;
7112          }
7113        if (LocaleCompare("type",option+1) == 0)
7114          {
7115            if (*option == '+')
7116              {
7117                image_info->type=UndefinedType;
7118                (void) SetImageOption(image_info,option+1,"undefined");
7119                break;
7120              }
7121            image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
7122              MagickFalse,argv[i+1]);
7123            (void) SetImageOption(image_info,option+1,argv[i+1]);
7124            break;
7125          }
7126        break;
7127      }
7128      case 'u':
7129      {
7130        if (LocaleCompare("undercolor",option+1) == 0)
7131          {
7132            if (*option == '+')
7133              (void) DeleteImageOption(image_info,option+1);
7134            else
7135              (void) SetImageOption(image_info,option+1,argv[i+1]);
7136            break;
7137          }
7138        if (LocaleCompare("units",option+1) == 0)
7139          {
7140            if (*option == '+')
7141              {
7142                image_info->units=UndefinedResolution;
7143                (void) SetImageOption(image_info,option+1,"undefined");
7144                break;
7145              }
7146            image_info->units=(ResolutionType) ParseCommandOption(
7147              MagickResolutionOptions,MagickFalse,argv[i+1]);
7148            (void) SetImageOption(image_info,option+1,argv[i+1]);
7149            break;
7150          }
7151        break;
7152      }
7153      case 'v':
7154      {
7155        if (LocaleCompare("verbose",option+1) == 0)
7156          {
7157            if (*option == '+')
7158              {
7159                image_info->verbose=MagickFalse;
7160                break;
7161              }
7162            image_info->verbose=MagickTrue;
7163            image_info->ping=MagickFalse;
7164            break;
7165          }
7166        if (LocaleCompare("view",option+1) == 0)
7167          {
7168            if (*option == '+')
7169              {
7170                if (image_info->view != (char *) NULL)
7171                  image_info->view=DestroyString(image_info->view);
7172                break;
7173              }
7174            (void) CloneString(&image_info->view,argv[i+1]);
7175            break;
7176          }
7177        if (LocaleCompare("virtual-pixel",option+1) == 0)
7178          {
7179            if (*option == '+')
7180              (void) SetImageOption(image_info,option+1,"undefined");
7181            else
7182              (void) SetImageOption(image_info,option+1,argv[i+1]);
7183            break;
7184          }
7185        break;
7186      }
7187      case 'w':
7188      {
7189        if (LocaleCompare("white-point",option+1) == 0)
7190          {
7191            if (*option == '+')
7192              (void) SetImageOption(image_info,option+1,"0.0");
7193            else
7194              (void) SetImageOption(image_info,option+1,argv[i+1]);
7195            break;
7196          }
7197        break;
7198      }
7199      default:
7200        break;
7201    }
7202    i+=count;
7203  }
7204  return(MagickTrue);
7205}
7206
7207/*
7208%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7209%                                                                             %
7210%                                                                             %
7211%                                                                             %
7212+     M o g r i f y I m a g e L i s t                                         %
7213%                                                                             %
7214%                                                                             %
7215%                                                                             %
7216%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7217%
7218%  MogrifyImageList() applies any command line options that might affect the
7219%  entire image list (e.g. -append, -coalesce, etc.).
7220%
7221%  The format of the MogrifyImage method is:
7222%
7223%      MagickBooleanType MogrifyImageList(ImageInfo *image_info,const int argc,
7224%        const char **argv,Image **images,ExceptionInfo *exception)
7225%
7226%  A description of each parameter follows:
7227%
7228%    o image_info: the image info..
7229%
7230%    o argc: Specifies a pointer to an integer describing the number of
7231%      elements in the argument vector.
7232%
7233%    o argv: Specifies a pointer to a text array containing the command line
7234%      arguments.
7235%
7236%    o images: pointer to pointer of the first image in image list.
7237%
7238%    o exception: return any errors or warnings in this structure.
7239%
7240*/
7241WandExport MagickBooleanType MogrifyImageList(ImageInfo *image_info,
7242  const int argc,const char **argv,Image **images,ExceptionInfo *exception)
7243{
7244  const char
7245    *option;
7246
7247  ImageInfo
7248    *mogrify_info;
7249
7250  MagickStatusType
7251    status;
7252
7253  PixelInterpolateMethod
7254   interpolate_method;
7255
7256  QuantizeInfo
7257    *quantize_info;
7258
7259  register ssize_t
7260    i;
7261
7262  ssize_t
7263    count,
7264    index;
7265
7266  /*
7267    Apply options to the image list.
7268  */
7269  assert(image_info != (ImageInfo *) NULL);
7270  assert(image_info->signature == MagickSignature);
7271  assert(images != (Image **) NULL);
7272  assert((*images)->previous == (Image *) NULL);
7273  assert((*images)->signature == MagickSignature);
7274  if ((*images)->debug != MagickFalse)
7275    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7276      (*images)->filename);
7277  if ((argc <= 0) || (*argv == (char *) NULL))
7278    return(MagickTrue);
7279  interpolate_method=UndefinedInterpolatePixel;
7280  mogrify_info=CloneImageInfo(image_info);
7281  quantize_info=AcquireQuantizeInfo(mogrify_info);
7282  status=MagickTrue;
7283  for (i=0; i < (ssize_t) argc; i++)
7284  {
7285    if (*images == (Image *) NULL)
7286      break;
7287    option=argv[i];
7288    if (IsCommandOption(option) == MagickFalse)
7289      continue;
7290    count=ParseCommandOption(MagickCommandOptions,MagickFalse,option);
7291    count=MagickMax(count,0L);
7292    if ((i+count) >= (ssize_t) argc)
7293      break;
7294    status=MogrifyImageInfo(mogrify_info,(int) count+1,argv+i,exception);
7295    switch (*(option+1))
7296    {
7297      case 'a':
7298      {
7299        if (LocaleCompare("affinity",option+1) == 0)
7300          {
7301            (void) SyncImagesSettings(mogrify_info,*images,exception);
7302            if (*option == '+')
7303              {
7304                (void) RemapImages(quantize_info,*images,(Image *) NULL,
7305                  exception);
7306                break;
7307              }
7308            i++;
7309            break;
7310          }
7311        if (LocaleCompare("append",option+1) == 0)
7312          {
7313            Image
7314              *append_image;
7315
7316            (void) SyncImagesSettings(mogrify_info,*images,exception);
7317            append_image=AppendImages(*images,*option == '-' ? MagickTrue :
7318              MagickFalse,exception);
7319            if (append_image == (Image *) NULL)
7320              {
7321                status=MagickFalse;
7322                break;
7323              }
7324            *images=DestroyImageList(*images);
7325            *images=append_image;
7326            break;
7327          }
7328        if (LocaleCompare("average",option+1) == 0)
7329          {
7330            Image
7331              *average_image;
7332
7333            /*
7334              Average an image sequence (deprecated).
7335            */
7336            (void) SyncImagesSettings(mogrify_info,*images,exception);
7337            average_image=EvaluateImages(*images,MeanEvaluateOperator,
7338              exception);
7339            if (average_image == (Image *) NULL)
7340              {
7341                status=MagickFalse;
7342                break;
7343              }
7344            *images=DestroyImageList(*images);
7345            *images=average_image;
7346            break;
7347          }
7348        break;
7349      }
7350      case 'c':
7351      {
7352        if (LocaleCompare("channel-fx",option+1) == 0)
7353          {
7354            Image
7355              *channel_image;
7356
7357            (void) SyncImagesSettings(mogrify_info,*images,exception);
7358            channel_image=ChannelFxImage(*images,argv[i+1],exception);
7359            if (channel_image == (Image *) NULL)
7360              {
7361                status=MagickFalse;
7362                break;
7363              }
7364            *images=DestroyImageList(*images);
7365            *images=channel_image;
7366            break;
7367          }
7368        if (LocaleCompare("clut",option+1) == 0)
7369          {
7370            Image
7371              *clut_image,
7372              *image;
7373
7374            (void) SyncImagesSettings(mogrify_info,*images,exception);
7375            image=RemoveFirstImageFromList(images);
7376            clut_image=RemoveFirstImageFromList(images);
7377            if (clut_image == (Image *) NULL)
7378              {
7379                status=MagickFalse;
7380                break;
7381              }
7382            (void) ClutImage(image,clut_image,interpolate_method,exception);
7383            clut_image=DestroyImage(clut_image);
7384            *images=DestroyImageList(*images);
7385            *images=image;
7386            break;
7387          }
7388        if (LocaleCompare("coalesce",option+1) == 0)
7389          {
7390            Image
7391              *coalesce_image;
7392
7393            (void) SyncImagesSettings(mogrify_info,*images,exception);
7394            coalesce_image=CoalesceImages(*images,exception);
7395            if (coalesce_image == (Image *) NULL)
7396              {
7397                status=MagickFalse;
7398                break;
7399              }
7400            *images=DestroyImageList(*images);
7401            *images=coalesce_image;
7402            break;
7403          }
7404        if (LocaleCompare("combine",option+1) == 0)
7405          {
7406            Image
7407              *combine_image;
7408
7409            (void) SyncImagesSettings(mogrify_info,*images,exception);
7410            combine_image=CombineImages(*images,exception);
7411            if (combine_image == (Image *) NULL)
7412              {
7413                status=MagickFalse;
7414                break;
7415              }
7416            *images=DestroyImageList(*images);
7417            *images=combine_image;
7418            break;
7419          }
7420        if (LocaleCompare("composite",option+1) == 0)
7421          {
7422            const char
7423              *value;
7424
7425            Image
7426              *mask_image,
7427              *composite_image,
7428              *image;
7429
7430            MagickBooleanType
7431              clip_to_self;
7432
7433            RectangleInfo
7434              geometry;
7435
7436            (void) SyncImagesSettings(mogrify_info,*images,exception);
7437            value=GetImageOption(mogrify_info,"compose:clip-to-self");
7438            if (value == (const char *) NULL)
7439              clip_to_self=MagickTrue;
7440            else
7441              clip_to_self=IsStringTrue(GetImageOption(mogrify_info,
7442                "compose:clip-to-self")); /* if this is true */
7443            if (IsMagickFalse(clip_to_self)) /* or */
7444              clip_to_self=IfMagickFalse(IsStringNotFalse(GetImageOption(
7445                mogrify_info,"compose:outside-overlay"))); /* this false */
7446            image=RemoveFirstImageFromList(images);
7447            composite_image=RemoveFirstImageFromList(images);
7448            if (composite_image == (Image *) NULL)
7449              {
7450                status=MagickFalse;
7451                break;
7452              }
7453            (void) TransformImage(&composite_image,(char *) NULL,
7454              composite_image->geometry,exception);
7455            SetGeometry(composite_image,&geometry);
7456            (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
7457            GravityAdjustGeometry(image->columns,image->rows,image->gravity,
7458              &geometry);
7459            mask_image=RemoveFirstImageFromList(images);
7460            if (mask_image != (Image *) NULL)
7461              {
7462                if ((image->compose == DisplaceCompositeOp) ||
7463                    (image->compose == DistortCompositeOp))
7464                  {
7465                    /*
7466                      Merge Y displacement into X displacement image.
7467                    */
7468                    (void) CompositeImage(composite_image,mask_image,
7469                      CopyGreenCompositeOp,MagickTrue,0,0,exception);
7470                    mask_image=DestroyImage(mask_image);
7471                  }
7472                else
7473                  {
7474                    /*
7475                      Set a blending mask for the composition.
7476                    */
7477                    (void) NegateImage(mask_image,MagickFalse,exception);
7478                    (void) SetImageMask(composite_image,mask_image,exception);
7479                    mask_image=DestroyImage(mask_image);
7480                  }
7481              }
7482            (void) CompositeImage(image,composite_image,image->compose,
7483              clip_to_self,geometry.x,geometry.y,exception);
7484            (void) SetImageMask(image,(Image *) NULL,exception);
7485            composite_image=DestroyImage(composite_image);
7486            *images=DestroyImageList(*images);
7487            *images=image;
7488            break;
7489          }
7490        break;
7491      }
7492      case 'd':
7493      {
7494        if (LocaleCompare("deconstruct",option+1) == 0)
7495          {
7496            Image
7497              *deconstruct_image;
7498
7499            (void) SyncImagesSettings(mogrify_info,*images,exception);
7500            deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
7501              exception);
7502            if (deconstruct_image == (Image *) NULL)
7503              {
7504                status=MagickFalse;
7505                break;
7506              }
7507            *images=DestroyImageList(*images);
7508            *images=deconstruct_image;
7509            break;
7510          }
7511        if (LocaleCompare("delete",option+1) == 0)
7512          {
7513            if (*option == '+')
7514              DeleteImages(images,"-1",exception);
7515            else
7516              DeleteImages(images,argv[i+1],exception);
7517            break;
7518          }
7519        if (LocaleCompare("dither",option+1) == 0)
7520          {
7521            if (*option == '+')
7522              {
7523                quantize_info->dither_method=NoDitherMethod;
7524                break;
7525              }
7526            quantize_info->dither_method=(DitherMethod) ParseCommandOption(
7527              MagickDitherOptions,MagickFalse,argv[i+1]);
7528            break;
7529          }
7530        if (LocaleCompare("duplicate",option+1) == 0)
7531          {
7532            Image
7533              *duplicate_images;
7534
7535            if (*option == '+')
7536              duplicate_images=DuplicateImages(*images,1,"-1",exception);
7537            else
7538              {
7539                const char
7540                  *p;
7541
7542                size_t
7543                  number_duplicates;
7544
7545                number_duplicates=(size_t) StringToLong(argv[i+1]);
7546                p=strchr(argv[i+1],',');
7547                if (p == (const char *) NULL)
7548                  duplicate_images=DuplicateImages(*images,number_duplicates,
7549                    "-1",exception);
7550                else
7551                  duplicate_images=DuplicateImages(*images,number_duplicates,p,
7552                    exception);
7553              }
7554            AppendImageToList(images, duplicate_images);
7555            (void) SyncImagesSettings(mogrify_info,*images,exception);
7556            break;
7557          }
7558        break;
7559      }
7560      case 'e':
7561      {
7562        if (LocaleCompare("evaluate-sequence",option+1) == 0)
7563          {
7564            Image
7565              *evaluate_image;
7566
7567            MagickEvaluateOperator
7568              op;
7569
7570            (void) SyncImageSettings(mogrify_info,*images,exception);
7571            op=(MagickEvaluateOperator) ParseCommandOption(
7572              MagickEvaluateOptions,MagickFalse,argv[i+1]);
7573            evaluate_image=EvaluateImages(*images,op,exception);
7574            if (evaluate_image == (Image *) NULL)
7575              {
7576                status=MagickFalse;
7577                break;
7578              }
7579            *images=DestroyImageList(*images);
7580            *images=evaluate_image;
7581            break;
7582          }
7583        break;
7584      }
7585      case 'f':
7586      {
7587        if (LocaleCompare("fft",option+1) == 0)
7588          {
7589            Image
7590              *fourier_image;
7591
7592            /*
7593              Implements the discrete Fourier transform (DFT).
7594            */
7595            (void) SyncImageSettings(mogrify_info,*images,exception);
7596            fourier_image=ForwardFourierTransformImage(*images,*option == '-' ?
7597              MagickTrue : MagickFalse,exception);
7598            if (fourier_image == (Image *) NULL)
7599              break;
7600            *images=DestroyImage(*images);
7601            *images=fourier_image;
7602            break;
7603          }
7604        if (LocaleCompare("flatten",option+1) == 0)
7605          {
7606            Image
7607              *flatten_image;
7608
7609            (void) SyncImagesSettings(mogrify_info,*images,exception);
7610            flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
7611            if (flatten_image == (Image *) NULL)
7612              break;
7613            *images=DestroyImageList(*images);
7614            *images=flatten_image;
7615            break;
7616          }
7617        if (LocaleCompare("fx",option+1) == 0)
7618          {
7619            Image
7620              *fx_image;
7621
7622            (void) SyncImagesSettings(mogrify_info,*images,exception);
7623            fx_image=FxImage(*images,argv[i+1],exception);
7624            if (fx_image == (Image *) NULL)
7625              {
7626                status=MagickFalse;
7627                break;
7628              }
7629            *images=DestroyImageList(*images);
7630            *images=fx_image;
7631            break;
7632          }
7633        break;
7634      }
7635      case 'h':
7636      {
7637        if (LocaleCompare("hald-clut",option+1) == 0)
7638          {
7639            Image
7640              *hald_image,
7641              *image;
7642
7643            (void) SyncImagesSettings(mogrify_info,*images,exception);
7644            image=RemoveFirstImageFromList(images);
7645            hald_image=RemoveFirstImageFromList(images);
7646            if (hald_image == (Image *) NULL)
7647              {
7648                status=MagickFalse;
7649                break;
7650              }
7651            (void) HaldClutImage(image,hald_image,exception);
7652            hald_image=DestroyImage(hald_image);
7653            if (*images != (Image *) NULL)
7654              *images=DestroyImageList(*images);
7655            *images=image;
7656            break;
7657          }
7658        break;
7659      }
7660      case 'i':
7661      {
7662        if (LocaleCompare("ift",option+1) == 0)
7663          {
7664            Image
7665              *fourier_image,
7666              *magnitude_image,
7667              *phase_image;
7668
7669            /*
7670              Implements the inverse fourier discrete Fourier transform (DFT).
7671            */
7672            (void) SyncImagesSettings(mogrify_info,*images,exception);
7673            magnitude_image=RemoveFirstImageFromList(images);
7674            phase_image=RemoveFirstImageFromList(images);
7675            if (phase_image == (Image *) NULL)
7676              {
7677                status=MagickFalse;
7678                break;
7679              }
7680            fourier_image=InverseFourierTransformImage(magnitude_image,
7681              phase_image,*option == '-' ? MagickTrue : MagickFalse,exception);
7682            if (fourier_image == (Image *) NULL)
7683              break;
7684            if (*images != (Image *) NULL)
7685              *images=DestroyImage(*images);
7686            *images=fourier_image;
7687            break;
7688          }
7689        if (LocaleCompare("insert",option+1) == 0)
7690          {
7691            Image
7692              *p,
7693              *q;
7694
7695            index=0;
7696            if (*option != '+')
7697              index=(ssize_t) StringToLong(argv[i+1]);
7698            p=RemoveLastImageFromList(images);
7699            if (p == (Image *) NULL)
7700              {
7701                (void) ThrowMagickException(exception,GetMagickModule(),
7702                  OptionError,"NoSuchImage","'%s'",argv[i+1]);
7703                status=MagickFalse;
7704                break;
7705              }
7706            q=p;
7707            if (index == 0)
7708              PrependImageToList(images,q);
7709            else
7710              if (index == (ssize_t) GetImageListLength(*images))
7711                AppendImageToList(images,q);
7712              else
7713                {
7714                   q=GetImageFromList(*images,index-1);
7715                   if (q == (Image *) NULL)
7716                     {
7717                       (void) ThrowMagickException(exception,GetMagickModule(),
7718                         OptionError,"NoSuchImage","'%s'",argv[i+1]);
7719                       status=MagickFalse;
7720                       break;
7721                     }
7722                  InsertImageInList(&q,p);
7723                }
7724            *images=GetFirstImageInList(q);
7725            break;
7726          }
7727        if (LocaleCompare("interpolate",option+1) == 0)
7728          {
7729            interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
7730              MagickInterpolateOptions,MagickFalse,argv[i+1]);
7731            break;
7732          }
7733        break;
7734      }
7735      case 'l':
7736      {
7737        if (LocaleCompare("layers",option+1) == 0)
7738          {
7739            Image
7740              *layers;
7741
7742            ImageLayerMethod
7743              method;
7744
7745            (void) SyncImagesSettings(mogrify_info,*images,exception);
7746            layers=(Image *) NULL;
7747            method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
7748              MagickFalse,argv[i+1]);
7749            switch (method)
7750            {
7751              case CoalesceLayer:
7752              {
7753                layers=CoalesceImages(*images,exception);
7754                break;
7755              }
7756              case CompareAnyLayer:
7757              case CompareClearLayer:
7758              case CompareOverlayLayer:
7759              default:
7760              {
7761                layers=CompareImagesLayers(*images,method,exception);
7762                break;
7763              }
7764              case MergeLayer:
7765              case FlattenLayer:
7766              case MosaicLayer:
7767              case TrimBoundsLayer:
7768              {
7769                layers=MergeImageLayers(*images,method,exception);
7770                break;
7771              }
7772              case DisposeLayer:
7773              {
7774                layers=DisposeImages(*images,exception);
7775                break;
7776              }
7777              case OptimizeImageLayer:
7778              {
7779                layers=OptimizeImageLayers(*images,exception);
7780                break;
7781              }
7782              case OptimizePlusLayer:
7783              {
7784                layers=OptimizePlusImageLayers(*images,exception);
7785                break;
7786              }
7787              case OptimizeTransLayer:
7788              {
7789                OptimizeImageTransparency(*images,exception);
7790                break;
7791              }
7792              case RemoveDupsLayer:
7793              {
7794                RemoveDuplicateLayers(images,exception);
7795                break;
7796              }
7797              case RemoveZeroLayer:
7798              {
7799                RemoveZeroDelayLayers(images,exception);
7800                break;
7801              }
7802              case OptimizeLayer:
7803              {
7804                /*
7805                  General Purpose, GIF Animation Optimizer.
7806                */
7807                layers=CoalesceImages(*images,exception);
7808                if (layers == (Image *) NULL)
7809                  {
7810                    status=MagickFalse;
7811                    break;
7812                  }
7813                *images=DestroyImageList(*images);
7814                *images=layers;
7815                layers=OptimizeImageLayers(*images,exception);
7816                if (layers == (Image *) NULL)
7817                  {
7818                    status=MagickFalse;
7819                    break;
7820                  }
7821                *images=DestroyImageList(*images);
7822                *images=layers;
7823                layers=(Image *) NULL;
7824                OptimizeImageTransparency(*images,exception);
7825                (void) RemapImages(quantize_info,*images,(Image *) NULL,
7826                  exception);
7827                break;
7828              }
7829              case CompositeLayer:
7830              {
7831                CompositeOperator
7832                  compose;
7833
7834                Image
7835                  *source;
7836
7837                RectangleInfo
7838                  geometry;
7839
7840                /*
7841                  Split image sequence at the first 'NULL:' image.
7842                */
7843                source=(*images);
7844                while (source != (Image *) NULL)
7845                {
7846                  source=GetNextImageInList(source);
7847                  if ((source != (Image *) NULL) &&
7848                      (LocaleCompare(source->magick,"NULL") == 0))
7849                    break;
7850                }
7851                if (source != (Image *) NULL)
7852                  {
7853                    if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7854                        (GetNextImageInList(source) == (Image *) NULL))
7855                      source=(Image *) NULL;
7856                    else
7857                      {
7858                        /*
7859                          Separate the two lists, junk the null: image.
7860                        */
7861                        source=SplitImageList(source->previous);
7862                        DeleteImageFromList(&source);
7863                      }
7864                  }
7865                if (source == (Image *) NULL)
7866                  {
7867                    (void) ThrowMagickException(exception,GetMagickModule(),
7868                      OptionError,"MissingNullSeparator","layers Composite");
7869                    status=MagickFalse;
7870                    break;
7871                  }
7872                /*
7873                  Adjust offset with gravity and virtual canvas.
7874                */
7875                SetGeometry(*images,&geometry);
7876                (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
7877                geometry.width=source->page.width != 0 ?
7878                  source->page.width : source->columns;
7879                geometry.height=source->page.height != 0 ?
7880                 source->page.height : source->rows;
7881                GravityAdjustGeometry((*images)->page.width != 0 ?
7882                  (*images)->page.width : (*images)->columns,
7883                  (*images)->page.height != 0 ? (*images)->page.height :
7884                  (*images)->rows,(*images)->gravity,&geometry);
7885                compose=OverCompositeOp;
7886                option=GetImageOption(mogrify_info,"compose");
7887                if (option != (const char *) NULL)
7888                  compose=(CompositeOperator) ParseCommandOption(
7889                    MagickComposeOptions,MagickFalse,option);
7890                CompositeLayers(*images,compose,source,geometry.x,geometry.y,
7891                  exception);
7892                source=DestroyImageList(source);
7893                break;
7894              }
7895            }
7896            if (layers == (Image *) NULL)
7897              break;
7898            *images=DestroyImageList(*images);
7899            *images=layers;
7900            break;
7901          }
7902        break;
7903      }
7904      case 'm':
7905      {
7906        if (LocaleCompare("map",option+1) == 0)
7907          {
7908            (void) SyncImagesSettings(mogrify_info,*images,exception);
7909            if (*option == '+')
7910              {
7911                (void) RemapImages(quantize_info,*images,(Image *) NULL,
7912                  exception);
7913                break;
7914              }
7915            i++;
7916            break;
7917          }
7918        if (LocaleCompare("maximum",option+1) == 0)
7919          {
7920            Image
7921              *maximum_image;
7922
7923            /*
7924              Maximum image sequence (deprecated).
7925            */
7926            (void) SyncImagesSettings(mogrify_info,*images,exception);
7927            maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
7928            if (maximum_image == (Image *) NULL)
7929              {
7930                status=MagickFalse;
7931                break;
7932              }
7933            *images=DestroyImageList(*images);
7934            *images=maximum_image;
7935            break;
7936          }
7937        if (LocaleCompare("minimum",option+1) == 0)
7938          {
7939            Image
7940              *minimum_image;
7941
7942            /*
7943              Minimum image sequence (deprecated).
7944            */
7945            (void) SyncImagesSettings(mogrify_info,*images,exception);
7946            minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
7947            if (minimum_image == (Image *) NULL)
7948              {
7949                status=MagickFalse;
7950                break;
7951              }
7952            *images=DestroyImageList(*images);
7953            *images=minimum_image;
7954            break;
7955          }
7956        if (LocaleCompare("morph",option+1) == 0)
7957          {
7958            Image
7959              *morph_image;
7960
7961            (void) SyncImagesSettings(mogrify_info,*images,exception);
7962            morph_image=MorphImages(*images,StringToUnsignedLong(argv[i+1]),
7963              exception);
7964            if (morph_image == (Image *) NULL)
7965              {
7966                status=MagickFalse;
7967                break;
7968              }
7969            *images=DestroyImageList(*images);
7970            *images=morph_image;
7971            break;
7972          }
7973        if (LocaleCompare("mosaic",option+1) == 0)
7974          {
7975            Image
7976              *mosaic_image;
7977
7978            (void) SyncImagesSettings(mogrify_info,*images,exception);
7979            mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
7980            if (mosaic_image == (Image *) NULL)
7981              {
7982                status=MagickFalse;
7983                break;
7984              }
7985            *images=DestroyImageList(*images);
7986            *images=mosaic_image;
7987            break;
7988          }
7989        break;
7990      }
7991      case 'p':
7992      {
7993        if (LocaleCompare("print",option+1) == 0)
7994          {
7995            char
7996              *string;
7997
7998            (void) SyncImagesSettings(mogrify_info,*images,exception);
7999            string=InterpretImageProperties(mogrify_info,*images,argv[i+1],
8000              exception);
8001            if (string == (char *) NULL)
8002              break;
8003            (void) FormatLocaleFile(stdout,"%s",string);
8004            string=DestroyString(string);
8005          }
8006        if (LocaleCompare("process",option+1) == 0)
8007          {
8008            char
8009              **arguments;
8010
8011            int
8012              j,
8013              number_arguments;
8014
8015            (void) SyncImagesSettings(mogrify_info,*images,exception);
8016            arguments=StringToArgv(argv[i+1],&number_arguments);
8017            if (arguments == (char **) NULL)
8018              break;
8019            if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
8020              {
8021                char
8022                  breaker,
8023                  quote,
8024                  *token;
8025
8026                const char
8027                  *arguments;
8028
8029                int
8030                  next,
8031                  status;
8032
8033                size_t
8034                  length;
8035
8036                TokenInfo
8037                  *token_info;
8038
8039                /*
8040                  Support old style syntax, filter="-option arg".
8041                */
8042                length=strlen(argv[i+1]);
8043                token=(char *) NULL;
8044                if (~length >= (MaxTextExtent-1))
8045                  token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
8046                    sizeof(*token));
8047                if (token == (char *) NULL)
8048                  break;
8049                next=0;
8050                arguments=argv[i+1];
8051                token_info=AcquireTokenInfo();
8052                status=Tokenizer(token_info,0,token,length,arguments,"","=",
8053                  "\"",'\0',&breaker,&next,&quote);
8054                token_info=DestroyTokenInfo(token_info);
8055                if (status == 0)
8056                  {
8057                    const char
8058                      *argv;
8059
8060                    argv=(&(arguments[next]));
8061                    (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
8062                      exception);
8063                  }
8064                token=DestroyString(token);
8065                break;
8066              }
8067            (void) SubstituteString(&arguments[1],"-","");
8068            (void) InvokeDynamicImageFilter(arguments[1],&(*images),
8069              number_arguments-2,(const char **) arguments+2,exception);
8070            for (j=0; j < number_arguments; j++)
8071              arguments[j]=DestroyString(arguments[j]);
8072            arguments=(char **) RelinquishMagickMemory(arguments);
8073            break;
8074          }
8075        break;
8076      }
8077      case 'r':
8078      {
8079        if (LocaleCompare("reverse",option+1) == 0)
8080          {
8081            ReverseImageList(images);
8082            break;
8083          }
8084        break;
8085      }
8086      case 's':
8087      {
8088        if (LocaleCompare("smush",option+1) == 0)
8089          {
8090            Image
8091              *smush_image;
8092
8093            ssize_t
8094              offset;
8095
8096            (void) SyncImagesSettings(mogrify_info,*images,exception);
8097            offset=(ssize_t) StringToLong(argv[i+1]);
8098            smush_image=SmushImages(*images,*option == '-' ? MagickTrue :
8099              MagickFalse,offset,exception);
8100            if (smush_image == (Image *) NULL)
8101              {
8102                status=MagickFalse;
8103                break;
8104              }
8105            *images=DestroyImageList(*images);
8106            *images=smush_image;
8107            break;
8108          }
8109        if (LocaleCompare("swap",option+1) == 0)
8110          {
8111            Image
8112              *p,
8113              *q,
8114              *swap;
8115
8116            ssize_t
8117              swap_index;
8118
8119            index=(-1);
8120            swap_index=(-2);
8121            if (*option != '+')
8122              {
8123                GeometryInfo
8124                  geometry_info;
8125
8126                MagickStatusType
8127                  flags;
8128
8129                swap_index=(-1);
8130                flags=ParseGeometry(argv[i+1],&geometry_info);
8131                index=(ssize_t) geometry_info.rho;
8132                if ((flags & SigmaValue) != 0)
8133                  swap_index=(ssize_t) geometry_info.sigma;
8134              }
8135            p=GetImageFromList(*images,index);
8136            q=GetImageFromList(*images,swap_index);
8137            if ((p == (Image *) NULL) || (q == (Image *) NULL))
8138              {
8139                (void) ThrowMagickException(exception,GetMagickModule(),
8140                  OptionError,"NoSuchImage","'%s'",(*images)->filename);
8141                status=MagickFalse;
8142                break;
8143              }
8144            if (p == q)
8145              break;
8146            swap=CloneImage(p,0,0,MagickTrue,exception);
8147            ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
8148            ReplaceImageInList(&q,swap);
8149            *images=GetFirstImageInList(q);
8150            break;
8151          }
8152        break;
8153      }
8154      case 'w':
8155      {
8156        if (LocaleCompare("write",option+1) == 0)
8157          {
8158            char
8159              key[MaxTextExtent];
8160
8161            Image
8162              *write_images;
8163
8164            ImageInfo
8165              *write_info;
8166
8167            (void) SyncImagesSettings(mogrify_info,*images,exception);
8168            (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[i+1]);
8169            (void) DeleteImageRegistry(key);
8170            write_images=(*images);
8171            if (*option == '+')
8172              write_images=CloneImageList(*images,exception);
8173            write_info=CloneImageInfo(mogrify_info);
8174            status&=WriteImages(write_info,write_images,argv[i+1],exception);
8175            write_info=DestroyImageInfo(write_info);
8176            if (*option == '+')
8177              write_images=DestroyImageList(write_images);
8178            break;
8179          }
8180        break;
8181      }
8182      default:
8183        break;
8184    }
8185    i+=count;
8186  }
8187  quantize_info=DestroyQuantizeInfo(quantize_info);
8188  mogrify_info=DestroyImageInfo(mogrify_info);
8189  status&=MogrifyImageInfo(image_info,argc,argv,exception);
8190  return(status != 0 ? MagickTrue : MagickFalse);
8191}
8192
8193/*
8194%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8195%                                                                             %
8196%                                                                             %
8197%                                                                             %
8198+     M o g r i f y I m a g e s                                               %
8199%                                                                             %
8200%                                                                             %
8201%                                                                             %
8202%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8203%
8204%  MogrifyImages() applies image processing options to a sequence of images as
8205%  prescribed by command line options.
8206%
8207%  The format of the MogrifyImage method is:
8208%
8209%      MagickBooleanType MogrifyImages(ImageInfo *image_info,
8210%        const MagickBooleanType post,const int argc,const char **argv,
8211%        Image **images,Exceptioninfo *exception)
8212%
8213%  A description of each parameter follows:
8214%
8215%    o image_info: the image info..
8216%
8217%    o post: If true, post process image list operators otherwise pre-process.
8218%
8219%    o argc: Specifies a pointer to an integer describing the number of
8220%      elements in the argument vector.
8221%
8222%    o argv: Specifies a pointer to a text array containing the command line
8223%      arguments.
8224%
8225%    o images: pointer to a pointer of the first image in image list.
8226%
8227%    o exception: return any errors or warnings in this structure.
8228%
8229*/
8230WandExport MagickBooleanType MogrifyImages(ImageInfo *image_info,
8231  const MagickBooleanType post,const int argc,const char **argv,
8232  Image **images,ExceptionInfo *exception)
8233{
8234#define MogrifyImageTag  "Mogrify/Image"
8235
8236  MagickStatusType
8237    status;
8238
8239  MagickBooleanType
8240    proceed;
8241
8242  size_t
8243    n;
8244
8245  register ssize_t
8246    i;
8247
8248  assert(image_info != (ImageInfo *) NULL);
8249  assert(image_info->signature == MagickSignature);
8250  if (images == (Image **) NULL)
8251    return(MogrifyImage(image_info,argc,argv,images,exception));
8252  assert((*images)->previous == (Image *) NULL);
8253  assert((*images)->signature == MagickSignature);
8254  if ((*images)->debug != MagickFalse)
8255    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
8256      (*images)->filename);
8257  if ((argc <= 0) || (*argv == (char *) NULL))
8258    return(MagickTrue);
8259  (void) SetImageInfoProgressMonitor(image_info,(MagickProgressMonitor) NULL,
8260    (void *) NULL);
8261  status=0;
8262
8263#if 0
8264  (void) FormatLocaleFile(stderr, "mogrify start %s %d (%s)\n",argv[0],argc,
8265    post?"post":"pre");
8266#endif
8267
8268  /*
8269    Pre-process multi-image sequence operators
8270  */
8271  if (post == MagickFalse)
8272    status&=MogrifyImageList(image_info,argc,argv,images,exception);
8273  /*
8274    For each image, process simple single image operators
8275  */
8276  i=0;
8277  n=GetImageListLength(*images);
8278  for ( ; ; )
8279  {
8280#if 0
8281  (void) FormatLocaleFile(stderr,"mogrify %ld of %ld\n",(long)
8282    GetImageIndexInList(*images),(long)GetImageListLength(*images));
8283#endif
8284    status&=MogrifyImage(image_info,argc,argv,images,exception);
8285    proceed=SetImageProgress(*images,MogrifyImageTag,(MagickOffsetType) i, n);
8286    if (proceed == MagickFalse)
8287      break;
8288    if ( (*images)->next == (Image *) NULL )
8289      break;
8290    *images=(*images)->next;
8291    i++;
8292  }
8293  assert( *images != (Image *) NULL );
8294#if 0
8295  (void) FormatLocaleFile(stderr,"mogrify end %ld of %ld\n",(long)
8296    GetImageIndexInList(*images),(long)GetImageListLength(*images));
8297#endif
8298
8299  /*
8300    Post-process, multi-image sequence operators
8301  */
8302  *images=GetFirstImageInList(*images);
8303  if (post != MagickFalse)
8304    status&=MogrifyImageList(image_info,argc,argv,images,exception);
8305  return(status != 0 ? MagickTrue : MagickFalse);
8306}
8307