]> granicus.if.org Git - imagemagick/blobdiff - MagickWand/operation.c
(no commit message)
[imagemagick] / MagickWand / operation.c
index e904e03ce3693951f1d8ff6e36773a0cd3644d83..253fe10c95dfe014b5cf6873ca627b8b25855f11 100644 (file)
@@ -17,7 +17,7 @@
 %                               September 2011                                %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
 #include "MagickCore/monitor-private.h"
 #include "MagickCore/thread-private.h"
 #include "MagickCore/string-private.h"
+#include "MagickCore/pixel-private.h"
 \f
 /*
   Define declarations.
 */
-#define USE_WAND_METHODS  0
+#define USE_WAND_METHODS  1
 #define MAX_STACK_DEPTH  32
 #define UNDEFINED_COMPRESSION_QUALITY  0UL
 
+/* FUTURE: why is this default so specific? */
+#define DEFAULT_DISSIMILARITY_THRESHOLD "0.31830988618379067154"
+
 /*
   Constant declaration. (temporary exports)
 */
@@ -72,6 +76,11 @@ static const char
   BackgroundColor[] = "#fff",  /* white */
   BorderColor[] = "#dfdfdf",  /* sRGB gray */
   MatteColor[] = "#bdbdbd";  /* slightly darker gray */
+
+/* For Debugging Geometry Input */
+#define ReportGeometry(flags,info) \
+  (void) FormatLocaleFile(stderr, "Geometry = 0x%04X : %lg x %lg %+lg %+lg\n", \
+       flags, info.rho, info.sigma, info.xi, info.psi )
 \f
 /*
 ** Function to report on the progress of image operations
@@ -148,29 +157,6 @@ static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
   return(image);
 }
 
-#if 0
-/*
-  FloatListOption() converts a string option of space or comma seperated
-  numbers into a list of floating point numbers, required by some operations.
-*/
-static MagickBooleanType FloatListOption(const char *option,
-     size_t *number_arguments, double **arguments, ExceptionInfo *exception)
-{
-  char
-    token[MaxTextExtent];
-
-  const char
-    *p;
-
-  MagickBooleanType
-    error;
-
-  register size_t
-    x;
-
-}
-#endif
-
 /*
   SparseColorOption() parse the complex -sparse-color argument into an
   an array of floating point values than call SparseColorImage().
@@ -217,7 +203,8 @@ static Image *SparseColorOption(const Image *image,
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
   /*
-    Limit channels according to image - and add up number of color channel.
+    Limit channels according to image
+    add up number of values needed per color.
   */
   number_colors=0;
   if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
@@ -230,7 +217,7 @@ static Image *SparseColorOption(const Image *image,
       (image->colorspace == CMYKColorspace))
     number_colors++;
   if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
-      IfMagickTrue(image->matte))
+      image->alpha_trait == BlendPixelTrait)
     number_colors++;
 
   /*
@@ -309,7 +296,7 @@ static Image *SparseColorOption(const Image *image,
           (image->colorspace == CMYKColorspace))
         sparse_arguments[x++] = QuantumScale*color.black;
       if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
-          IfMagickTrue(image->matte))
+          image->alpha_trait == BlendPixelTrait)
         sparse_arguments[x++] = QuantumScale*color.alpha;
     }
     else {
@@ -349,7 +336,7 @@ static Image *SparseColorOption(const Image *image,
         token[0] = ','; /* used this token - get another */
       }
       if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
-          IfMagickTrue(image->matte))
+          image->alpha_trait == BlendPixelTrait)
         {
         while ( token[0] == ',' ) GetMagickToken(p,&p,token);
         if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
@@ -380,7 +367,7 @@ static Image *SparseColorOption(const Image *image,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+   C L I S e t t i n g O p t i o n I n f o                                   %
+%   C L I S e t t i n g O p t i o n I n f o                                   %
 %                                                                             %
 %                                                                             %
 %                                                                             %
@@ -411,29 +398,8 @@ static Image *SparseColorOption(const Image *image,
 %    o arg1, arg2: optional argument strings to the operation
 %        arg2 is currently only used by "-limit"
 %
-% Example usage...
-%
-%    CLISettingOptionInfo(cli_wand, "-background", "Red", NULL); // set value
-%    CLISettingOptionInfo(cli_wand, "-adjoin", NULL, NULL);      // set boolean
-%    CLISettingOptionInfo(cli_wand, "+adjoin", NULL, NULL);      // unset
-%
-% Or for handling command line arguments EG: +/-option ["arg1"]
-%
-%    argc,argv
-%    i=index in argv
-%
-%    option_info = GetCommandOptionInfo(argv[i]);
-%    count=option_info->type;
-%    option_type=option_info->flags;
-%
-%    if ( (option_type & SettingOperatorOptionFlags) != 0 )
-%      CLISettingOptionInfo(cli_wand, argv[i],
-%                   (count>=1) ? argv[i+1] : (char *)NULL,
-%                   (count>=2) ? argv[i+2] : (char *)NULL);
-%    i += count+1;
-%
 */
-WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
+WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
      const char *option,const char *arg1, const char *arg2)
 {
   ssize_t
@@ -455,6 +421,38 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
 #define ArgBooleanString  (IfSetOption?"true":"false")
 #define ArgOption(def)    (IfSetOption?arg1:(const char *)(def))
 
+#if 0
+Setting are not directly involved with images, so can not
+interpret Percent Escapes in Arguments, At least not yet */
+
+#define _process_flags    (cli_wand->process_flags)
+#define _option_type      ((CommandOptionFlags) cli_wand->command->flags)
+  /* Interpret Percent Escapes in Arguments - using first image */
+  arg1 = arg1n,
+  arg2 = arg2n;
+  if ( (((_process_flags & ProcessInterpretProperities) != 0 )
+        || ((_option_type & AlwaysInterpretArgsFlag) != 0)
+       )  && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
+    /* Interpret Percent escapes in argument 1 */
+    if (arg1n != (char *) NULL) {
+      arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
+      if (arg1 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg1=arg1n;  /* use the given argument as is */
+      }
+    }
+    if (arg2n != (char *) NULL) {
+      arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
+      if (arg2 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg2=arg2n;  /* use the given argument as is */
+      }
+    }
+  }
+#undef _process_flags
+#undef _option_type
+#endif
+
   switch (*(option+1))
   {
     case 'a':
@@ -466,7 +464,7 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         }
       if (LocaleCompare("affine",option+1) == 0)
         {
-          CLIWandWarnDepreciated("-draw 'affine ...'");
+          CLIWandWarnReplaced("-draw 'affine ...'");
           if (IfSetOption)
             (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
           else
@@ -572,7 +570,7 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         }
       if (LocaleCompare("box",option+1) == 0)
         {
-          CLIWandWarnDepreciated("-undercolor");
+          CLIWandWarnReplaced("-undercolor");
           CLISettingOptionInfo(cli_wand,"-undercolor",arg1, arg2);
           break;
         }
@@ -767,18 +765,28 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
           (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
           break;
         }
+      if (LocaleCompare("dissimilarity-threshold",option+1) == 0)
+        {
+          /* FUTURE: this is only used by CompareImages() which is used
+             only by the "compare" CLI program at this time.  */
+          arg1=ArgOption(DEFAULT_DISSIMILARITY_THRESHOLD);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
+          break;
+        }
       if (LocaleCompare("dither",option+1) == 0)
         {
           /* _image_info attr (on/off), _quantize_info attr (on/off)
              but also ImageInfo and _quantize_info method!
              FUTURE: merge the duality of the dithering options
           */
-          _image_info->dither = _quantize_info->dither = ArgBoolean;
+          _image_info->dither = ArgBoolean;
           (void) SetImageOption(_image_info,option+1,ArgOption("none"));
           _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
-                    MagickDitherOptions,MagickFalse,ArgOption("none"));
+             MagickDitherOptions,MagickFalse,ArgOption("none"));
           if (_quantize_info->dither_method == NoDitherMethod)
-            _image_info->dither = _quantize_info->dither = MagickFalse;
+            _image_info->dither = MagickFalse;
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
@@ -928,15 +936,37 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
+    case 'h':
+    {
+      if (LocaleCompare("highlight-color",option+1) == 0)
+        {
+          /* FUTURE: this is only used by CompareImages() which is used
+             only by the "compare" CLI program at this time.  */
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          break;
+        }
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
+    }
     case 'i':
     {
+      if (LocaleCompare("intensity",option+1) == 0)
+        {
+          arg1 = ArgOption("undefined");
+          parse = ParseCommandOption(MagickPixelIntensityOptions,MagickFalse,
+            arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityType",
+              option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
+          break;
+        }
       if (LocaleCompare("intent",option+1) == 0)
         {
           /* Only used by coders: MIFF, MPC, BMP, PNG
              and for image profile call to AcquireTransformThreadSet()
              SyncImageSettings() used to set per-image attribute.
           */
-          arg1 = ArgOption("indefined");
+          arg1 = ArgOption("undefined");
           parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
           if (parse < 0)
             CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
@@ -1034,6 +1064,8 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         }
       if (LocaleCompare("lowlight-color",option+1) == 0)
         {
+          /* FUTURE: this is only used by CompareImages() which is used
+             only by the "compare" CLI program at this time.  */
           (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
@@ -1058,6 +1090,17 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
              &_image_info->matte_color,_exception);
           break;
         }
+      if (LocaleCompare("metric",option+1) == 0)
+        {
+          /* FUTURE: this is only used by CompareImages() which is used
+             only by the "compare" CLI program at this time.  */
+          parse=ParseCommandOption(MagickMetricOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedMetricType",
+                option,arg1);
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          break;
+        }
       if (LocaleCompare("monitor",option+1) == 0)
         {
           (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
@@ -1277,9 +1320,9 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         {
           if (IfMagickFalse(IsGeometry(arg1)))
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
-          SeedPseudoRandomGenerator(
-               IfSetOption ? (size_t) StringToUnsignedLong(arg1)
-                           : (size_t) time((time_t *) NULL) );
+          SetRandomSecretKey(
+               IfSetOption ? (unsigned long) StringToUnsignedLong(arg1)
+                           : (unsigned long) time((time_t *) NULL) );
           break;
         }
       if (LocaleCompare("size",option+1) == 0)
@@ -1350,6 +1393,15 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
           _draw_info->style=(StyleType) parse;
           break;
         }
+#if 0
+      if (LocaleCompare("subimage-search",option+1) == 0)
+        {
+        /* FUTURE: this is only used by CompareImages() which is used
+            only by the "compare" CLI program at this time.  */
+          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
+          break;
+        }
+#endif
       if (LocaleCompare("synchronize",option+1) == 0)
         {
           /* FUTURE: syncronize to storage - but what does that mean? */
@@ -1368,6 +1420,7 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         }
       if (LocaleCompare("texture",option+1) == 0)
         {
+          /* Note: arguments do not have percent escapes expanded */
           /* FUTURE: move _image_info string to option splay-tree
              Other than "montage" what uses "texture" ????
           */
@@ -1376,6 +1429,7 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         }
       if (LocaleCompare("tile",option+1) == 0)
         {
+          /* Note: arguments do not have percent escapes expanded */
           _draw_info->fill_pattern=IfSetOption
                                  ?GetImageCache(_image_info,arg1,_exception)
                                  :DestroyImage(_draw_info->fill_pattern);
@@ -1528,6 +1582,14 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
   }
 
+#if 0
+  /* clean up percent escape interpreted strings */
+  if (arg1 != arg1n )
+    arg1=DestroyString((char *)arg1);
+  if (arg2 != arg2n )
+    arg2=DestroyString((char *)arg2);
+#endif
+
 #undef _image_info
 #undef _exception
 #undef _draw_info
@@ -1552,14 +1614,13 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  WandSimpleOperatorImages() applys one simple image operation given to all
-%  the images in the CLI wand,  with the settings that was previously saved in
-%  the CLI wand.
+%  CLISimpleOperatorImages() applys one simple image operation given to all
+%  the images in the CLI wand, using any per-image or global settings that was
+%  previously saved in the CLI wand.
 %
-%  It is assumed that any per-image settings are up-to-date with respect to
-%  extra settings that were already saved in the wand.
+%  It is assumed that any such settings are up-to-date.
 %
-%  The format of the WandSimpleOperatorImage method is:
+%  The format of the WandSimpleOperatorImages method is:
 %
 %    void CLISimpleOperatorImages(MagickCLI *cli_wand,
 %        const char *option, const char *arg1, const char *arg2)
@@ -1572,35 +1633,11 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
 %
 %    o arg1, arg2: optional argument strings to the operation
 %
-% Any problems will be added to the 'exception' entry of the given wand.
-%
-% Example usage...
-%
-%  CLISimpleOperatorImages(cli_wand, "-crop","100x100+20+30",NULL);
-%  CLISimpleOperatorImages(cli_wand, "+repage",NULL,NULL);
-%  CLISimpleOperatorImages(cli_wand, "+distort","SRT","45");
-%
-% Or for handling command line arguments EG: +/-option ["arg1"]
-%
-%    cli_wand
-%    argc,argv
-%    i=index in argv
-%
-%    option_info = GetCommandOptionInfo(argv[i]);
-%    count=option_info->type;
-%    option_type=option_info->flags;
-%
-%    if ( (option_type & SimpleOperatorOptionFlag) != 0 )
-%      CLISimpleOperatorImages(cli_wand, argv[i],
-%          count>=1 ? argv[i+1] : (char *)NULL,
-%          count>=2 ? argv[i+2] : (char *)NULL );
-%    i += count+1;
-%
 */
 
 /*
-  Internal subrountine to apply one simple image operation to the current
-  image pointed to by the CLI wand.
+  CLISimpleOperatorImage() is an Internal subrountine to apply one simple
+  image operation to the current image pointed to by the CLI wand.
 
   The image in the list may be modified in three different ways...
     * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
@@ -1615,8 +1652,8 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
   also change.  GetFirstImageInList() should be used by caller if they wish
   return the Image pointer to the first image in list.
 */
-static void CLISimpleOperatorImage(MagickCLI *cli_wand,
-  const char *option, const char *arg1, const char *arg2)
+static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
+  const char *option, const char *arg1n, const char *arg2n)
 {
   Image *
     new_image;
@@ -1633,11 +1670,17 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
   ssize_t
     parse;
 
+  const char    /* For percent escape interpretImageProperties() */
+    *arg1,
+    *arg2;
+
 #define _image_info     (cli_wand->wand.image_info)
 #define _image          (cli_wand->wand.images)
 #define _exception      (cli_wand->wand.exception)
 #define _draw_info      (cli_wand->draw_info)
 #define _quantize_info  (cli_wand->quantize_info)
+#define _process_flags  (cli_wand->process_flags)
+#define _option_type    ((CommandOptionFlags) cli_wand->command->flags)
 #define IfNormalOp      (*option=='-')
 #define IfPlusOp        (*option!='-')
 #define normal_op       IsMagickTrue(IfNormalOp)
@@ -1650,24 +1693,48 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
   if (IfMagickTrue(cli_wand->wand.debug))
     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
 
-  (void) SyncImageSettings(_image_info,_image,_exception);
+  /* Interpret Percent Escapes in Arguments - using first image */
+  arg1 = arg1n,
+  arg2 = arg2n;
+  if ( (((_process_flags & ProcessInterpretProperities) != 0 )
+        || ((_option_type & AlwaysInterpretArgsFlag) != 0)
+       )  && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
+    /* Interpret Percent escapes in argument 1 */
+    if (arg1n != (char *) NULL) {
+      arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
+      if (arg1 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg1=arg1n;  /* use the given argument as is */
+      }
+    }
+    if (arg2n != (char *) NULL) {
+      arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
+      if (arg2 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg2=arg2n;  /* use the given argument as is */
+      }
+    }
+  }
+#undef _process_flags
+#undef _option_type
 
-  SetGeometryInfo(&geometry_info);
+#if 0
+  (void) FormatLocaleFile(stderr,
+    "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
+#endif
 
   new_image = (Image *)NULL; /* the replacement image, if not null at end */
+  SetGeometryInfo(&geometry_info);
 
-  /* FUTURE: We may need somthing a little more optimized than this!
-     Perhaps, do the 'sync' if 'settings tainted' before next operator.
-  */
   switch (*(option+1))
   {
     case 'a':
     {
       if (LocaleCompare("adaptive-blur",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           new_image=AdaptiveBlurImage(_image,geometry_info.rho,
@@ -1686,9 +1753,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("adaptive-sharpen",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
@@ -1697,32 +1764,26 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("alpha",option+1) == 0)
         {
-          parse=ParseCommandOption(MagickAlphaOptions,MagickFalse,arg1);
+          parse=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,arg1);
           if (parse < 0)
-            CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelType",
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelOption",
                  option,arg1);
-          (void) SetImageAlphaChannel(_image,(AlphaChannelType)parse,
+          (void) SetImageAlphaChannel(_image,(AlphaChannelOption)parse,
                _exception);
           break;
         }
       if (LocaleCompare("annotate",option+1) == 0)
         {
           char
-            *text,
             geometry[MaxTextExtent];
 
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           SetGeometryInfo(&geometry_info);
           flags=ParseGeometry(arg1,&geometry_info);
+          if (flags == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=geometry_info.rho;
-          text=InterpretImageProperties(_image_info,_image,arg2,
-            _exception);
-          if (text == (char *) NULL)
-            break;
-          (void) CloneString(&_draw_info->text,text);
-          text=DestroyString(text);
+          (void) CloneString(&_draw_info->text,arg2);
           (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
             geometry_info.xi,geometry_info.psi);
           (void) CloneString(&_draw_info->geometry,geometry);
@@ -1750,49 +1811,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("auto-orient",option+1) == 0)
         {
-          /* This should probably be a MagickCore function */
-          switch (_image->orientation)
-          {
-            case TopRightOrientation:
-            {
-              new_image=FlopImage(_image,_exception);
-              break;
-            }
-            case BottomRightOrientation:
-            {
-              new_image=RotateImage(_image,180.0,_exception);
-              break;
-            }
-            case BottomLeftOrientation:
-            {
-              new_image=FlipImage(_image,_exception);
-              break;
-            }
-            case LeftTopOrientation:
-            {
-              new_image=TransposeImage(_image,_exception);
-              break;
-            }
-            case RightTopOrientation:
-            {
-              new_image=RotateImage(_image,90.0,_exception);
-              break;
-            }
-            case RightBottomOrientation:
-            {
-              new_image=TransverseImage(_image,_exception);
-              break;
-            }
-            case LeftBottomOrientation:
-            {
-              new_image=RotateImage(_image,270.0,_exception);
-              break;
-            }
-            default:
-              break;
-          }
-          if (new_image != (Image *) NULL)
-            new_image->orientation=TopLeftOrientation;
+          new_image=AutoOrientImage(_image,_image->orientation,_exception);
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
@@ -1810,18 +1829,18 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         {
           geometry_info.rho=1.5;
           if (IfNormalOp) {
-            if (IfMagickFalse(IsGeometry(arg1)))
-              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
             flags=ParseGeometry(arg1,&geometry_info);
+            if ((flags & RhoValue) == 0)
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           }
           new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
           break;
         }
       if (LocaleCompare("blur",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
@@ -1836,19 +1855,14 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           const char*
             value;
 
-          if (IfMagickFalse(IsGeometry(arg1)))
+          flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
+          if ((flags & (WidthValue | HeightValue)) == 0)
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
-
+          compose=OverCompositeOp;
           value=GetImageOption(_image_info,"compose");
           if (value != (const char *) NULL)
-            compose=(CompositeOperator) ParseCommandOption(
-                 MagickComposeOptions,MagickFalse,value);
-          else
-            compose=OverCompositeOp;  /* use Over not _image->compose */
-
-          flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
-          if ((flags & SigmaValue) == 0)
-            geometry.height=geometry.width;
+            compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
+              MagickFalse,value);
           new_image=BorderImage(_image,&geometry,compose,_exception);
           break;
         }
@@ -1864,9 +1878,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           MagickStatusType
             flags;
 
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           brightness=geometry_info.rho;
           contrast=0.0;
           if ((flags & SigmaValue) != 0)
@@ -1881,6 +1895,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     {
       if (LocaleCompare("cdl",option+1) == 0)
         {
+          /* Note: arguments do not have percent escapes expanded */
           char
             *color_correction_collection;
 
@@ -1896,15 +1911,15 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("charcoal",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           if ((flags & XiValue) == 0)
             geometry_info.xi=1.0;
-          new_image=CharcoalImage(_image,geometry_info.rho,
-            geometry_info.sigma,_exception);
+          new_image=CharcoalImage(_image,geometry_info.rho,geometry_info.sigma,
+            _exception);
           break;
         }
       if (LocaleCompare("chop",option+1) == 0)
@@ -1930,6 +1945,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("clip-mask",option+1) == 0)
         {
+          /* Note: arguments do not have percent escapes expanded */
           CacheView
             *mask_view;
 
@@ -1946,7 +1962,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
             y;
 
           if (IfPlusOp) {
-            /* "+clip-mask" Remove the write mask */
+            /* use "+clip-mask" Remove the write mask for -clip-path */
             (void) SetImageMask(_image,(Image *) NULL,_exception);
             break;
           }
@@ -1957,7 +1973,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
             break;
           /* Create a write mask from cli_wand mask image */
           /* FUTURE: use Alpha operations instead and create a Grey Image */
-          mask_view=AcquireCacheView(mask_image);
+          mask_view=AcquireAuthenticCacheView(mask_image,_exception);
           for (y=0; y < (ssize_t) mask_image->rows; y++)
           {
             q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
@@ -1966,7 +1982,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
               break;
             for (x=0; x < (ssize_t) mask_image->columns; x++)
             {
-              if (IfMagickFalse(mask_image->matte))
+              if (mask_image->alpha_trait != BlendPixelTrait)
                 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
               SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
               SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
@@ -1978,7 +1994,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           }
           /* clean up and set the write mask */
           mask_view=DestroyCacheView(mask_view);
-          mask_image->matte=MagickTrue;
+          mask_image->alpha_trait=BlendPixelTrait;
           (void) SetImageMask(_image,mask_image,_exception);
           mask_image=DestroyImage(mask_image);
           break;
@@ -1986,6 +2002,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
       if (LocaleCompare("clip-path",option+1) == 0)
         {
           (void) ClipImagePath(_image,arg1,normal_op,_exception);
+          /* Note: Use "+clip-mask" remove the write mask added */
           break;
         }
       if (LocaleCompare("colorize",option+1) == 0)
@@ -2035,13 +2052,13 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
              That seems to be a little strange!
           */
           (void) TransformImageColorspace(_image,
-                    IfNormalOp ? _image_info->colorspace : RGBColorspace,
+                    IfNormalOp ? _image_info->colorspace : sRGBColorspace,
                     _exception);
           break;
         }
       if (LocaleCompare("contrast",option+1) == 0)
         {
-          CLIWandWarnDepreciated(normal_op?"-level":"+level");
+          CLIWandWarnReplaced(normal_op?"-level":"+level");
           (void) ContrastImage(_image,normal_op,_exception);
           break;
         }
@@ -2054,9 +2071,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           MagickStatusType
             flags;
 
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           black_point=geometry_info.rho;
           white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
             black_point;
@@ -2064,7 +2081,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
               black_point*=(double) _image->columns*_image->rows/100.0;
               white_point*=(double) _image->columns*_image->rows/100.0;
             }
-          white_point=(MagickRealType) _image->columns*_image->rows-
+          white_point=(double) _image->columns*_image->rows-
             white_point;
           (void) ContrastStretchImage(_image,black_point,white_point,
             _exception);
@@ -2078,8 +2095,8 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           kernel_info=AcquireKernelInfo(arg1);
           if (kernel_info == (KernelInfo *) NULL)
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
-          /* kernel_info->bias=_image->bias; -- FUTURE: check this path! */
-          new_image=ConvolveImage(_image,kernel_info,_exception);
+          new_image=MorphologyImage(_image,CorrelateMorphology,1,kernel_info,
+            _exception);
           kernel_info=DestroyKernelInfo(kernel_info);
           break;
         }
@@ -2105,6 +2122,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     {
       if (LocaleCompare("decipher",option+1) == 0)
         {
+          /* Note: arguments do not have percent escapes expanded */
           StringInfo
             *passkey;
 
@@ -2151,21 +2169,11 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("distort",option+1) == 0)
         {
-          char
-            *args,
-            token[MaxTextExtent];
-
-          const char
-            *p;
-
           double
-            *arguments;
-
-          register ssize_t
-            x;
+            *args;
 
-          size_t
-            number_arguments;
+          ssize_t
+            count;
 
           parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
           if ( parse < 0 )
@@ -2189,42 +2197,14 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
                     (size_t)2,resize_args,MagickTrue,_exception);
                break;
             }
-          /* handle percent arguments */
-          args=InterpretImageProperties(_image_info,_image,arg2,_exception);
-          if (args == (char *) NULL)
-            break;
-          /* convert arguments into an array of doubles
-             FUTURE: make this a separate function.
-             Also make use of new 'sentinal' feature to avoid need for
-             tokenization.
-          */
-          p=(char *) args;
-          for (x=0; *p != '\0'; x++)
-          {
-            GetMagickToken(p,&p,token);
-            if (*token == ',')
-              GetMagickToken(p,&p,token);
-          }
-          number_arguments=(size_t) x;
-          arguments=(double *) AcquireQuantumMemory(number_arguments,
-            sizeof(*arguments));
-          if (arguments == (double *) NULL)
-            CLIWandExceptionBreak(ResourceLimitFatalError,
-                                "MemoryAllocationFailed",option);
-          (void) ResetMagickMemory(arguments,0,number_arguments*
-                        sizeof(*arguments));
-          p=(char *) args;
-          for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
-          {
-            GetMagickToken(p,&p,token);
-            if (*token == ',')
-              GetMagickToken(p,&p,token);
-            arguments[x]=StringToDouble(token,(char **) NULL);
-          }
-          args=DestroyString(args);
-          new_image=DistortImage(_image,(DistortImageMethod) parse,
-               number_arguments,arguments,plus_alt_op,_exception);
-          arguments=(double *) RelinquishMagickMemory(arguments);
+          /* convert argument string into an array of doubles */
+          args = StringToArrayOfDoubles(arg2,&count,_exception);
+          if (args == (double *)NULL )
+            CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
+
+          new_image=DistortImage(_image,(DistortImageMethod) parse,count,args,
+               plus_alt_op,_exception);
+          args=(double *) RelinquishMagickMemory(args);
           break;
         }
       if (LocaleCompare("draw",option+1) == 0)
@@ -2240,20 +2220,17 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     {
       if (LocaleCompare("edge",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
-          if ((flags & SigmaValue) == 0)
-            geometry_info.sigma=1.0;
-          new_image=EdgeImage(_image,geometry_info.rho,geometry_info.sigma,
-               _exception);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          new_image=EdgeImage(_image,geometry_info.rho,_exception);
           break;
         }
       if (LocaleCompare("emboss",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           new_image=EmbossImage(_image,geometry_info.rho,
@@ -2262,6 +2239,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("encipher",option+1) == 0)
         {
+          /* Note: arguments do not have percent escapes expanded */
           StringInfo
             *passkey;
 
@@ -2346,7 +2324,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
           (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
           (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
-                    geometry.y,plus_alt_op,_exception);
+            geometry.y,plus_alt_op,_exception);
           break;
         }
       if (LocaleCompare("frame",option+1) == 0)
@@ -2361,19 +2339,15 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
             value;
 
           value=GetImageOption(_image_info,"compose");
-          if (value != (const char *) NULL)
-            compose=(CompositeOperator) ParseCommandOption(
-                 MagickComposeOptions,MagickFalse,value);
-          else
             compose=OverCompositeOp;  /* use Over not _image->compose */
-
+          if (value != (const char *) NULL)
+            compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
+              MagickFalse,value);
           if (IfMagickFalse(IsGeometry(arg1)))
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
           frame_info.width=geometry.width;
           frame_info.height=geometry.height;
-          if ((flags & HeightValue) == 0)
-            frame_info.height=geometry.width;
           frame_info.outer_bevel=geometry.x;
           frame_info.inner_bevel=geometry.y;
           frame_info.x=(ssize_t) frame_info.width;
@@ -2385,60 +2359,24 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("function",option+1) == 0)
         {
-          char
-            *arguments,
-            token[MaxTextExtent];
-
-          const char
-            *p;
-
           double
-            *parameters;
+            *args;
 
-          register ssize_t
-            x;
-
-          size_t
-            number_parameters;
+          ssize_t
+            count;
 
-          /*
-            Function Modify Image Values
-            FUTURE: code should be almost a duplicate of that is "distort"
-          */
           parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
           if ( parse < 0 )
             CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
                  option,arg1);
-          arguments=InterpretImageProperties(_image_info,_image,arg2,
-            _exception);
-          if (arguments == (char *) NULL)
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
-          p=(char *) arguments;
-          for (x=0; *p != '\0'; x++)
-          {
-            GetMagickToken(p,&p,token);
-            if (*token == ',')
-              GetMagickToken(p,&p,token);
-          }
-          number_parameters=(size_t) x;
-          parameters=(double *) AcquireQuantumMemory(number_parameters,
-            sizeof(*parameters));
-          if (parameters == (double *) NULL)
-            ThrowWandFatalException(ResourceLimitFatalError,
-              "MemoryAllocationFailed",_image->filename);
-          (void) ResetMagickMemory(parameters,0,number_parameters*
-            sizeof(*parameters));
-          p=(char *) arguments;
-          for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++) {
-            GetMagickToken(p,&p,token);
-            if (*token == ',')
-              GetMagickToken(p,&p,token);
-            parameters[x]=StringToDouble(token,(char **) NULL);
-          }
-          arguments=DestroyString(arguments);
-          (void) FunctionImage(_image,(MagickFunction)parse,number_parameters,
-                  parameters,_exception);
-          parameters=(double *) RelinquishMagickMemory(parameters);
+          /* convert argument string into an array of doubles */
+          args = StringToArrayOfDoubles(arg2,&count,_exception);
+          if (args == (double *)NULL )
+            CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
+
+          (void) FunctionImage(_image,(MagickFunction)parse,count,args,
+               _exception);
+          args=(double *) RelinquishMagickMemory(args);
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
@@ -2447,20 +2385,33 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     {
       if (LocaleCompare("gamma",option+1) == 0)
         {
+          double
+            constant;
+
           if (IfMagickFalse(IsGeometry(arg1)))
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          constant=StringToDouble(arg1,(char **) NULL);
+#if 0
+          /* Using Gamma, via a cache */
+          if (IfPlusOp)
+            constant=PerceptibleReciprocal(constant);
+          (void) GammaImage(_image,constant,_exception);
+#else
+          /* Using Evaluate POW, direct update of values - more accurite */
           if (IfNormalOp)
-            (void) GammaImage(_image,StringToDouble(arg1,(char **) NULL),
-                 _exception);
-          else
-            _image->gamma=StringToDouble(arg1,(char **) NULL);
+            constant=PerceptibleReciprocal(constant);
+          (void) EvaluateImage(_image,PowEvaluateOperator,constant,_exception);
+#endif
+          /* Set gamma setting -- Old meaning of "+gamma"
+           * _image->gamma=StringToDouble(arg1,(char **) NULL);
+           */
           break;
         }
       if (LocaleCompare("gaussian-blur",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           new_image=GaussianBlurImage(_image,geometry_info.rho,
@@ -2469,7 +2420,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("gaussian",option+1) == 0)
         {
-          CLIWandWarnDepreciated("-gaussian-blur");
+          CLIWandWarnReplaced("-gaussian-blur");
           CLISimpleOperatorImage(cli_wand,"-gaussian-blur",arg1,NULL);
         }
       if (LocaleCompare("geometry",option+1) == 0)
@@ -2496,13 +2447,17 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
               _image->filter,_exception);
           break;
         }
-      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
-    }
-    case 'h':
-    {
-      if (LocaleCompare("highlight-color",option+1) == 0)
+      if (LocaleCompare("distort",option+1) == 0)
         {
-          (void) SetImageArtifact(_image,option+1,arg1);
+          parse = ParseCommandOption(MagickPixelIntensityOptions,
+            MagickFalse,arg1);
+          if ( parse < 0 )
+             CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
+               option,arg1);
+          _image->intensity = (PixelIntensityMethod) parse;
+          (void) TransformImageColorspace(_image,
+                    IfNormalOp ? _image_info->colorspace : GRAYColorspace,
+                    _exception);
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
@@ -2516,15 +2471,14 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
             *text;
 
           format=GetImageOption(_image_info,"format");
-          if (format == (char *) NULL)
-            {
-              (void) IdentifyImage(_image,stdout,_image_info->verbose,
-                _exception);
-              break;
-            }
+          if (format == (char *) NULL) {
+            (void) IdentifyImage(_image,stdout,_image_info->verbose,_exception);
+            break;
+          }
           text=InterpretImageProperties(_image_info,_image,format,_exception);
           if (text == (char *) NULL)
-            break;
+            CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
+                 option);
           (void) fputs(text,stdout);
           (void) fputc('\n',stdout);
           text=DestroyString((char *)text);
@@ -2532,11 +2486,11 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("implode",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
-          (void) ParseGeometry(arg1,&geometry_info);
-          new_image=ImplodeImage(_image,geometry_info.rho,
-            _image->interpolate,_exception);
+          new_image=ImplodeImage(_image,geometry_info.rho,_image->interpolate,
+               _exception);
           break;
         }
       if (LocaleCompare("interpolative-resize",option+1) == 0)
@@ -2556,9 +2510,11 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     {
       if (LocaleCompare("lat",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          if ((flags & SigmaValue) == 0)
+            geometry_info.sigma=1.0;
           if ((flags & PercentValue) != 0)
             geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
           new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
@@ -2568,7 +2524,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("level",option+1) == 0)
         {
-          MagickRealType
+          double
             black_point,
             gamma,
             white_point;
@@ -2576,11 +2532,11 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           MagickStatusType
             flags;
 
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           black_point=geometry_info.rho;
-          white_point=(MagickRealType) QuantumRange;
+          white_point=(double) QuantumRange;
           if ((flags & SigmaValue) != 0)
             white_point=geometry_info.sigma;
           gamma=1.0;
@@ -2588,11 +2544,11 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
             gamma=geometry_info.xi;
           if ((flags & PercentValue) != 0)
             {
-              black_point*=(MagickRealType) (QuantumRange/100.0);
-              white_point*=(MagickRealType) (QuantumRange/100.0);
+              black_point*=(double) (QuantumRange/100.0);
+              white_point*=(double) (QuantumRange/100.0);
             }
           if ((flags & SigmaValue) == 0)
-            white_point=(MagickRealType) QuantumRange-black_point;
+            white_point=(double) QuantumRange-black_point;
           if (IfPlusOp || ((flags & AspectValue) != 0))
             (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
           else
@@ -2647,11 +2603,11 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           MagickStatusType
             flags;
 
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           black_point=geometry_info.rho;
-          white_point=(MagickRealType) _image->columns*_image->rows;
+          white_point=(double) _image->columns*_image->rows;
           if ((flags & SigmaValue) != 0)
             white_point=geometry_info.sigma;
           if ((flags & PercentValue) != 0)
@@ -2660,7 +2616,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
               white_point*=(double) _image->columns*_image->rows/100.0;
             }
           if ((flags & SigmaValue) == 0)
-            white_point=(MagickRealType) _image->columns*_image->rows-
+            white_point=(double) _image->columns*_image->rows-
               black_point;
           (void) LinearStretchImage(_image,black_point,white_point,_exception);
           break;
@@ -2685,12 +2641,13 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     {
       if (LocaleCompare("map",option+1) == 0)
         {
-          CLIWandWarnDepreciated("-remap");
+          CLIWandWarnReplaced("-remap");
           CLISimpleOperatorImage(cli_wand,"-remap",NULL,NULL);
           break;
         }
       if (LocaleCompare("mask",option+1) == 0)
         {
+          /* Note: arguments do not have percent escapes expanded */
           Image
             *mask;
 
@@ -2709,21 +2666,21 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("matte",option+1) == 0)
         {
-          CLIWandWarnDepreciated(IfNormalOp?"-alpha Set":"-alpha Off");
+          CLIWandWarnReplaced(IfNormalOp?"-alpha Set":"-alpha Off");
           (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
                          DeactivateAlphaChannel, _exception);
           break;
         }
       if (LocaleCompare("median",option+1) == 0)
         {
-          CLIWandWarnDepreciated("-statistic Median");
+          CLIWandWarnReplaced("-statistic Median");
           CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1);
           break;
         }
       if (LocaleCompare("mode",option+1) == 0)
         {
           /* FUTURE: note this is also a special "montage" option */
-          CLIWandWarnDepreciated("-statistic Mode");
+          CLIWandWarnReplaced("-statistic Mode");
           CLISimpleOperatorImage(cli_wand,"-statistic","Mode",arg1);
           break;
         }
@@ -2782,9 +2739,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("motion-blur",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           new_image=MotionBlurImage(_image,geometry_info.rho,
@@ -2810,7 +2767,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
 
           if (IfNormalOp)
             {
-              CLIWandWarnDepreciated("-statistic NonPeak");
+              CLIWandWarnReplaced("-statistic NonPeak");
               CLISimpleOperatorImage(cli_wand,"-statistic","NonPeak",arg1);
               break;
             }
@@ -2856,11 +2813,19 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     {
       if (LocaleCompare("paint",option+1) == 0)
         {
-          (void) ParseGeometry(arg1,&geometry_info);
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
                _exception);
           break;
         }
+      if (LocaleCompare("perceptible",option+1) == 0)
+        {
+          (void) PerceptibleImage(_image,StringToDouble(arg1,(char **) NULL),
+            _exception);
+          break;
+        }
       if (LocaleCompare("polaroid",option+1) == 0)
         {
           const char
@@ -2878,9 +2843,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
             random_info=DestroyRandomInfo(random_info);
           }
           else {
-            if (IfMagickFalse(IsGeometry(arg1)))
-              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
             flags=ParseGeometry(arg1,&geometry_info);
+            if ((flags & RhoValue) == 0)
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
             angle=geometry_info.rho;
           }
           caption=GetImageProperty(_image,"caption",_exception);
@@ -2890,11 +2855,11 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("posterize",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
-          (void) ParseGeometry(arg1,&geometry_info);
           (void) PosterizeImage(_image,(size_t) geometry_info.rho,
-               _quantize_info->dither,_exception);
+            _quantize_info->dither_method,_exception);
           break;
         }
       if (LocaleCompare("preview",option+1) == 0)
@@ -2912,6 +2877,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("profile",option+1) == 0)
         {
+          /* Note: arguments do not have percent escapes expanded */
           const char
             *name;
 
@@ -2975,9 +2941,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     {
       if (LocaleCompare("radial-blur",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           new_image=RadialBlurImage(_image,geometry_info.rho,_exception);
           break;
         }
@@ -2986,8 +2952,6 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           if (IfMagickFalse(IsGeometry(arg1)))
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
-          if ((flags & SigmaValue) == 0)
-            geometry.height=geometry.width;
           (void) RaiseImage(_image,&geometry,normal_op,_exception);
           break;
         }
@@ -3000,11 +2964,12 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("recolor",option+1) == 0)
         {
-          CLIWandWarnDepreciated("-color-matrix");
+          CLIWandWarnReplaced("-color-matrix");
           CLISimpleOperatorImage(cli_wand,"-color-matrix",arg1,NULL);
         }
       if (LocaleCompare("remap",option+1) == 0)
         {
+          /* Note: arguments do not have percent escapes expanded */
           Image
             *remap_image;
 
@@ -3031,9 +2996,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
       if (LocaleCompare("resample",option+1) == 0)
         {
           /* FUTURE: Roll into a resize special operation */
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=geometry_info.rho;
           new_image=ResampleImage(_image,geometry_info.rho,
@@ -3059,15 +3024,13 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("rotate",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
-          if (strchr(arg1,'>') != (char *) NULL)
-            if (_image->columns <= _image->rows)
-              break;
-          if (strchr(arg1,'<') != (char *) NULL)
-            if (_image->columns >= _image->rows)
-              break;
-          (void) ParseGeometry(arg1,&geometry_info);
+          if ((flags & GreaterValue) != 0 && (_image->columns <= _image->rows))
+            break;
+          if ((flags & LessValue) != 0 && (_image->columns >= _image->rows))
+            break;
           new_image=RotateImage(_image,geometry_info.rho,_exception);
           break;
         }
@@ -3097,9 +3060,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("segment",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           (void) SegmentImage(_image,_image->colorspace,
@@ -3109,9 +3072,11 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("selective-blur",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          if ((flags & SigmaValue) == 0)
+            geometry_info.sigma=1.0;
           if ((flags & PercentValue) != 0)
             geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
           new_image=SelectiveBlurImage(_image,geometry_info.rho,
@@ -3133,56 +3098,20 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
                  (double) QuantumRange+1.0),_exception);
           break;
         }
-      if (LocaleCompare("set",option+1) == 0)
-        {
-          char
-            *value;
-
-          if (IfPlusOp) {
-              if (LocaleNCompare(arg1,"registry:",9) == 0)
-                (void) DeleteImageRegistry(arg1+9);
-              else
-                if (LocaleNCompare(arg1,"option:",7) == 0)
-                  {
-                    (void) DeleteImageOption(_image_info,arg1+7);
-                    (void) DeleteImageArtifact(_image,arg1+7);
-                  }
-                else
-                  (void) DeleteImageProperty(_image,arg1);
-              break;
-            }
-          value=InterpretImageProperties(_image_info,_image,arg2,_exception);
-          if (value == (char *) NULL)
-            break;
-          if (LocaleNCompare(arg1,"registry:",9) == 0)
-            (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
-          else
-            if (LocaleNCompare(arg1,"option:",7) == 0)
-              {
-                (void) SetImageOption(_image_info,arg1+7,value);
-                (void) SetImageArtifact(_image,arg1+7,value);
-              }
-            else
-              (void) SetImageProperty(_image,arg1,value,_exception);
-          value=DestroyString(value);
-          break;
-        }
       if (LocaleCompare("shade",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
-          if ((flags & SigmaValue) == 0)
-            geometry_info.sigma=1.0;
+          if (((flags & RhoValue) == 0) || ((flags & SigmaValue) == 0))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           new_image=ShadeImage(_image,normal_op,geometry_info.rho,
                geometry_info.sigma,_exception);
           break;
         }
       if (LocaleCompare("shadow",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           if ((flags & XiValue) == 0)
@@ -3196,9 +3125,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("sharpen",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           if ((flags & XiValue) == 0)
@@ -3217,35 +3146,34 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("shear",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=geometry_info.rho;
-          new_image=ShearImage(_image,geometry_info.rho,
-            geometry_info.sigma,_exception);
+          new_image=ShearImage(_image,geometry_info.rho,geometry_info.sigma,
+            _exception);
           break;
         }
       if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=(double) QuantumRange/2.0;
           if ((flags & PercentValue) != 0)
             geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
               100.0;
           (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
-               geometry_info.sigma,
-            _exception);
+               geometry_info.sigma,_exception);
           break;
         }
       if (LocaleCompare("sketch",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           new_image=SketchImage(_image,geometry_info.rho,
@@ -3262,34 +3190,27 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("sparse-color",option+1) == 0)
         {
-          char
-            *arguments;
-
           parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
           if ( parse < 0 )
             CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
                 option,arg1);
-          arguments=InterpretImageProperties(_image_info,_image,arg2,_exception);
-          if (arguments == (char *) NULL)
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
-          new_image=SparseColorOption(_image,(SparseColorMethod)parse,
-               arguments,_exception);
-          arguments=DestroyString(arguments);
+          new_image=SparseColorOption(_image,(SparseColorMethod)parse,arg2,
+               _exception);
           break;
         }
       if (LocaleCompare("splice",option+1) == 0)
         {
           if (IfMagickFalse(IsGeometry(arg1)))
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
-          (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
+          flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
           new_image=SpliceImage(_image,&geometry,_exception);
           break;
         }
       if (LocaleCompare("spread",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
-          (void) ParseGeometry(arg1,&geometry_info);
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
           new_image=SpreadImage(_image,geometry_info.rho,_image->interpolate,
                _exception);
           break;
@@ -3300,9 +3221,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
           if ( parse < 0 )
             CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
                  option,arg1);
-          if (IfMagickFalse(IsGeometry(arg2)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
           flags=ParseGeometry(arg2,&geometry_info);
+          if ((flags & RhoValue) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=geometry_info.rho;
           new_image=StatisticImage(_image,(StatisticType)parse,
@@ -3317,9 +3238,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("swirl",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
-          (void) ParseGeometry(arg1,&geometry_info);
           new_image=SwirlImage(_image,geometry_info.rho,
             _image->interpolate,_exception);
           break;
@@ -3360,7 +3281,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("transform",option+1) == 0)
         {
-          CLIWandWarnDepreciated("+distort AffineProjection");
+          CLIWandWarnReplaced("+distort AffineProjection");
           new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
           break;
         }
@@ -3420,9 +3341,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("unsharp",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           if ((flags & XiValue) == 0)
@@ -3449,9 +3370,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("vignette",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           if ((flags & XiValue) == 0)
@@ -3469,9 +3390,9 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     {
       if (LocaleCompare("wave",option+1) == 0)
         {
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
@@ -3490,14 +3411,18 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
     default:
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
   }
-  /*
-     Replace current image with any image that was generated
-     and set image point to last image (so image->next is correct)
-  */
+  /* clean up percent escape interpreted strings */
+  if (arg1 != arg1n )
+    arg1=DestroyString((char *)arg1);
+  if (arg2 != arg2n )
+    arg2=DestroyString((char *)arg2);
+
+  /* Replace current image with any image that was generated
+     and set image point to last image (so image->next is correct) */
   if (new_image != (Image *) NULL)
     ReplaceImageInListReturnLast(&_image,new_image);
 
-  return;
+  return(MagickTrue);
 #undef _image_info
 #undef _draw_info
 #undef _quantize_info
@@ -3509,12 +3434,14 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
 #undef plus_alt_op
 }
 
-WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
-  const char *option, const char *arg1, const char *arg2)
+WandPrivate MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,
+  const char *option,const char *arg1,const char *arg2)
 {
+#if !USE_WAND_METHODS
   size_t
     n,
     i;
+#endif
 
   assert(cli_wand != (MagickCLI *) NULL);
   assert(cli_wand->signature == WandSignature);
@@ -3543,7 +3470,7 @@ WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
     CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
   MagickResetIterator(&cli_wand->wand);
 #endif
-  return;
+  return(MagickTrue);
 }
 \f
 /*
@@ -3559,12 +3486,13 @@ WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
 %
 %  CLIListOperatorImages() applies a single operation that is apply to the
 %  entire image list as a whole. The result is often a complete replacment
-%  of the image list with a completely new list, or just a single image.
+%  of the image list with a completely new list, or with just a single image
+%  result.
 %
 %  The format of the MogrifyImage method is:
 %
-%    void CLIListOperatorImages(MagickCLI *cli_wand,
-%        const char *option, const char *arg1, const char *arg2)
+%    MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
+%      const char *option,const char *arg1,const char *arg2)
 %
 %  A description of each parameter follows:
 %
@@ -3575,42 +3503,30 @@ WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
 %    o arg1, arg2: optional argument strings to the operation
 %        arg2 is currently not used
 %
-% Example usage...
-%
-%  CLIListOperatorImages(cli_wand,MagickFalse,"-duplicate", "3",  NULL);
-%  CLIListOperatorImages(cli_wand,MagickTrue, "+append",    NULL, NULL);
-%
-% Or for handling command line arguments EG: +/-option ["arg1"]
-%
-%    cli_wand
-%    argc,argv
-%    i=index in argv
-%
-%    option_info = GetCommandOptionInfo(argv[i]);
-%    count=option_info->type;
-%    option_type=option_info->flags;
-%
-%    if ( (option_type & ListOperatorOptionFlag) != 0 )
-%      CLIListOperatorImages(cli_wand,argv[i],
-%          count>=1 ? argv[i+1] : (char *)NULL,
-%          count>=2 ? argv[i+2] : (char *)NULL );
-%    i += count+1;
-%
 */
-WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
-     const char *option,const char *arg1, const char *magick_unused(arg2))
+WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
+  const char *option,const char *arg1n,const char *arg2n)
 {
-  ssize_t
-    parse;
+  const char    /* For percent escape interpretImageProperties() */
+    *arg1,
+    *arg2;
 
   Image
     *new_images;
 
+  MagickStatusType
+    status;
+
+  ssize_t
+    parse;
+
 #define _image_info     (cli_wand->wand.image_info)
 #define _images         (cli_wand->wand.images)
 #define _exception      (cli_wand->wand.exception)
 #define _draw_info      (cli_wand->draw_info)
 #define _quantize_info  (cli_wand->quantize_info)
+#define _process_flags  (cli_wand->process_flags)
+#define _option_type    ((CommandOptionFlags) cli_wand->command->flags)
 #define IfNormalOp      (*option=='-')
 #define IfPlusOp        (*option!='-')
 #define normal_op       IsMagickTrue(IfNormalOp)
@@ -3622,8 +3538,37 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
   if (IfMagickTrue(cli_wand->wand.debug))
     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
 
-  (void) SyncImagesSettings(_image_info,_images,_exception);
+  /* Interpret Percent Escapes in Arguments - using first image */
+  arg1 = arg1n;
+  arg2 = arg2n;
+  if ( (((_process_flags & ProcessInterpretProperities) != 0 )
+        || ((_option_type & AlwaysInterpretArgsFlag) != 0)
+       )  && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
+    /* Interpret Percent escapes in argument 1 */
+    if (arg1n != (char *) NULL) {
+      arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
+      if (arg1 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg1=arg1n;  /* use the given argument as is */
+      }
+    }
+    if (arg2n != (char *) NULL) {
+      arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
+      if (arg2 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg2=arg2n;  /* use the given argument as is */
+      }
+    }
+  }
+#undef _process_flags
+#undef _option_type
+
+#if 0
+  (void) FormatLocaleFile(stderr,
+    "CLIListOperatorImages: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
+#endif
 
+  status=MagickTrue;
   new_images=NewImageList();
 
   switch (*(option+1))
@@ -3637,7 +3582,7 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
         }
       if (LocaleCompare("average",option+1) == 0)
         {
-          CLIWandWarnDepreciated("-evaluate-sequence Mean");
+          CLIWandWarnReplaced("-evaluate-sequence Mean");
           CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
           break;
         }
@@ -3676,7 +3621,11 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
       if (LocaleCompare("combine",option+1) == 0)
         {
           /* FUTURE - this may be replaced by a 'channel' method */
-          new_images=CombineImages(_images,_exception);
+          parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
+              arg1);
+          new_images=CombineImages(_images,(ColorspaceType) parse,_exception);
           break;
         }
       if (LocaleCompare("composite",option+1) == 0)
@@ -3726,32 +3675,44 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
           /* FUTURE - this should not be here! - should be part of -geometry */
           (void) TransformImage(&source_image,(char *) NULL,
             source_image->geometry,_exception);
-
           SetGeometry(source_image,&geometry);
           (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
           GravityAdjustGeometry(new_images->columns,new_images->rows,
-               new_images->gravity, &geometry);
-
+            new_images->gravity, &geometry);
           mask_image=RemoveFirstImageFromList(&_images);
           if (mask_image != (Image *) NULL)
-            { /* handle a third write mask image */
+            {
               if ((compose == DisplaceCompositeOp) ||
-                  (compose == DistortCompositeOp)) {
-                /* Merge Y displacement into X displace/distort map. */
-                (void) CompositeImage(source_image,mask_image,
+                  (compose == DistortCompositeOp))
+                status&=CompositeImage(source_image,mask_image,
                   CopyGreenCompositeOp,MagickTrue,0,0,_exception);
-                mask_image=DestroyImage(mask_image);
-              }
-              else {
-                /* Set a blending mask for the composition.  */
-                (void) NegateImage(mask_image,MagickFalse,_exception);
-                (void) SetImageMask(new_images,mask_image,_exception);
-                mask_image=DestroyImage(mask_image);
-              }
+              else
+                {
+                  Image
+                    *image;
+
+                  RectangleInfo
+                    source_geometry;
+
+                  source_geometry.width=mask_image->columns;
+                  source_geometry.height=mask_image->rows;
+                  source_geometry.x=(-geometry.x);
+                  source_geometry.y=(-geometry.y);
+                  geometry.x=0;
+                  geometry.y=0;
+                  image=ExtentImage(source_image,&source_geometry,_exception);
+                  if (image != (Image *) NULL)
+                    {
+                      source_image=DestroyImage(source_image);
+                      source_image=image;
+                    }
+                  status&=CompositeImage(source_image,mask_image,
+                    IntensityCompositeOp,MagickTrue,0,0,_exception);
+                }
+              mask_image=DestroyImage(mask_image);
             }
-          (void) CompositeImage(new_images,source_image,compose,clip_to_self,
+          status&=CompositeImage(new_images,source_image,compose,clip_to_self,
             geometry.x,geometry.y,_exception);
-          (void) SetImageMask(new_images,(Image *) NULL,_exception);
           source_image=DestroyImage(source_image);
           break;
         }
@@ -3761,7 +3722,7 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
     {
       if (LocaleCompare("deconstruct",option+1) == 0)
         {
-          CLIWandWarnDepreciated("-layer CompareAny");
+          CLIWandWarnReplaced("-layer CompareAny");
           CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
           break;
         }
@@ -3916,7 +3877,7 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
           if ( parse < 0 )
             CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
                  option,arg1);
-          switch ((ImageLayerMethod) parse)
+          switch ((LayerMethod) parse)
           {
             case CoalesceLayer:
             {
@@ -3928,7 +3889,7 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
             case CompareOverlayLayer:
             default:
             {
-              new_images=CompareImagesLayers(_images,(ImageLayerMethod) parse,
+              new_images=CompareImagesLayers(_images,(LayerMethod) parse,
                    _exception);
               break;
             }
@@ -3937,7 +3898,7 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
             case MosaicLayer:
             case TrimBoundsLayer:
             {
-              new_images=MergeImageLayers(_images,(ImageLayerMethod) parse,
+              new_images=MergeImageLayers(_images,(LayerMethod) parse,
                    _exception);
               break;
             }
@@ -4059,7 +4020,7 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
     {
       if (LocaleCompare("map",option+1) == 0)
         {
-          CLIWandWarnDepreciated("+remap");
+          CLIWandWarnReplaced("+remap");
           (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
           break;
         }
@@ -4088,20 +4049,30 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
     }
     case 'p':
     {
-      if (LocaleCompare("print",option+1) == 0)
+      if (LocaleCompare("poly",option+1) == 0)
         {
-          char
-            *string;
+          double
+            *args;
 
-          string=InterpretImageProperties(_image_info,_images,arg1,_exception);
-          if (string == (char *) NULL)
-            break;
-          (void) FormatLocaleFile(stdout,"%s",string);
-          string=DestroyString(string);
+          ssize_t
+            count;
+
+          /* convert argument string into an array of doubles */
+          args = StringToArrayOfDoubles(arg2,&count,_exception);
+          if (args == (double *)NULL )
+            CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
+          new_images=PolynomialImage(_images,count >> 1,args,_exception);
+          args=(double *) RelinquishMagickMemory(args);
+          break;
+        }
+      if (LocaleCompare("print",option+1) == 0)
+        {
+          (void) FormatLocaleFile(stdout,"%s",arg1);
           break;
         }
       if (LocaleCompare("process",option+1) == 0)
         {
+          /* FUTURE: better parsing using ScriptToken() from string ??? */
           char
             **arguments;
 
@@ -4188,20 +4159,68 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
     {
       if (LocaleCompare("smush",option+1) == 0)
         {
-          Image
-            *smush_image;
-
+          /* FUTURE: this option needs more work to make better */
           ssize_t
             offset;
 
           if (IfMagickFalse(IsGeometry(arg1)))
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           offset=(ssize_t) StringToLong(arg1);
-          smush_image=SmushImages(_images,normal_op,offset,_exception);
-          if (smush_image == (Image *) NULL)
-            break;
-          _images=DestroyImageList(_images);
-          _images=smush_image;
+          new_images=SmushImages(_images,normal_op,offset,_exception);
+          break;
+        }
+      if (LocaleCompare("subimage",option+1) == 0)
+        {
+          Image
+            *base_image,
+            *compare_image;
+
+          const char *
+            value;
+
+          MetricType
+            metric;
+
+          double
+            similarity;
+
+          RectangleInfo
+            offset;
+
+          base_image=GetImageFromList(_images,0);
+          compare_image=GetImageFromList(_images,1);
+
+          /* Comparision Metric */
+          metric=UndefinedMetric;
+          value=GetImageOption(_image_info,"metric");
+          if (value != (const char *) NULL)
+            metric=(MetricType) ParseCommandOption(MagickMetricOptions,
+              MagickFalse,value);
+
+          new_images=SimilarityImage(base_image,compare_image,metric,0.0,
+               &offset,&similarity,_exception);
+
+          if ( new_images != (Image *)NULL ) {
+            char
+              result[MaxTextExtent];
+
+            (void) FormatLocaleString(result,MaxTextExtent,"%lf",similarity);
+            (void) SetImageProperty(new_images,"subimage:similarity",result,
+                 _exception);
+            (void) FormatLocaleString(result,MaxTextExtent,"%+ld",
+                (long) offset.x);
+            (void) SetImageProperty(new_images,"subimage:x",result,
+                 _exception);
+            (void) FormatLocaleString(result,MaxTextExtent,"%+ld",
+                (long) offset.y);
+            (void) SetImageProperty(new_images,"subimage:y",result,
+                 _exception);
+            (void) FormatLocaleString(result,MaxTextExtent,"%lux%lu%+ld%+ld",
+                (unsigned long) offset.width,(unsigned long) offset.height,
+                (long) offset.x,(long) offset.y);
+            (void) SetImageProperty(new_images,"subimage:offset",result,
+                 _exception);
+          }
           break;
         }
       if (LocaleCompare("swap",option+1) == 0) {
@@ -4214,8 +4233,8 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
           index,
           swap_index;
 
-        index=-1;
-        swap_index=-2;
+        index=(-1);
+        swap_index=(-2);
         if (IfNormalOp) {
           GeometryInfo
             geometry_info;
@@ -4224,9 +4243,9 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
             flags;
 
           swap_index=(-1);
-          if (IfMagickFalse(IsGeometry(arg1)))
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & RhoValue) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           index=(ssize_t) geometry_info.rho;
           if ((flags & SigmaValue) != 0)
             swap_index=(ssize_t) geometry_info.sigma;
@@ -4252,13 +4271,19 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
     default:
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
   }
-  if (new_images == (Image *) NULL)
-    return;
 
-  if (_images != (Image *) NULL)
-    _images=DestroyImageList(_images);
+  /* clean up percent escape interpreted strings */
+  if (arg1 != arg1n )
+    arg1=DestroyString((char *)arg1);
+  if (arg2 != arg2n )
+    arg2=DestroyString((char *)arg2);
+
+  /* if new image list generated, replace existing image list */
+  if (new_images == (Image *) NULL)
+    return(status);
+  _images=DestroyImageList(_images);
   _images=GetFirstImageInList(new_images);
-  return;
+  return(status);
 
 #undef _image_info
 #undef _images
@@ -4275,59 +4300,46 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+   C L I S p e c i a l O p e r a t i o n s                                   %
++   C L I N o I m a g e O p e r a t i o n s                                   %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  CLISpecialOperator() Applies operations that may not actually need images
-%  in an image list wen it is applied.
+%  CLINoImageOperator() Applies operations that may not actually need images
+%  in an image list.
 %
-%  The classic operators of this type is -read, which actually creates images
-%  even when no images are present.  Or image stack operators, which can be
-%  applied to empty image lists.
+%  The classic operators of this type is "-read", which actually creates
+%  images even when no images are present.  Or image stack operators, which
+%  can be applied (push or pop) to an empty image list.
 %
-%  Note: unlike other Operators, these may involve other special 'option'
-%  character prefixes, other than simply '-' or '+'.
+%  Note that these operators may involve other special 'option' prefix
+%  characters other  than '-' or '+', namely parenthesis and braces.
 %
-%  The format of the CLISpecialOption method is:
+%  The format of the CLINoImageOption method is:
 %
-%      void CLISpecialOption(MagickCLI *cli_wand,const char *option,
-%           const char *arg1)
+%      void CLINoImageOption(MagickCLI *cli_wand,const char *option,
+%           const char *arg1, const char *arg2)
 %
 %  A description of each parameter follows:
 %
-%    o cli_wand: the main CLI Wand to use.
+%    o cli_wand: the main CLI Wand to use. (sometimes not required)
 %
 %    o option: The special option (with any switch char) to process
 %
-%    o arg1: Argument for option, if required
-%
-% Example Usage...
-%
-%  CLISpecialOperator(cli_wand,"-read","rose:");
-%
-% Or for handling command line arguments EG: +/-option ["arg1"]
-%
-%    cli_wand
-%    argc,argv
-%    i=index in argv
-%
-%    option_info = GetCommandOptionInfo(argv[i]);
-%    count=option_info->type;
-%    option_type=option_info->flags;
-%
-%    if ( (option_type & SpecialOptionFlag) != 0 )
-%      CLISpecialOperator(cli_wand,argv[i],
-%          count>=1 ? argv[i+1] : (char *)NULL);
-%    i += count+1;
+%    o arg1 & arg2: Argument for option, if required
+%                   Currently arg2 is not used.
 %
 */
-
-WandExport void CLISpecialOperator(MagickCLI *cli_wand,
-  const char *option, const char *arg1)
+WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
+  const char *option,const char *arg1,const char *arg2)
 {
+#if 0
+  const char    /* For percent escape interpretImageProperties() */
+    *arg1,
+    *arg2;
+#endif
+
 #define _image_info     (cli_wand->wand.image_info)
 #define _images         (cli_wand->wand.images)
 #define _exception      (cli_wand->wand.exception)
@@ -4340,322 +4352,450 @@ WandExport void CLISpecialOperator(MagickCLI *cli_wand,
   if (IfMagickTrue(cli_wand->wand.debug))
     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
 
-  if(_images != (Image *)NULL)
-    (void) SyncImagesSettings(cli_wand->wand.image_info,_images,_exception);
-
-  /*
-    No-op options  (ignore these)
-  */
-  if (LocaleCompare("noop",option+1) == 0)   /* no argument */
-    return;
-  if (LocaleCompare("sans",option+1) == 0)   /* one argument */
-    return;
-  if (LocaleCompare("sans0",option+1) == 0)  /* no argument */
-    return;
-  if (LocaleCompare("sans2",option+1) == 0)  /* two arguments */
-    return;
-  /*
-    Image Reading
-  */
-  if ( ( LocaleCompare("read",option+1) == 0 ) ||
-     ( LocaleCompare("--",option) == 0 ) ) {
-    int
-      argc;
-    char
-      **argv;
-
-    ssize_t
-      i;
-
-    /* Expand the filename argument (meta-characters or "@filelist" ) */
-    argc = 1;
-    argv = (char **) &arg1;
-    MagickBooleanType
-      status=ExpandFilenames(&argc,&argv);
-
-    if (IfMagickFalse(status))
-      CLIWandExceptArgReturn(ResourceLimitError,"MemoryAllocationFailed",
-          option,GetExceptionMessage(errno));
-
-    /* loop over expanded list reading images */
-    for (i=0; i<argc; i++) {
-#if !USE_WAND_METHODS
-      Image *
-        new_images;
-      if (IfMagickTrue(_image_info->ping))
-        new_images=PingImages(_image_info,argv[i],_exception);
-      else
-        new_images=ReadImages(_image_info,argv[i],_exception);
-      AppendImageToList(&_images, new_images);
-#else
-      /* read images using MagickWand method - no ping */
-      /* This is not working! - it locks up in a CPU loop! */
-      MagickSetLastIterator(&cli_wand->wand);
-      MagickReadImage(&cli_wand->wand,arg1);
-      MagickSetFirstIterator(&cli_wand->wand);
-#endif
+#if 0
+  Not able to be used as their may not be any images!
+  Also the only option that may have arguments that can be percent escaped is
+  "-clone".
+
+#define _process_flags  (cli_wand->process_flags)
+#define _option_type    ((CommandOptionFlags) cli_wand->command->flags)
+  /* Interpret Percent Escapes in Arguments - using first image */
+  arg1 = arg1n;
+  arg2 = arg2n;
+  if ( (((_process_flags & ProcessInterpretProperities) != 0 )
+        || ((_option_type & AlwaysInterpretArgsFlag) != 0)
+       )  && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
+    /* Interpret Percent escapes in argument 1 */
+    if (arg1n != (char *) NULL) {
+      arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
+      if (arg1 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg1=arg1n;  /* use the given argument as is */
+      }
+    }
+    if (arg2n != (char *) NULL) {
+      arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
+      if (arg2 == (char *) NULL) {
+        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+        arg2=arg2n;  /* use the given argument as is */
+      }
     }
-    /* FUTURE: how do I free the expanded filename arguments??? */
-
-    return;
   }
-  /*
-    Image Writing  (no-images present is valid in specific cases)
-  */
-  if (LocaleCompare("write",option+1) == 0) {
-    char
-      key[MaxTextExtent];
+#undef _process_flags
+#undef _option_type
+#endif
 
-    Image
-      *write_images;
+  do {  /* break to exit code */
+    /*
+      No-op options  (ignore these)
+    */
+    if (LocaleCompare("noop",option+1) == 0)   /* zero argument */
+      break;
+    if (LocaleCompare("sans",option+1) == 0)   /* one argument */
+      break;
+    if (LocaleCompare("sans0",option+1) == 0)  /* zero argument */
+      break;
+    if (LocaleCompare("sans1",option+1) == 0)  /* one argument */
+      break;
+    if (LocaleCompare("sans2",option+1) == 0)  /* two arguments */
+      break;
+    /*
+      Image Reading
+    */
+    if ( ( LocaleCompare("read",option+1) == 0 ) ||
+      ( LocaleCompare("--",option) == 0 ) ) {
+      /* Do Glob filename Expansion for 'arg1' then read all images.
+      *
+      * Expansion handles '@', '~', '*', and '?' meta-characters while ignoring
+      * (but attaching to the filenames in the generated argument list) any
+      * [...] read modifiers that may be present.
+      *
+      * For example: It will expand '*.gif[20x20]' into a list such as
+      * 'abc.gif[20x20]',  'foobar.gif[20x20]',  'xyzzy.gif[20x20]'
+      *
+      * NOTE: In IMv6 this was done globally across all images. This
+      * meant you could include IM options in '@filename' lists, but you
+      * could not include comments.   Doing it only for image read makes
+      * it far more secure.
+      *
+      * Note: arguments do not have percent escapes expanded for security
+      * reasons.
+      */
+      int      argc;
+      char     **argv;
+      ssize_t  i;
 
-    ImageInfo
-      *write_info;
+      argc = 1;
+      argv = (char **) &arg1;
 
-    /* Need images, unless a "null:" output coder is used */
-    if ( cli_wand->wand.images == (Image *) NULL ) {
-      if ( LocaleCompare(arg1,"null:") == 0 )
-        return;
-      CLIWandExceptArgReturn(OptionError,"NoImagesForWrite",option,arg1);
+      /* Expand 'glob' expressions in the given filename.
+        Expansion handles any 'coder:' prefix, or read modifiers attached
+        to the filename, including them in the resulting expanded list.
+      */
+      if (IfMagickFalse(  ExpandFilenames(&argc,&argv)  ))
+        CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
+            option,GetExceptionMessage(errno));
+
+      /* loop over expanded filename list, and read then all in */
+      for (i=0; i<argc; i++) {
+        Image *
+          new_images;
+        if (IfMagickTrue(_image_info->ping))
+          new_images=PingImages(_image_info,argv[i],_exception);
+        else
+          new_images=ReadImages(_image_info,argv[i],_exception);
+        AppendImageToList(&_images, new_images);
+      }
+      argv=DestroyStringList(argv);  /* Destroy the Expanded Filename list */
+      break;
     }
+    /*
+      Image Writing
+      Note: Writing a empty image list is valid in specific cases
+    */
+    if (LocaleCompare("write",option+1) == 0) {
+      /* Note: arguments do not have percent escapes expanded */
+      char
+        key[MaxTextExtent];
 
-    (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
-    (void) DeleteImageRegistry(key);
-    write_images=_images;
-    if (IfPlusOp)
-      write_images=CloneImageList(_images,_exception);
-    write_info=CloneImageInfo(_image_info);
-    (void) WriteImages(write_info,write_images,arg1,_exception);
-    write_info=DestroyImageInfo(write_info);
-    if (IfPlusOp)
-      write_images=DestroyImageList(write_images);
-    return;
-  }
-  /*
-    Parenthesis and Brace operations
-  */
-  if (LocaleCompare("(",option) == 0) {
-    /* stack 'push' images */
-    Stack
-      *node;
-
-    size_t
-      size;
-
-    size=0;
-    node=cli_wand->image_list_stack;
-    for ( ; node != (Stack *)NULL; node=node->next)
-      size++;
-    if ( size >= MAX_STACK_DEPTH )
-      CLIWandExceptionReturn(OptionError,"ParenthesisNestedTooDeeply",option);
-    node=(Stack *) AcquireMagickMemory(sizeof(*node));
-    if (node == (Stack *) NULL)
-      CLIWandExceptionReturn(ResourceLimitFatalError,
-           "MemoryAllocationFailed",option);
-    node->data = (void *)cli_wand->wand.images;
-    cli_wand->wand.images = NewImageList();
-    node->next = cli_wand->image_list_stack;
-    cli_wand->image_list_stack = node;
-
-    /* handle respect-parenthesis */
-    if (IfMagickTrue(IsStringTrue(GetImageOption(cli_wand->wand.image_info,
-                  "respect-parenthesis"))))
-      option="{"; /* fall-thru so as to push image settings too */
-    else
-      return;
-  }
-  if (LocaleCompare("{",option) == 0) {
-    /* stack 'push' of image_info settings */
-    Stack
-      *node;
-
-    size_t
-      size;
-
-    size=0;
-    node=cli_wand->image_info_stack;
-    for ( ; node != (Stack *)NULL; node=node->next)
-      size++;
-    if ( size >= MAX_STACK_DEPTH )
-      CLIWandExceptionReturn(OptionError,"CurlyBracesNestedTooDeeply",option);
-    node=(Stack *) AcquireMagickMemory(sizeof(*node));
-    if (node == (Stack *) NULL)
-      CLIWandExceptionReturn(ResourceLimitFatalError,
-           "MemoryAllocationFailed",option);
-
-    node->data = (void *)cli_wand->wand.image_info;
-    cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
-    if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
-      CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
-           option);
-      cli_wand->wand.image_info = (ImageInfo *)node->data;
-      node = (Stack *)RelinquishMagickMemory(node);
-      return;
-    }
+      Image
+        *write_images;
 
-    node->next = cli_wand->image_info_stack;
-    cli_wand->image_info_stack = node;
+      ImageInfo
+        *write_info;
 
-    return;
-  }
-  if (LocaleCompare(")",option) == 0) {
-    /* pop images from stack */
-    Stack
-      *node;
-
-    node = (Stack *)cli_wand->image_list_stack;
-    if ( node == (Stack *)NULL)
-      CLIWandExceptionReturn(OptionError,"UnbalancedParenthesis",option);
-    cli_wand->image_list_stack = node->next;
-
-    AppendImageToList((Image **)&node->data,cli_wand->wand.images);
-    cli_wand->wand.images= (Image *)node->data;
-    node = (Stack *)RelinquishMagickMemory(node);
-
-    /* handle respect-parenthesis - of the previous 'pushed' settings */
-    node = cli_wand->image_info_stack;
-    if ( node != (Stack *)NULL)
-      {
-        if (IfMagickTrue(IsStringTrue(GetImageOption(
-               cli_wand->wand.image_info,"respect-parenthesis"))))
-          option="}"; /* fall-thru so as to pop image settings too */
-        else
-          return;
+      /* Need images, unless a "null:" output coder is used */
+      if ( cli_wand->wand.images == (Image *) NULL ) {
+        if ( LocaleCompare(arg1,"null:") == 0 )
+          break;
+        CLIWandExceptArgBreak(OptionError,"NoImagesForWrite",option,arg1);
       }
-    else
-      return;
-  }
-  if (LocaleCompare("}",option) == 0) {
-    /* pop image_info settings from stack */
-    Stack
-      *node;
 
-    node = (Stack *)cli_wand->image_info_stack;
-    if ( node == (Stack *)NULL)
-      CLIWandExceptionReturn(OptionError,"UnbalancedCurlyBraces",option);
-    cli_wand->image_info_stack = node->next;
+      (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
+      (void) DeleteImageRegistry(key);
+      write_images=_images;
+      if (IfPlusOp)
+        write_images=CloneImageList(_images,_exception);
+      write_info=CloneImageInfo(_image_info);
+      (void) WriteImages(write_info,write_images,arg1,_exception);
+      write_info=DestroyImageInfo(write_info);
+      if (IfPlusOp)
+        write_images=DestroyImageList(write_images);
+      break;
+    }
+    /*
+      Parenthesis and Brace operations
+    */
+    if (LocaleCompare("(",option) == 0) {
+      /* stack 'push' images */
+      Stack
+        *node;
+
+      size_t
+        size;
+
+      size=0;
+      node=cli_wand->image_list_stack;
+      for ( ; node != (Stack *)NULL; node=node->next)
+        size++;
+      if ( size >= MAX_STACK_DEPTH )
+        CLIWandExceptionBreak(OptionError,"ParenthesisNestedTooDeeply",option);
+      node=(Stack *) AcquireMagickMemory(sizeof(*node));
+      if (node == (Stack *) NULL)
+        CLIWandExceptionBreak(ResourceLimitFatalError,
+            "MemoryAllocationFailed",option);
+      node->data = (void *)cli_wand->wand.images;
+      cli_wand->wand.images = NewImageList();
+      node->next = cli_wand->image_list_stack;
+      cli_wand->image_list_stack = node;
+
+      /* handle respect-parenthesis */
+      if (IfMagickTrue(IsStringTrue(GetImageOption(cli_wand->wand.image_info,
+                    "respect-parenthesis"))))
+        option="{"; /* fall-thru so as to push image settings too */
+      else
+        break;
+      /* fall thru to next if */
+    }
+    if (LocaleCompare("{",option) == 0) {
+      /* stack 'push' of image_info settings */
+      Stack
+        *node;
+
+      size_t
+        size;
+
+      size=0;
+      node=cli_wand->image_info_stack;
+      for ( ; node != (Stack *)NULL; node=node->next)
+        size++;
+      if ( size >= MAX_STACK_DEPTH )
+        CLIWandExceptionBreak(OptionError,"CurlyBracesNestedTooDeeply",option);
+      node=(Stack *) AcquireMagickMemory(sizeof(*node));
+      if (node == (Stack *) NULL)
+        CLIWandExceptionBreak(ResourceLimitFatalError,
+            "MemoryAllocationFailed",option);
+
+      node->data = (void *)cli_wand->wand.image_info;
+      cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
+      if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
+        CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
+            option);
+        cli_wand->wand.image_info = (ImageInfo *)node->data;
+        node = (Stack *)RelinquishMagickMemory(node);
+        break;
+      }
 
-    (void) DestroyImageInfo(cli_wand->wand.image_info);
-    cli_wand->wand.image_info = (ImageInfo *)node->data;
-    node = (Stack *)RelinquishMagickMemory(node);
+      node->next = cli_wand->image_info_stack;
+      cli_wand->image_info_stack = node;
 
-    GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
-    cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
-    cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
+      break;
+    }
+    if (LocaleCompare(")",option) == 0) {
+      /* pop images from stack */
+      Stack
+        *node;
+
+      node = (Stack *)cli_wand->image_list_stack;
+      if ( node == (Stack *)NULL)
+        CLIWandExceptionBreak(OptionError,"UnbalancedParenthesis",option);
+      cli_wand->image_list_stack = node->next;
+
+      AppendImageToList((Image **)&node->data,cli_wand->wand.images);
+      cli_wand->wand.images= (Image *)node->data;
+      node = (Stack *)RelinquishMagickMemory(node);
 
-    return;
-  }
-  if (LocaleCompare("clone",option+1) == 0) {
-      Image
-        *new_images;
-
-      if (*option == '+')
-        arg1="-1";
-      if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
-        CLIWandExceptionReturn(OptionError,"InvalidArgument",option);
-      if ( cli_wand->image_list_stack == (Stack *)NULL)
-        CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
-      new_images = (Image *)cli_wand->image_list_stack->data;
-      if (new_images == (Image *) NULL)
-        CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
-      new_images=CloneImages(new_images,arg1,_exception);
-      if (new_images == (Image *) NULL)
-        CLIWandExceptionReturn(OptionError,"NoSuchImage",option);
-      AppendImageToList(&_images,new_images);
-      return;
+      /* handle respect-parenthesis - of the previous 'pushed' settings */
+      node = cli_wand->image_info_stack;
+      if ( node != (Stack *)NULL)
+        {
+          if (IfMagickTrue(IsStringTrue(GetImageOption(
+                cli_wand->wand.image_info,"respect-parenthesis"))))
+            option="}"; /* fall-thru so as to pop image settings too */
+          else
+            break;
+        }
+      else
+        break;
+      /* fall thru to next if */
     }
-  /*
-    Informational Operations
-  */
-  if (LocaleCompare("version",option+1) == 0) {
-    (void) FormatLocaleFile(stdout,"Version: %s\n",
-      GetMagickVersion((size_t *) NULL));
-    (void) FormatLocaleFile(stdout,"Copyright: %s\n",
-      GetMagickCopyright());
-    (void) FormatLocaleFile(stdout,"Features: %s\n\n",
-      GetMagickFeatures());
-    return;
-  }
-  if (LocaleCompare("list",option+1) == 0) {
-    /* FUTURE: This should really be built into the MagickCore
-       It does not actually require a cli-wand or and images!
-     */
-    ssize_t
-      list;
-
-    list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
-    if ( list < 0 ) {
-      CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
-      return;
+    if (LocaleCompare("}",option) == 0) {
+      /* pop image_info settings from stack */
+      Stack
+        *node;
+
+      node = (Stack *)cli_wand->image_info_stack;
+      if ( node == (Stack *)NULL)
+        CLIWandExceptionBreak(OptionError,"UnbalancedCurlyBraces",option);
+      cli_wand->image_info_stack = node->next;
+
+      (void) DestroyImageInfo(cli_wand->wand.image_info);
+      cli_wand->wand.image_info = (ImageInfo *)node->data;
+      node = (Stack *)RelinquishMagickMemory(node);
+
+      GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
+      cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
+      cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
+
+      break;
     }
-    switch (list)
-    {
-      case MagickCoderOptions:
+    if (LocaleCompare("set",option+1) == 0)
       {
-        (void) ListCoderInfo((FILE *) NULL,_exception);
+        /* Note: arguments are not percent escapes expanded yet */
+        /* Some settings are applied to each image in memory in turn.
+           While others only need to be applied once globally.
+        */
+        char
+          *value;
+
+        if (LocaleNCompare(arg1,"registry:",9) == 0)
+          {
+            if (IfPlusOp)
+              {
+                (void) DeleteImageRegistry(arg1+9);
+                break;
+              }
+            value=InterpretImageProperties(_image_info,_images,arg2,_exception);
+            if (value == (char *) NULL)
+              CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
+                    option);
+            (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
+            value=DestroyString(value);
+            break;
+          }
+        if (LocaleNCompare(arg1,"option:",7) == 0)
+          {
+            /* delete equivelent artifact from all images (if any) */
+            MagickResetIterator(&cli_wand->wand);
+            while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
+              (void) DeleteImageArtifact(_images,arg1+7);
+            MagickResetIterator(&cli_wand->wand);
+            /* now set/delete the global option as needed */
+            if (IfPlusOp) {
+              (void) DeleteImageOption(_image_info,arg1+7);
+              break;
+            }
+            value=InterpretImageProperties(_image_info,_images,arg2,_exception);
+            if (value == (char *) NULL)
+              CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
+                option);
+            (void) SetImageOption(_image_info,arg1+7,value);
+            value=DestroyString(value);
+            break;
+          }
+        if ( cli_wand->wand.images == (Image *) NULL )
+          CLIWandExceptArgBreak(OptionError,"NoImagesFound",option,arg1);
+        MagickResetIterator(&cli_wand->wand);
+        while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
+          {
+            Image
+              *next;
+
+            if (IfPlusOp) {
+              if (LocaleNCompare(arg1,"artifact:",9) == 0)
+                (void) DeleteImageArtifact(_images,arg1+9);
+              else if (LocaleNCompare(arg1,"property:",9) == 0)
+                (void) DeleteImageProperty(_images,arg1+9);
+              else
+                (void) DeleteImageProperty(_images,arg1);
+              break;
+            }
+            next=_images;
+            for ( ; next != (Image *) NULL; next=GetNextImageInList(next))
+            {
+              value=InterpretImageProperties(_image_info,next,arg2,_exception);
+              if (value == (char *) NULL)
+                CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
+                  option);
+              if (LocaleNCompare(arg1,"artifact:",9) == 0)
+                (void) SetImageArtifact(next,arg1+9,value);
+              else
+                if (LocaleNCompare(arg1,"property:",9) == 0)
+                  (void) SetImageProperty(next,arg1+9,value,_exception);
+                else
+                  (void) SetImageProperty(next,arg1,value,_exception);
+              value=DestroyString(value);
+            }
+            break;
+          }
+        MagickResetIterator(&cli_wand->wand);
         break;
-      }
-      case MagickColorOptions:
-      {
-        (void) ListColorInfo((FILE *) NULL,_exception);
+     }
+    if (LocaleCompare("clone",option+1) == 0) {
+        Image
+          *new_images;
+
+        if (*option == '+')
+          arg1="-1";
+        if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
+          CLIWandExceptionBreak(OptionError,"InvalidArgument",option);
+        if ( cli_wand->image_list_stack == (Stack *)NULL)
+          CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
+        new_images = (Image *)cli_wand->image_list_stack->data;
+        if (new_images == (Image *) NULL)
+          CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
+        new_images=CloneImages(new_images,arg1,_exception);
+        if (new_images == (Image *) NULL)
+          CLIWandExceptionBreak(OptionError,"NoSuchImage",option);
+        AppendImageToList(&_images,new_images);
         break;
       }
-      case MagickConfigureOptions:
+    /*
+       Informational Operations.
+
+       Note that these do not require either a cli-wand or images!
+       Though currently a cli-wand much be provided regardless.
+    */
+    if (LocaleCompare("version",option+1) == 0)
       {
-        (void) ListConfigureInfo((FILE *) NULL,_exception);
+        ListMagickVersion(stdout);
         break;
       }
-      case MagickDelegateOptions:
-      {
-        (void) ListDelegateInfo((FILE *) NULL,_exception);
+    if (LocaleCompare("list",option+1) == 0) {
+      /*
+         FUTURE: This 'switch' should really be part of MagickCore
+      */
+      ssize_t
+        list;
+
+      list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
+      if ( list < 0 ) {
+        CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
         break;
       }
-      case MagickFontOptions:
+      switch (list)
       {
-        (void) ListTypeInfo((FILE *) NULL,_exception);
-        break;
+        case MagickCoderOptions:
+        {
+          (void) ListCoderInfo((FILE *) NULL,_exception);
+          break;
+        }
+        case MagickColorOptions:
+        {
+          (void) ListColorInfo((FILE *) NULL,_exception);
+          break;
+        }
+        case MagickConfigureOptions:
+        {
+          (void) ListConfigureInfo((FILE *) NULL,_exception);
+          break;
+        }
+        case MagickDelegateOptions:
+        {
+          (void) ListDelegateInfo((FILE *) NULL,_exception);
+          break;
+        }
+        case MagickFontOptions:
+        {
+          (void) ListTypeInfo((FILE *) NULL,_exception);
+          break;
+        }
+        case MagickFormatOptions:
+          (void) ListMagickInfo((FILE *) NULL,_exception);
+          break;
+        case MagickLocaleOptions:
+          (void) ListLocaleInfo((FILE *) NULL,_exception);
+          break;
+        case MagickLogOptions:
+          (void) ListLogInfo((FILE *) NULL,_exception);
+          break;
+        case MagickMagicOptions:
+          (void) ListMagicInfo((FILE *) NULL,_exception);
+          break;
+        case MagickMimeOptions:
+          (void) ListMimeInfo((FILE *) NULL,_exception);
+          break;
+        case MagickModuleOptions:
+          (void) ListModuleInfo((FILE *) NULL,_exception);
+          break;
+        case MagickPolicyOptions:
+          (void) ListPolicyInfo((FILE *) NULL,_exception);
+          break;
+        case MagickResourceOptions:
+          (void) ListMagickResourceInfo((FILE *) NULL,_exception);
+          break;
+        case MagickThresholdOptions:
+          (void) ListThresholdMaps((FILE *) NULL,_exception);
+          break;
+        default:
+          (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
+            _exception);
+          break;
       }
-      case MagickFormatOptions:
-        (void) ListMagickInfo((FILE *) NULL,_exception);
-        break;
-      case MagickLocaleOptions:
-        (void) ListLocaleInfo((FILE *) NULL,_exception);
-        break;
-      case MagickLogOptions:
-        (void) ListLogInfo((FILE *) NULL,_exception);
-        break;
-      case MagickMagicOptions:
-        (void) ListMagicInfo((FILE *) NULL,_exception);
-        break;
-      case MagickMimeOptions:
-        (void) ListMimeInfo((FILE *) NULL,_exception);
-        break;
-      case MagickModuleOptions:
-        (void) ListModuleInfo((FILE *) NULL,_exception);
-        break;
-      case MagickPolicyOptions:
-        (void) ListPolicyInfo((FILE *) NULL,_exception);
-        break;
-      case MagickResourceOptions:
-        (void) ListMagickResourceInfo((FILE *) NULL,_exception);
-        break;
-      case MagickThresholdOptions:
-        (void) ListThresholdMaps((FILE *) NULL,_exception);
-        break;
-      default:
-        (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
-          _exception);
-        break;
+      break;
     }
-    return;
-  }
+
+    CLIWandException(OptionError,"UnrecognizedOption",option);
+
+  } while (0);  /* break to exit code. */
 
 #if 0
-  // Other 'special' options this should handle
-  //    "region"  "reset"  "arg"
-  if ( ( process_flags & ProcessUnknownOptionError ) != 0 )
+  /* clean up percent escape interpreted strings */
+  if (arg1 != arg1n )
+    arg1=DestroyString((char *)arg1);
+  if (arg2 != arg2n )
+    arg2=DestroyString((char *)arg2);
 #endif
-    CLIWandException(OptionError,"UnrecognizedOption",option);
 
 #undef _image_info
 #undef _images
@@ -4663,3 +4803,152 @@ WandExport void CLISpecialOperator(MagickCLI *cli_wand,
 #undef IfNormalOp
 #undef IfPlusOp
 }
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
++   C L I O p t i o n                                                         %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  CLIOption() Processes the given option using the given CLI Magick Wand.
+%  The option arguments can be variable in number, though at this time no more
+%  that two is actually used by any option (this may change). Excess options
+%  are simply ignored.
+%
+%  If the cli_wand->command pointer is non-null, then it is assumed that the
+%  option has already been search for up from the CommandOptions[] table in
+%  "MagickCore/options.c" using  GetCommandOptionInfo().  If not set this
+%  routine will do the lookup instead. The pointer is reset afterward.
+%
+%  This action allows the caller to lookup and pre-handle any 'special'
+%  options, (such as implicit reads) before calling this general option
+%  handler to deal with 'standard' command line options.
+%
+%  The format of the CLIOption method is:
+%
+%       void CLIOption(MagickCLI *cli_wand,const char *option, ...)
+%
+%  A description of each parameter follows:
+%
+%     o cli_wand: the main CLI Wand to use.
+%
+%     o option: The special option (with any switch char) to process
+%
+%     o args: any required arguments for an option (variable number)
+%
+%  Example Usage...
+%
+%    CLIoption(cli_wand,"-read","rose:");
+%    CLIoption(cli_wand,"-virtual-pixel","transparent");
+%    CLIoption(cli_wand,"-distort","SRT:","30");
+%    CLIoption(cli_wand,"-write","rotated_rose.png");
+%
+*/
+WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
+{
+  const char
+    *arg1,
+    *arg2;
+
+  CommandOptionFlags
+    option_type;
+
+  assert(cli_wand != (MagickCLI *) NULL);
+  assert(cli_wand->signature == WandSignature);
+  assert(cli_wand->wand.signature == WandSignature);
+  if (IfMagickTrue(cli_wand->wand.debug))
+    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
+
+  do { /* Break Code Block for error handling */
+
+    /* get information about option */
+    if ( cli_wand->command == (const OptionInfo *) NULL )
+      cli_wand->command = GetCommandOptionInfo(option);
+#if 0
+      (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
+            option, cli_wand->command->mnemonic );
+#endif
+    option_type=(CommandOptionFlags) cli_wand->command->flags;
+
+    if ( option_type == UndefinedOptionFlag )
+      CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
+
+    assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
+
+    /* depreciated options */
+    if ( (option_type & DeprecateOptionFlag) != 0 )
+      CLIWandExceptionBreak(OptionError,"DeprecatedOptionNoCode",option);
+
+    /* options that this module does not handle */
+    if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
+      CLIWandExceptionBreak(OptionFatalError,"InvalidUseOfOption",option);
+
+    /* Get argument strings from VarArgs
+      How can you determine arguments is enough was supplied? */
+    { size_t
+        count = cli_wand->command->type;
+
+      va_list
+        operands;
+
+      va_start(operands,option);
+
+      arg1=arg2=NULL;
+      if ( count >= 1 )
+        arg1=(const char *) va_arg(operands, const char *);
+      if ( count >= 2 )
+        arg2=(const char *) va_arg(operands, const char *);
+
+      va_end(operands);
+
+#if 0
+      (void) FormatLocaleFile(stderr,
+        "CLIOption: \"%s\"  Count: %ld  Flags: %04x  Args: \"%s\" \"%s\"\n",
+            option,(long) count,option_type,arg1,arg2);
+#endif
+    }
+
+    /*
+      Call the appropriate option handler
+    */
+
+    /* FUTURE: this is temporary - get 'settings' to handle distribution of
+      settings to images attributes,proprieties,artifacts */
+    if ( cli_wand->wand.images != (Image *)NULL )
+      SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
+          cli_wand->wand.exception);
+
+    if ( (option_type & SettingOptionFlags) != 0 ) {
+      CLISettingOptionInfo(cli_wand, option, arg1, arg2);
+      // FUTURE: Sync Specific Settings into Image Properities (not global)
+    }
+
+    /* Operators that do not need images - read, write, stack, clone */
+    if ( (option_type & NoImageOperatorFlag) != 0)
+      CLINoImageOperator(cli_wand, option, arg1, arg2);
+
+    /* FUTURE: The not a setting part below is a temporary hack due to
+    * some options being both a Setting and a Simple operator.
+    * Specifically -monitor, -depth, and  -colorspace */
+    if ( cli_wand->wand.images == (Image *)NULL )
+      if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
+          ((option_type & SettingOptionFlags) == 0 ))  /* temp hack */
+        CLIWandExceptionBreak(OptionError,"NoImagesFound",option);
+
+    /* Operators work on single images, and needs a loop over the images */
+    if ( (option_type & SimpleOperatorFlag) != 0)
+      CLISimpleOperatorImages(cli_wand, option, arg1, arg2);
+
+    /* Operators that work on the image list as a whole */
+    if ( (option_type & ListOperatorFlag) != 0 )
+      CLIListOperatorImages(cli_wand, option, arg1, arg2);
+
+  } while (0);  /* end Break code block */
+
+  cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */
+}