]> granicus.if.org Git - imagemagick/blobdiff - MagickWand/operation.c
(no commit message)
[imagemagick] / MagickWand / operation.c
index 6717a67bb0557e2b3c2b6db0e60f75cd9bd84956..65982cb716501a09dc8cc79273e730762e2cdfb7 100644 (file)
@@ -3,21 +3,21 @@
 %                                                                             %
 %                                                                             %
 %                                                                             %
-%             OOO  PPPP  EEEE RRRR   AA  TTTTTT III  OOO  N   N               %
-%            O   O P   P E    R   R A  A   TT    I  O   O NN  N               %
-%            O   O PPPP  EEE  RRRR  AAAA   TT    I  O   O N N N               %
-%            O   O P     E    R R   A  A   TT    I  O   O N  NN               %
-%             OOO  P     EEEE R  RR A  A   TT   III  OOO  N   N               %
+%          OOO   PPPP   EEEE  RRRR    AA   TTTTT  III   OOO   N   N           %
+%         O   O  P   P  E     R   R  A  A    T     I   O   O  NN  N           %
+%         O   O  PPPP   EEE   RRRR   AAAA    T     I   O   O  N N N           %
+%         O   O  P      E     R R    A  A    T     I   O   O  N  NN           %
+%          OOO   P      EEEE  R  RR  A  A    T    III   OOO   N   N           %
 %                                                                             %
 %                                                                             %
-%                         MagickWand Module Methods                           %
+%                         CLI Magick Option Methods                           %
 %                                                                             %
-%                              Software Design                                %
-%                                John Cristy                                  %
+%                              Dragon Computing                               %
+%                              Anthony Thyssen                                %
 %                               September 2011                                %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2012 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  %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 % Apply the given options (settings, and simple, or sequence operations) to
-% the given image(s) according to the current "image_info" and "draw_info"
-% settings.
+% the given image(s) according to the current "image_info", "draw_info", and
+% "quantize_info" settings, stored in a special CLI Image Wand.
 %
 % The final goal is to allow the execution in a strict one option at a time
 % manner that is needed for 'pipelining and file scripting' of options in
 % IMv7.
 %
-% Anthony Thyssen, Sept 2011
+% Anthony Thyssen, September 2011
 */
-#if 0
 \f
 /*
   Include declarations.
 */
 #include "MagickWand/studio.h"
 #include "MagickWand/MagickWand.h"
-#include "MagickWand/mogrify-private.h"
+#include "MagickWand/magick-wand-private.h"
+#include "MagickWand/wand.h"
+#include "MagickWand/wandcli.h"
+#include "MagickWand/wandcli-private.h"
+#include "MagickWand/operation.h"
 #include "MagickCore/monitor-private.h"
 #include "MagickCore/thread-private.h"
 #include "MagickCore/string-private.h"
 /*
   Define declarations.
 */
-#define UndefinedCompressionQuality  0UL
+#define USE_WAND_METHODS  0
+#define MAX_STACK_DEPTH  32
+#define UNDEFINED_COMPRESSION_QUALITY  0UL
+
 /*
   Constant declaration. (temporary exports)
 */
 static const char
   BackgroundColor[] = "#fff",  /* white */
-  BorderColor[] = "#dfdfdf",  /* gray */
-  MatteColor[] = "#bdbdbd";  /* gray */
+  BorderColor[] = "#dfdfdf",  /* sRGB gray */
+  MatteColor[] = "#bdbdbd";  /* slightly darker gray */
 \f
 /*
 ** Function to report on the progress of image operations
 */
 static MagickBooleanType MonitorProgress(const char *text,
   const MagickOffsetType offset,const MagickSizeType extent,
-  void *wand_unused(client_data))
+  void *wand_unused(cli_wandent_data))
 {
   char
     message[MaxTextExtent],
@@ -142,6 +148,29 @@ 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().
@@ -149,10 +178,12 @@ static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
   specifications (or direct floating point numbers).  The number of floats
   needed to represent a color varies depending on teh current channel
   setting.
+
+  This really should be in MagickCore, so that other API's can make use of it.
 */
 static Image *SparseColorOption(const Image *image,
   const SparseColorMethod method,const char *arguments,
-  const MagickBooleanType color_from_image,ExceptionInfo *exception)
+  ExceptionInfo *exception)
 {
   char
     token[MaxTextExtent];
@@ -181,7 +212,7 @@ static Image *SparseColorOption(const Image *image,
 
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
+  if (IfMagickTrue(image->debug))
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
@@ -199,7 +230,7 @@ static Image *SparseColorOption(const Image *image,
       (image->colorspace == CMYKColorspace))
     number_colors++;
   if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
-      (image->matte != MagickFalse))
+      IfMagickTrue(image->matte))
     number_colors++;
 
   /*
@@ -211,33 +242,17 @@ static Image *SparseColorOption(const Image *image,
   {
     GetMagickToken(p,&p,token);
     if ( token[0] == ',' ) continue;
-    if ( isalpha((int) token[0]) || token[0] == '#' ) {
-      if ( color_from_image ) {
-        (void) ThrowMagickException(exception,GetMagickModule(),
-            OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
-            "Color arg given, when colors are coming from image");
-        return( (Image *)NULL);
-      }
-      x += number_colors;  /* color argument */
-    }
-    else {
+    if ( isalpha((int) token[0]) || token[0] == '#' )
+      x += number_colors;  /* color argument found */
+    else
       x++;   /* floating point argument */
-    }
-  }
-  error=MagickTrue;
-  if ( color_from_image ) {
-    /* just the control points are being given */
-    error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse;
-    number_arguments=(x/2)*(2+number_colors);
   }
-  else {
-    /* control points and color values */
-    error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
-    number_arguments=x;
-  }
-  if ( error ) {
+  /* control points and color values */
+  error = IsMagickTrue( x % (2+number_colors) );
+  number_arguments=x;
+  if ( IfMagickTrue(error) ) {
     (void) ThrowMagickException(exception,GetMagickModule(),
-               OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
+               OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
                "Invalid number of Arguments");
     return( (Image *)NULL);
   }
@@ -260,110 +275,100 @@ static Image *SparseColorOption(const Image *image,
     if ( token[0] == '\0' ) break;
     if ( isalpha((int) token[0]) || token[0] == '#' ) {
       (void) ThrowMagickException(exception,GetMagickModule(),
-            OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
+            OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
             "Color found, instead of X-coord");
       error = MagickTrue;
       break;
     }
-    sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
+    sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
     /* Y coordinate */
     token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
     if ( token[0] == '\0' ) break;
     if ( isalpha((int) token[0]) || token[0] == '#' ) {
       (void) ThrowMagickException(exception,GetMagickModule(),
-            OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
+            OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
             "Color found, instead of Y-coord");
       error = MagickTrue;
       break;
     }
-    sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
-    /* color values for this control point */
-#if 0
-    if ( (color_from_image ) {
-      /* get color from image */
-      /* HOW??? */
+    sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
+    /* color name or function given in string argument */
+    token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
+    if ( token[0] == '\0' ) break;
+    if ( isalpha((int) token[0]) || token[0] == '#' ) {
+      /* Color string given */
+      (void) QueryColorCompliance(token,AllCompliance,&color,
+                exception);
+      if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
+        sparse_arguments[x++] = QuantumScale*color.red;
+      if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
+        sparse_arguments[x++] = QuantumScale*color.green;
+      if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
+        sparse_arguments[x++] = QuantumScale*color.blue;
+      if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
+          (image->colorspace == CMYKColorspace))
+        sparse_arguments[x++] = QuantumScale*color.black;
+      if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
+          IfMagickTrue(image->matte))
+        sparse_arguments[x++] = QuantumScale*color.alpha;
     }
-    else
-#endif
-    {
-      /* color name or function given in string argument */
-      token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
-      if ( token[0] == '\0' ) break;
-      if ( isalpha((int) token[0]) || token[0] == '#' ) {
-        /* Color string given */
-        (void) QueryMagickColorCompliance(token,AllComplience,&color,
-                  exception);
-        if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
-          sparse_arguments[x++] = QuantumScale*color.red;
-        if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
-          sparse_arguments[x++] = QuantumScale*color.green;
-        if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
-          sparse_arguments[x++] = QuantumScale*color.blue;
-        if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
-            (image->colorspace == CMYKColorspace))
-          sparse_arguments[x++] = QuantumScale*color.black;
-        if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
-            (image->matte != MagickFalse))
-          sparse_arguments[x++] = QuantumScale*color.alpha;
+    else {
+      /* Colors given as a set of floating point values - experimental */
+      /* NB: token contains the first floating point value to use! */
+      if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
+        {
+        while ( token[0] == ',' ) GetMagickToken(p,&p,token);
+        if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
+          break;
+        sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
+        token[0] = ','; /* used this token - get another */
       }
-      else {
-        /* Colors given as a set of floating point values - experimental */
-        /* NB: token contains the first floating point value to use! */
-        if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
-          {
-          while ( token[0] == ',' ) GetMagickToken(p,&p,token);
-          if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
-            break;
-          sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
-          token[0] = ','; /* used this token - get another */
-        }
-        if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
-          {
-          while ( token[0] == ',' ) GetMagickToken(p,&p,token);
-          if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
-            break;
-          sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
-          token[0] = ','; /* used this token - get another */
-        }
-        if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
-          {
-          while ( token[0] == ',' ) GetMagickToken(p,&p,token);
-          if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
-            break;
-          sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
-          token[0] = ','; /* used this token - get another */
-        }
-        if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
-            (image->colorspace == CMYKColorspace))
-          {
-          while ( token[0] == ',' ) GetMagickToken(p,&p,token);
-          if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
-            break;
-          sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
-          token[0] = ','; /* used this token - get another */
-        }
-        if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
-            (image->matte != MagickFalse))
-          {
-          while ( token[0] == ',' ) GetMagickToken(p,&p,token);
-          if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
-            break;
-          sparse_arguments[x++]=InterpretLocaleValue(token,(char **) NULL);
-          token[0] = ','; /* used this token - get another */
-        }
+      if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
+        {
+        while ( token[0] == ',' ) GetMagickToken(p,&p,token);
+        if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
+          break;
+        sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
+        token[0] = ','; /* used this token - get another */
+      }
+      if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
+        {
+        while ( token[0] == ',' ) GetMagickToken(p,&p,token);
+        if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
+          break;
+        sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
+        token[0] = ','; /* used this token - get another */
+      }
+      if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
+          (image->colorspace == CMYKColorspace))
+        {
+        while ( token[0] == ',' ) GetMagickToken(p,&p,token);
+        if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
+          break;
+        sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
+        token[0] = ','; /* used this token - get another */
+      }
+      if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
+          IfMagickTrue(image->matte))
+        {
+        while ( token[0] == ',' ) GetMagickToken(p,&p,token);
+        if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
+          break;
+        sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
+        token[0] = ','; /* used this token - get another */
       }
     }
   }
   if ( number_arguments != x && !error ) {
     (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
-      "InvalidArgument","`%s': %s","sparse-color","Argument Parsing Error");
+      "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
     sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
     return( (Image *)NULL);
   }
   if ( error )
     return( (Image *)NULL);
 
-  /* Call the Interpolation function with the parsed arguments */
+  /* Call the Sparse Color Interpolation function with the parsed arguments */
   sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
     exception);
   sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
@@ -375,750 +380,724 @@ static Image *SparseColorOption(const Image *image,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+     S e t t i n g s 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                                   %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  SettingsOptionInfo() saves the given single settings argv[0] into a
-%  ImageInfo structure for later use by various image processing operations.
+%  CLISettingOptionInfo() applies a single settings option into a CLI wand
+%  holding the image_info, draw_info, quantize_info structures that will be
+%  used when processing the images.
 %
-%  The format of the SettingsOptionInfo method is:
+%  These options do no require images to be present in the CLI wand for them
+%  to be able to be set, in which case they will generally be applied to image
+%  that are read in later
 %
-%    MagickBooleanType SettingsOptionInfo(ImageInfo *image_info,
-%        const int argc, const char **argv,ExceptionInfo *exception)
+%  Options handled by this function are listed in CommandOptions[] of
+%  "option.c" that is one of "SettingOptionFlags" option flags.
+%
+%  The format of the CLISettingOptionInfo method is:
+%
+%    void CLISettingOptionInfo(MagickCLI *cli_wand,
+%               const char *option, const char *arg1, const char *arg2)
 %
 %  A description of each parameter follows:
 %
-%    o image_info: the image info..
+%    o cli_wand: structure holding settings to be applied
+%
+%    o option: The option string to be set
+%
+%    o arg1, arg2: optional argument strings to the operation
+%        arg2 is currently only used by "-limit"
 %
-%    o argc: Specifies a pointer to an integer describing the number of
-%      elements in the argument vector.
+% Example usage...
 %
-%    o argv: Specifies a pointer to a text array containing the command line
-%      arguments.
+%    CLISettingOptionInfo(cli_wand, "-background", "Red", NULL); // set value
+%    CLISettingOptionInfo(cli_wand, "-adjoin", NULL, NULL);      // set boolean
+%    CLISettingOptionInfo(cli_wand, "+adjoin", NULL, NULL);      // unset
 %
-%    o exception: return any errors or warnings in this structure.
+% 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 MagickBooleanType SettingsOptionInfo(ImageInfo *image_info,
-  const int argc,const char **argv,ExceptionInfo *exception)
+WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
+     const char *option,const char *arg1, const char *arg2)
 {
-  GeometryInfo
-    geometry_info;
-
-  /*
-    Initialize method variables.
-  */
-  assert(image_info != (ImageInfo *) NULL);
-  assert(image_info->signature == MagickSignature);
-  if (image_info->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
-      image_info->filename);
-  if (argc < 0)
-    return(MagickTrue);
-  /*
-    Set the image settings for one image.
-  */
-  switch (*(argv[0]+1))
+  ssize_t
+    parse;     /* option argument parsing (string to value table lookup) */
+
+  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);
+
+#define _image_info       (cli_wand->wand.image_info)
+#define _exception        (cli_wand->wand.exception)
+#define _draw_info        (cli_wand->draw_info)
+#define _quantize_info    (cli_wand->quantize_info)
+#define IfSetOption       (*option=='-')
+#define ArgBoolean        IsMagickTrue(IfSetOption)
+#define ArgBooleanNot     IsMagickFalse(IfSetOption)
+#define ArgBooleanString  (IfSetOption?"true":"false")
+#define ArgOption(def)    (IfSetOption?arg1:(const char *)(def))
+
+  switch (*(option+1))
   {
     case 'a':
     {
-      if (LocaleCompare("adjoin",argv[0]+1) == 0)
+      if (LocaleCompare("adjoin",option+1) == 0)
         {
-          image_info->adjoin=(*argv[0] == '-') ? MagickTrue : MagickFalse;
+          _image_info->adjoin = ArgBoolean;
           break;
         }
-      if (LocaleCompare("antialias",argv[0]+1) == 0)
+      if (LocaleCompare("affine",option+1) == 0)
         {
-          image_info->antialias=(*argv[0] == '-') ? MagickTrue : MagickFalse;
+          /* DEPRECIATED: _draw_info setting only: for -draw and -transform */
+          if (IfSetOption)
+            (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
+          else
+            GetAffineMatrix(&_draw_info->affine);
           break;
         }
-      if (LocaleCompare("attenuate",argv[0]+1) == 0)
+      if (LocaleCompare("antialias",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) DeleteImageOption(image_info,argv[0]+1);
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          _image_info->antialias =
+            _draw_info->stroke_antialias =
+              _draw_info->text_antialias = ArgBoolean;
           break;
         }
-      if (LocaleCompare("authenticate",argv[0]+1) == 0)
+      if (LocaleCompare("attenuate",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            (void) CloneString(&image_info->authenticate,(char *) NULL);
-          else
-            (void) CloneString(&image_info->authenticate,argv[1]);
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
           break;
         }
-      break;
+      if (LocaleCompare("authenticate",option+1) == 0)
+        {
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          break;
+        }
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'b':
     {
-      if (LocaleCompare("background",argv[0]+1) == 0)
+      if (LocaleCompare("background",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) DeleteImageOption(image_info,argv[0]+1);
-              (void) QueryColorCompliance(BackgroundColor,AllComplience,
-                &image_info->background_color,exception);
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
-          (void) QueryColorCompliance(argv[1],AllComplience,
-           &image_info->background_color,exception);
+          /* FUTURE: both _image_info attribute & ImageOption in use!
+             _image_info only used directly for generating new images.
+             SyncImageSettings() used to set per-image attribute.
+
+             FUTURE: if _image_info->background_color is not set then
+             we should fall back to per-image background_color
+
+             At this time -background will 'wipe out' the per-image
+             background color!
+
+             Better error handling of QueryColorCompliance() needed.
+          */
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          (void) QueryColorCompliance(ArgOption(BackgroundColor),AllCompliance,
+             &_image_info->background_color,_exception);
           break;
         }
-      if (LocaleCompare("bias",argv[0]+1) == 0)
+      if (LocaleCompare("bias",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"0.0");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
+             as it is actually rarely used except in direct convolve operations
+             Usage outside a direct convolve operation is actally non-sensible!
+
+             SyncImageSettings() used to set per-image attribute.
+          */
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("black-point-compensation",argv[0]+1) == 0)
+      if (LocaleCompare("black-point-compensation",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"false");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,"true");
+          /* Used as a image chromaticity setting
+             SyncImageSettings() used to set per-image attribute.
+          */
+          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
           break;
         }
-      if (LocaleCompare("blue-primary",argv[0]+1) == 0)
+      if (LocaleCompare("blue-primary",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"0.0");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* Image chromaticity X,Y  NB: Y=X if Y not defined
+             Used by many coders including PNG
+             SyncImageSettings() used to set per-image attribute.
+          */
+          arg1=ArgOption("0.0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("bordercolor",argv[0]+1) == 0)
+      if (LocaleCompare("bordercolor",option+1) == 0)
         {
-          if (*argv[0] == '+')
+          /* FUTURE: both _image_info attribute & ImageOption in use!
+             SyncImageSettings() used to set per-image attribute.
+             Better error checking of QueryColorCompliance().
+          */
+          if (IfSetOption)
             {
-              (void) DeleteImageOption(image_info,argv[0]+1);
-              (void) QueryColorCompliance(BorderColor,AllComplience,
-                &image_info->border_color,exception);
+              (void) SetImageOption(_image_info,option+1,arg1);
+              (void) QueryColorCompliance(arg1,AllCompliance,
+                  &_image_info->border_color,_exception);
+              (void) QueryColorCompliance(arg1,AllCompliance,
+                  &_draw_info->border_color,_exception);
               break;
             }
-          (void) QueryColorCompliance(argv[1],AllCompliece,&image_info->border_color,
-            exception);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          (void) DeleteImageOption(_image_info,option+1);
+          (void) QueryColorCompliance(BorderColor,AllCompliance,
+            &_image_info->border_color,_exception);
+          (void) QueryColorCompliance(BorderColor,AllCompliance,
+            &_draw_info->border_color,_exception);
           break;
         }
-      if (LocaleCompare("box",argv[0]+1) == 0)
+      if (LocaleCompare("box",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,"undercolor","none");
-              break;
-            }
-          (void) SetImageOption(image_info,"undercolor",argv[1]);
+          /* DEPRECIATED - now "undercolor" */
+          CLISettingOptionInfo(cli_wand,"undercolor",arg1, arg2);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'c':
     {
-      if (LocaleCompare("cache",argv[0]+1) == 0)
+      if (LocaleCompare("cache",option+1) == 0)
         {
           MagickSizeType
             limit;
 
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           limit=MagickResourceInfinity;
-          if (LocaleCompare("unlimited",argv[1]) != 0)
-            limit=(MagickSizeType) SiPrefixToDouble(argv[1],100.0);
+          if (LocaleCompare("unlimited",arg1) != 0)
+            limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
           (void) SetMagickResourceLimit(MemoryResource,limit);
           (void) SetMagickResourceLimit(MapResource,2*limit);
           break;
         }
-      if (LocaleCompare("caption",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            {
-              (void) DeleteImageOption(image_info,argv[0]+1);
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
-          break;
-        }
-      if (LocaleCompare("channel",argv[0]+1) == 0)
+      if (LocaleCompare("caption",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->channel=DefaultChannels;
-              break;
-            }
-          image_info->channel=(ChannelType) ParseChannelOption(argv[1]);
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("colors",argv[0]+1) == 0)
+      if (LocaleCompare("channel",option+1) == 0)
         {
-          image_info->colors=StringToUnsignedLong(argv[1]);
+          arg1=ArgOption("default");
+          parse=ParseChannelOption(arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",
+                 option,arg1);
+          _image_info->channel=(ChannelType) parse;
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("colorspace",argv[0]+1) == 0)
+      if (LocaleCompare("colorspace",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->colorspace=UndefinedColorspace;
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          image_info->colorspace=(ColorspaceType) ParseCommandOption(
-            MagickColorspaceOptions,MagickFalse,argv[1]);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* Setting used for new images via AquireImage()
+             But also used as a SimpleImageOperator
+             Undefined colorspace means don't modify images on
+             read or as a operation */
+          parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,
+                        ArgOption("undefined"));
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
+                                    option,arg1);
+          _image_info->colorspace=(ColorspaceType) parse;
           break;
         }
-      if (LocaleCompare("comment",argv[0]+1) == 0)
+      if (LocaleCompare("comment",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) DeleteImageOption(image_info,argv[0]+1);
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("compose",argv[0]+1) == 0)
+      if (LocaleCompare("compose",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* FUTURE: _image_info should be used,
+             SyncImageSettings() used to set per-image attribute. - REMOVE
+
+             This setting should NOT be used to set image 'compose'
+             "-layer" operators shoud use _image_info if defined otherwise
+             they should use a per-image compose setting.
+          */
+          parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
+                          ArgOption("undefined"));
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
+                                      option,arg1);
+          _image_info->compose=(CompositeOperator) parse;
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("compress",argv[0]+1) == 0)
+      if (LocaleCompare("compress",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->compression=UndefinedCompression;
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          image_info->compression=(CompressionType) ParseCommandOption(
-            MagickCompressOptions,MagickFalse,argv[1]);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* FUTURE: What should be used?  _image_info  or ImageOption ???
+             The former is more efficent, but Crisy prefers the latter!
+             SyncImageSettings() used to set per-image attribute.
+
+             The coders appears to use _image_info, not Image_Option
+             however the image attribute (for save) is set from the
+             ImageOption!
+
+             Note that "undefined" is a different setting to "none".
+          */
+          parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
+                     ArgOption("undefined"));
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
+                                      option,arg1);
+          _image_info->compression=(CompressionType) parse;
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'd':
     {
-      if (LocaleCompare("debug",argv[0]+1) == 0)
+      if (LocaleCompare("debug",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            (void) SetLogEventMask("none");
-          else
-            (void) SetLogEventMask(argv[1]);
-          image_info->debug=IsEventLogging();
+          /* SyncImageSettings() used to set per-image attribute. */
+          arg1=ArgOption("none");
+          parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
+                                      option,arg1);
+          (void) SetLogEventMask(arg1);
+          _image_info->debug=IsEventLogging();   /* extract logging*/
+          cli_wand->wand.debug=IsEventLogging();
           break;
         }
-      if (LocaleCompare("define",argv[0]+1) == 0)
+      if (LocaleCompare("define",option+1) == 0)
         {
-          if (*argv[0] == '+')
+          if (LocaleNCompare(arg1,"registry:",9) == 0)
             {
-              if (LocaleNCompare(argv[1],"registry:",9) == 0)
-                (void) DeleteImageRegistry(argv[1]+9);
+              if (IfSetOption)
+                (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
               else
-                (void) DeleteImageOption(image_info,argv[1]);
-              break;
-            }
-          if (LocaleNCompare(argv[1],"registry:",9) == 0)
-            {
-              (void) DefineImageRegistry(StringRegistryType,argv[1]+9,
-                exception);
+                (void) DeleteImageRegistry(arg1+9);
               break;
             }
-          (void) DefineImageOption(image_info,argv[1]);
+          /* DefineImageOption() equals SetImageOption() but with '=' */
+          if (IfSetOption)
+            (void) DefineImageOption(_image_info,arg1);
+          else if (IsMagickFalse(DeleteImageOption(_image_info,arg1)))
+            CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
           break;
         }
-      if (LocaleCompare("delay",argv[0]+1) == 0)
+      if (LocaleCompare("delay",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"0");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* Only used for new images via AcquireImage()
+             FUTURE: Option should also be used for "-morph" (color morphing)
+          */
+          arg1=ArgOption("0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("density",argv[0]+1) == 0)
+      if (LocaleCompare("density",option+1) == 0)
         {
-          /*
-            Set image density.
+          /* FUTURE: strings used in _image_info attr and _draw_info!
+             Basically as density can be in a XxY form!
+
+             SyncImageSettings() used to set per-image attribute.
           */
-          if (*argv[0] == '+')
-            {
-              if (image_info->density != (char *) NULL)
-                image_info->density=DestroyString(image_info->density);
-              (void) SetImageOption(image_info,argv[0]+1,"72");
-              break;
-            }
-          (void) CloneString(&image_info->density,argv[1]);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          (void) CloneString(&_image_info->density,ArgOption(NULL));
+          (void) CloneString(&_draw_info->density,_image_info->density);
           break;
         }
-      if (LocaleCompare("depth",argv[0]+1) == 0)
+      if (LocaleCompare("depth",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->depth=MAGICKCORE_QUANTUM_DEPTH;
-              break;
-            }
-          image_info->depth=StringToUnsignedLong(argv[1]);
+          /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
+             SyncImageSettings() used to set per-image attribute.
+          */
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
+                                       :MAGICKCORE_QUANTUM_DEPTH;
           break;
         }
-      if (LocaleCompare("direction",argv[0]+1) == 0)
+      if (LocaleCompare("direction",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* Image Option is only used to set _draw_info */
+          arg1=ArgOption("undefined");
+          parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
+                                      option,arg1);
+          _draw_info->direction=(DirectionType) parse;
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("display",argv[0]+1) == 0)
+      if (LocaleCompare("display",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              if (image_info->server_name != (char *) NULL)
-                image_info->server_name=DestroyString(
-                  image_info->server_name);
-              break;
-            }
-          (void) CloneString(&image_info->server_name,argv[1]);
+          (void) CloneString(&_image_info->server_name,ArgOption(NULL));
+          (void) CloneString(&_draw_info->server_name,_image_info->server_name);
           break;
         }
-      if (LocaleCompare("dispose",argv[0]+1) == 0)
+      if (LocaleCompare("dispose",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* only used in setting new images */
+          arg1=ArgOption("undefined");
+          parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
+                                      option,arg1);
+          (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
           break;
         }
-      if (LocaleCompare("dither",argv[0]+1) == 0)
+      if (LocaleCompare("dither",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->dither=MagickFalse;
-              (void) SetImageOption(image_info,argv[0]+1,"none");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
-          image_info->dither=MagickTrue;
+          /* _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;
+          (void) SetImageOption(_image_info,option+1,ArgOption("none"));
+          _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
+                    MagickDitherOptions,MagickFalse,ArgOption("none"));
+          if (_quantize_info->dither_method == NoDitherMethod)
+            _image_info->dither = _quantize_info->dither = MagickFalse;
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'e':
     {
-      if (LocaleCompare("encoding",argv[0]+1) == 0)
+      if (LocaleCompare("encoding",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
+          (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
           break;
         }
-      if (LocaleCompare("endian",argv[0]+1) == 0)
+      if (LocaleCompare("endian",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->endian=UndefinedEndian;
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          image_info->endian=(EndianType) ParseCommandOption(
-            MagickEndianOptions,MagickFalse,argv[1]);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* Both _image_info attr and ImageInfo */
+          arg1 = ArgOption("undefined");
+          parse = ParseCommandOption(MagickEndianOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedEndianType",
+                                      option,arg1);
+          /* FUTURE: check alloc/free of endian string!  - remove? */
+          _image_info->endian=(EndianType) (*arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("extract",argv[0]+1) == 0)
+      if (LocaleCompare("extract",option+1) == 0)
         {
-          /*
-            Set image extract geometry.
-          */
-          if (*argv[0] == '+')
-            {
-              if (image_info->extract != (char *) NULL)
-                image_info->extract=DestroyString(image_info->extract);
-              break;
-            }
-          (void) CloneString(&image_info->extract,argv[1]);
+          (void) CloneString(&_image_info->extract,ArgOption(NULL));
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'f':
     {
-      if (LocaleCompare("fill",argv[0]+1) == 0)
+      if (LocaleCompare("family",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"none");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          (void) CloneString(&_draw_info->family,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("filter",argv[0]+1) == 0)
+      if (LocaleCompare("fill",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* Set "fill" OR "fill-pattern" in _draw_info
+             The original fill color is preserved if a fill-pattern is given.
+             That way it does not effect other operations that directly using
+             the fill color and, can be retored using "+tile".
+          */
+          MagickBooleanType
+            status;
+
+          ExceptionInfo
+            *sans;
+
+          PixelInfo
+            color;
+
+          arg1 = ArgOption("none");  /* +fill turns it off! */
+          (void) SetImageOption(_image_info,option+1,arg1);
+          if (_draw_info->fill_pattern != (Image *) NULL)
+            _draw_info->fill_pattern=DestroyImage(_draw_info->fill_pattern);
+
+          /* is it a color or a image? -- ignore exceptions */
+          sans=AcquireExceptionInfo();
+          status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
+          sans=DestroyExceptionInfo(sans);
+
+          if (IfMagickFalse(status))
+            _draw_info->fill_pattern=GetImageCache(_image_info,arg1,_exception);
+          else
+            _draw_info->fill=color;
           break;
         }
-      if (LocaleCompare("font",argv[0]+1) == 0)
+      if (LocaleCompare("filter",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              if (image_info->font != (char *) NULL)
-                image_info->font=DestroyString(image_info->font);
-              break;
-            }
-          (void) CloneString(&image_info->font,argv[1]);
+          /* SyncImageSettings() used to set per-image attribute. */
+          arg1 = ArgOption("undefined");
+          parse = ParseCommandOption(MagickFilterOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedImageFilter",
+                                      option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
+          break;
+        }
+      if (LocaleCompare("font",option+1) == 0)
+        {
+          (void) CloneString(&_draw_info->font,ArgOption(NULL));
+          (void) CloneString(&_image_info->font,_draw_info->font);
           break;
         }
-      if (LocaleCompare("format",argv[0]+1) == 0)
+      if (LocaleCompare("format",option+1) == 0)
         {
+          /* FUTURE: why the ping test, you could set ping after this! */
+          /*
           register const char
             *q;
 
-          for (q=strchr(argv[1],'%'); q != (char *) NULL; q=strchr(q+1,'%'))
+          for (q=strchr(arg1,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
             if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
-              image_info->ping=MagickFalse;
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+              _image_info->ping=MagickFalse;
+          */
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("fuzz",argv[0]+1) == 0)
+      if (LocaleCompare("fuzz",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->fuzz=0.0;
-              (void) SetImageOption(image_info,argv[0]+1,"0");
-              break;
-            }
-          image_info->fuzz=SiPrefixToDouble(argv[1],(double) QuantumRange+
-            1.0);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* Option used to set image fuzz! unless blank canvas (from color)
+             Image attribute used for color compare operations
+             SyncImageSettings() used to set per-image attribute.
+
+             FUTURE: Can't find anything else using _image_info->fuzz directly!
+                     remove direct sttribute from image_info
+          */
+          arg1=ArgOption("0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          _image_info->fuzz=StringToDoubleInterval(arg1,(double)
+                QuantumRange+1.0);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'g':
     {
-      if (LocaleCompare("gravity",argv[0]+1) == 0)
+      if (LocaleCompare("gravity",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* SyncImageSettings() used to set per-image attribute. */
+          arg1 = ArgOption("none");
+          parse = ParseCommandOption(MagickGravityOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedGravityType",
+                                      option,arg1);
+          _draw_info->gravity=(GravityType) parse;
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("green-primary",argv[0]+1) == 0)
+      if (LocaleCompare("green-primary",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"0.0");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* Image chromaticity X,Y  NB: Y=X if Y not defined
+             SyncImageSettings() used to set per-image attribute.
+             Used directly by many coders
+          */
+          arg1=ArgOption("0.0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'i':
     {
-      if (LocaleCompare("intent",argv[0]+1) == 0)
+      if (LocaleCompare("intent",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* 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");
+          parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
+                                      option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("interlace",argv[0]+1) == 0)
+      if (LocaleCompare("interlace",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->interlace=UndefinedInterlace;
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          image_info->interlace=(InterlaceType) ParseCommandOption(
-            MagickInterlaceOptions,MagickFalse,argv[1]);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* _image_info is directly used by coders (so why an image setting?)
+             SyncImageSettings() used to set per-image attribute.
+          */
+          arg1 = ArgOption("undefined");
+          parse = ParseCommandOption(MagickInterlaceOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedInterlaceType",
+                                      option,arg1);
+          _image_info->interlace=(InterlaceType) parse;
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("interline-spacing",argv[0]+1) == 0)
+      if (LocaleCompare("interline-spacing",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
+          _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
+               (char **) NULL);
           break;
         }
-      if (LocaleCompare("interpolate",argv[0]+1) == 0)
+      if (LocaleCompare("interpolate",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* SyncImageSettings() used to set per-image attribute. */
+          arg1 = ArgOption("undefined");
+          parse = ParseCommandOption(MagickInterpolateOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedInterpolateMethod",
+                                      option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("interword-spacing",argv[0]+1) == 0)
+      if (LocaleCompare("interword-spacing",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
+          _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'k':
     {
-      if (LocaleCompare("kerning",argv[0]+1) == 0)
+      if (LocaleCompare("kerning",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'l':
     {
-      if (LocaleCompare("label",argv[0]+1) == 0)
+      if (LocaleCompare("label",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) DeleteImageOption(image_info,argv[0]+1);
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* only used for new images - not in SyncImageOptions() */
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("limit",argv[0]+1) == 0)
+      if (LocaleCompare("limit",option+1) == 0)
         {
           MagickSizeType
             limit;
 
-          ResourceType
-            type;
-
-          if (*argv[0] == '+')
-            break;
-          type=(ResourceType) ParseCommandOption(MagickResourceOptions,
-            MagickFalse,argv[1]);
           limit=MagickResourceInfinity;
-          if (LocaleCompare("unlimited",argv[2]) != 0)
-            limit=(MagickSizeType) SiPrefixToDouble(argv[2],100.0);
-          (void) SetMagickResourceLimit(type,limit);
+          parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType",
+                option,arg1);
+          if (LocaleCompare("unlimited",arg2) != 0)
+            limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
+          (void) SetMagickResourceLimit((ResourceType)parse,limit);
           break;
         }
-      if (LocaleCompare("list",argv[0]+1) == 0)
+      if (LocaleCompare("log",option+1) == 0)
         {
-          ssize_t
-            list;
-
-          /*
-            Display configuration list.
-          */
-          list=ParseCommandOption(MagickListOptions,MagickFalse,argv[1]);
-          switch (list)
-          {
-            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;
-            }
+          if (IfSetOption) {
+            if ((strchr(arg1,'%') == (char *) NULL))
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+            (void) SetLogFormat(arg1);
           }
           break;
         }
-      if (LocaleCompare("log",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            break;
-          (void) SetLogFormat(argv[1]);
-          break;
-        }
-      if (LocaleCompare("loop",argv[0]+1) == 0)
+      if (LocaleCompare("loop",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"0");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* SyncImageSettings() used to set per-image attribute. */
+          arg1=ArgOption("0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'm':
     {
-      if (LocaleCompare("matte",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"false");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,"true");
-          break;
-        }
-      if (LocaleCompare("mattecolor",argv[0]+1) == 0)
+      if (LocaleCompare("mattecolor",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,argv[1]);
-              (void) QueryColorCompliance(MatteColor,AllComplience,
-                &image_info->matte_color,exception);
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
-          (void) QueryColorCompliance(argv[1],AllComplience,&image_info->matte_color,
-            exception);
+          /* SyncImageSettings() used to set per-image attribute. */
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
+             &_image_info->matte_color,_exception);
           break;
         }
-      if (LocaleCompare("monitor",argv[0]+1) == 0)
+      if (LocaleCompare("monitor",option+1) == 0)
         {
-          (void) SetImageInfoProgressMonitor(image_info,MonitorProgress,
-            (void *) NULL);
+          (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
+                MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
           break;
         }
-      if (LocaleCompare("monochrome",argv[0]+1) == 0)
+      if (LocaleCompare("monochrome",option+1) == 0)
         {
-          image_info->monochrome=(*argv[0] == '-') ? MagickTrue : MagickFalse;
+          /* Setting (used by some input coders!) -- why?
+             Warning: This is also Special '-type' SimpleOperator
+          */
+          _image_info->monochrome= ArgBoolean;
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'o':
     {
-      if (LocaleCompare("orient",argv[0]+1) == 0)
+      if (LocaleCompare("orient",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->orientation=UndefinedOrientation;
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          image_info->orientation=(OrientationType) ParseCommandOption(
-            MagickOrientationOptions,MagickFalse,argv[1]);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* Is not used when defining for new images.
+             This makes it more of a 'operation' than a setting
+             FUTURE: make set meta-data operator instead.
+             SyncImageSettings() used to set per-image attribute.
+          */
+          parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
+               ArgOption("undefined"));
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
+                                      option,arg1);
+          _image_info->orientation=(OrientationType)parse;
+          (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
           break;
         }
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'p':
     {
-      if (LocaleCompare("page",argv[0]+1) == 0)
+      if (LocaleCompare("page",option+1) == 0)
         {
+          /* Only used for new images and image generators.
+             SyncImageSettings() used to set per-image attribute. ?????
+             That last is WRONG!!!!
+             FUTURE: adjust named 'page' sizes according density
+          */
           char
             *canonical_page,
             page[MaxTextExtent];
@@ -1132,17 +1111,17 @@ WandExport MagickBooleanType SettingsOptionInfo(ImageInfo *image_info,
           RectangleInfo
             geometry;
 
-          if (*argv[0] == '+')
+          if (!IfSetOption)
             {
-              (void) DeleteImageOption(image_info,argv[0]+1);
-              (void) CloneString(&image_info->page,(char *) NULL);
+              (void) DeleteImageOption(_image_info,option+1);
+              (void) CloneString(&_image_info->page,(char *) NULL);
               break;
             }
           (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
-          image_option=GetImageOption(image_info,"page");
+          image_option=GetImageOption(_image_info,"page");
           if (image_option != (const char *) NULL)
             flags=ParseAbsoluteGeometry(image_option,&geometry);
-          canonical_page=GetPageGeometry(argv[1]);
+          canonical_page=GetPageGeometry(arg1);
           flags=ParseAbsoluteGeometry(canonical_page,&geometry);
           canonical_page=DestroyString(canonical_page);
           (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
@@ -1151,344 +1130,410 @@ WandExport MagickBooleanType SettingsOptionInfo(ImageInfo *image_info,
             (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
               (unsigned long) geometry.width,(unsigned long) geometry.height,
               (long) geometry.x,(long) geometry.y);
-          (void) SetImageOption(image_info,argv[0]+1,page);
-          (void) CloneString(&image_info->page,page);
+          (void) SetImageOption(_image_info,option+1,page);
+          (void) CloneString(&_image_info->page,page);
           break;
         }
-      if (LocaleCompare("pen",argv[0]+1) == 0)
+      if (LocaleCompare("ping",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"none");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          _image_info->ping = ArgBoolean;
           break;
         }
-      if (LocaleCompare("ping",argv[0]+1) == 0)
+      if (LocaleCompare("pointsize",option+1) == 0)
         {
-          image_info->ping=(*argv[0] == '-') ? MagickTrue : MagickFalse;
-          break;
-        }
-      if (LocaleCompare("pointsize",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            geometry_info.rho=0.0;
-          else
-            (void) ParseGeometry(argv[1],&geometry_info);
-          image_info->pointsize=geometry_info.rho;
+          if (IfSetOption) {
+            if (IfMagickFalse(IsGeometry(arg1)))
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+            _image_info->pointsize =
+            _draw_info->pointsize =
+              StringToDouble(arg1,(char **) NULL);
+          }
+          else {
+            _image_info->pointsize=0.0; /* unset pointsize */
+            _draw_info->pointsize=12.0;
+          }
           break;
         }
-      if (LocaleCompare("precision",argv[0]+1) == 0)
+      if (LocaleCompare("precision",option+1) == 0)
         {
-          (void) SetMagickPrecision(StringToInteger(argv[1]));
+          arg1=ArgOption("-1");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetMagickPrecision(StringToInteger(arg1));
           break;
         }
-      if (LocaleCompare("preview",argv[0]+1) == 0)
+      /* FUTURE: Only the 'preview' coder appears to use this
+       * DEPRECIATE the coder?  Leaving only the 'preview' operator.
+      if (LocaleCompare("preview",option+1) == 0)
         {
-          /*
-            Preview image.
-          */
-          if (*argv[0] == '+')
-            {
-              image_info->preview_type=UndefinedPreview;
-              break;
-            }
-          image_info->preview_type=(PreviewType) ParseCommandOption(
-            MagickPreviewOptions,MagickFalse,argv[1]);
+          _image_info->preview_type=UndefinedPreview;
+          if (IfSetOption)
+            _image_info->preview_type=(PreviewType) ParseCommandOption(
+                MagickPreviewOptions,MagickFalse,arg1);
           break;
         }
-      break;
+      */
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'q':
     {
-      if (LocaleCompare("quality",argv[0]+1) == 0)
+      if (LocaleCompare("quality",option+1) == 0)
         {
-          /*
-            Set image compression quality.
-          */
-          if (*argv[0] == '+')
-            {
-              image_info->quality=UndefinedCompressionQuality;
-              (void) SetImageOption(image_info,argv[0]+1,"0");
-              break;
-            }
-          image_info->quality=StringToUnsignedLong(argv[1]);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
+                                            : UNDEFINED_COMPRESSION_QUALITY;
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("quiet",argv[0]+1) == 0)
+      if (LocaleCompare("quantize",option+1) == 0)
         {
+          /* Just a set direct in _quantize_info */
+          arg1=ArgOption("undefined");
+          parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
+                 option,arg1);
+          _quantize_info->colorspace=(ColorspaceType)parse;
+          break;
+        }
+      if (LocaleCompare("quiet",option+1) == 0)
+        {
+          /* FUTURE: if two -quiet is performed you can not do +quiet!
+             This needs to be checked over thoughly.
+          */
           static WarningHandler
             warning_handler = (WarningHandler) NULL;
 
-          if (*argv[0] == '+')
-            {
-              /*
-                Restore error or warning messages.
-              */
-              warning_handler=SetWarningHandler(warning_handler);
-              break;
-            }
-          /*
-            Suppress error or warning messages.
-          */
-          warning_handler=SetWarningHandler((WarningHandler) NULL);
+          WarningHandler
+            tmp = SetWarningHandler((WarningHandler) NULL);
+
+          if ( tmp != (WarningHandler) NULL)
+            warning_handler = tmp; /* remember the old handler */
+          if (!IfSetOption)        /* set the old handler */
+            warning_handler=SetWarningHandler(warning_handler);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'r':
     {
-      if (LocaleCompare("red-primary",argv[0]+1) == 0)
+      if (LocaleCompare("red-primary",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"0.0");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* Image chromaticity X,Y  NB: Y=X if Y not defined
+             Used by many coders
+             SyncImageSettings() used to set per-image attribute.
+          */
+          arg1=ArgOption("0.0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      break;
+      if (LocaleCompare("regard-warnings",option+1) == 0)
+        /* FUTURE: to be replaced by a 'fatal-level' type setting */
+        break;
+      if (LocaleCompare("render",option+1) == 0)
+        {
+          /* _draw_info only setting */
+          _draw_info->render= ArgBooleanNot;
+          break;
+        }
+      if (LocaleCompare("respect-parenthesis",option+1) == 0)
+        {
+          /* link image and setting stacks - option is itself saved on stack! */
+          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
+          break;
+        }
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 's':
     {
-      if (LocaleCompare("sampling-factor",argv[0]+1) == 0)
+      if (LocaleCompare("sampling-factor",option+1) == 0)
         {
-          /*
-            Set image sampling factor.
-          */
-          if (*argv[0] == '+')
-            {
-              if (image_info->sampling_factor != (char *) NULL)
-                image_info->sampling_factor=DestroyString(
-                  image_info->sampling_factor);
-              break;
-            }
-          (void) CloneString(&image_info->sampling_factor,argv[1]);
+          /* FUTURE: should be converted to jpeg:sampling_factor */
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("scene",argv[0]+1) == 0)
+      if (LocaleCompare("scene",option+1) == 0)
         {
-          /*
-            Set image scene.
+          /* SyncImageSettings() used to set this as a per-image attribute.
+             What ??? Why ????
           */
-          if (*argv[0] == '+')
-            {
-              image_info->scene=0;
-              (void) SetImageOption(image_info,argv[0]+1,"0");
-              break;
-            }
-          image_info->scene=StringToUnsignedLong(argv[1]);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          _image_info->scene=StringToUnsignedLong(ArgOption("0"));
           break;
         }
-      if (LocaleCompare("seed",argv[0]+1) == 0)
+      if (LocaleCompare("seed",option+1) == 0)
         {
-          size_t
-            seed;
-
-          if (*argv[0] == '+')
-            {
-              seed=(size_t) time((time_t *) NULL);
-              SeedPseudoRandomGenerator(seed);
-              break;
-            }
-          seed=StringToUnsignedLong(argv[1]);
-          SeedPseudoRandomGenerator(seed);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          SeedPseudoRandomGenerator(
+               IfSetOption ? (size_t) StringToUnsignedLong(arg1)
+                           : (size_t) time((time_t *) NULL) );
           break;
         }
-      if (LocaleCompare("size",argv[0]+1) == 0)
+      if (LocaleCompare("size",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              if (image_info->size != (char *) NULL)
-                image_info->size=DestroyString(image_info->size);
-              break;
-            }
-          (void) CloneString(&image_info->size,argv[1]);
+          /* FUTURE: string in _image_info -- convert to Option ???
+             Look at the special handling for "size" in SetImageOption()
+           */
+          (void) CloneString(&_image_info->size,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("stroke",argv[0]+1) == 0)
+      if (LocaleCompare("stretch",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"none");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          arg1=ArgOption("undefined");
+          parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
+                 option,arg1);
+          _draw_info->stretch=(StretchType) parse;
           break;
         }
-      if (LocaleCompare("strokewidth",argv[0]+1) == 0)
+      if (LocaleCompare("stroke",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"0");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* set stroke color OR stroke-pattern
+             UPDATE: ensure stroke color is not destroyed is a pattern
+             is given. Just in case the color is also used for other purposes.
+           */
+          MagickBooleanType
+            status;
+
+          ExceptionInfo
+            *sans;
+
+          PixelInfo
+            color;
+
+          arg1 = ArgOption("none");  /* +fill turns it off! */
+          (void) SetImageOption(_image_info,option+1,arg1);
+          if (_draw_info->stroke_pattern != (Image *) NULL)
+            _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
+
+          /* is it a color or a image? -- ignore exceptions */
+          sans=AcquireExceptionInfo();
+          status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
+          sans=DestroyExceptionInfo(sans);
+
+          if (IfMagickFalse(status))
+            _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
+          else
+            _draw_info->stroke=color;
           break;
         }
-      if (LocaleCompare("synchronize",argv[0]+1) == 0)
+      if (LocaleCompare("strokewidth",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->synchronize=MagickFalse;
-              break;
-            }
-          image_info->synchronize=MagickTrue;
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
+               (char **) NULL);
           break;
         }
-      break;
+      if (LocaleCompare("style",option+1) == 0)
+        {
+          arg1=ArgOption("undefined");
+          parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
+                 option,arg1);
+          _draw_info->style=(StyleType) parse;
+          break;
+        }
+      if (LocaleCompare("synchronize",option+1) == 0)
+        {
+          /* FUTURE: syncronize to storage - but what does that mean? */
+          _image_info->synchronize = ArgBoolean;
+          break;
+        }
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 't':
     {
-      if (LocaleCompare("taint",argv[0]+1) == 0)
+      if (LocaleCompare("taint",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"false");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,"true");
+          /* SyncImageSettings() used to set per-image attribute. */
+          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
           break;
         }
-      if (LocaleCompare("texture",argv[0]+1) == 0)
+      if (LocaleCompare("texture",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              if (image_info->texture != (char *) NULL)
-                image_info->texture=DestroyString(image_info->texture);
-              break;
-            }
-          (void) CloneString(&image_info->texture,argv[1]);
+          /* FUTURE: move _image_info string to option splay-tree
+             Other than "montage" what uses "texture" ????
+          */
+          (void) CloneString(&_image_info->texture,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("tile-offset",argv[0]+1) == 0)
+      if (LocaleCompare("tile",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"0");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          _draw_info->fill_pattern=IfSetOption
+                                 ?GetImageCache(_image_info,arg1,_exception)
+                                 :DestroyImage(_draw_info->fill_pattern);
           break;
         }
-      if (LocaleCompare("transparent-color",argv[0]+1) == 0)
+      if (LocaleCompare("tile-offset",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) QueryColorCompliance("none",AllComplience,
-                  &image_info->transparent_color,exception);
-              (void) SetImageOption(image_info,argv[0]+1,"none");
-              break;
-            }
-              (void) QueryColorCompliance("none",AllComplience,
-                  &image_info->transparent_color,exception);
-            exception);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* SyncImageSettings() used to set per-image attribute. ??? */
+          arg1=ArgOption("0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("type",argv[0]+1) == 0)
+      if (LocaleCompare("transparent-color",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->type=UndefinedType;
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
-            MagickFalse,argv[1]);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* FUTURE: both _image_info attribute & ImageOption in use!
+             _image_info only used for generating new images.
+             SyncImageSettings() used to set per-image attribute.
+
+             Note that +transparent-color, means fall-back to image
+             attribute so ImageOption is deleted, not set to a default.
+          */
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
+              &_image_info->transparent_color,_exception);
           break;
         }
-      break;
+      if (LocaleCompare("treedepth",option+1) == 0)
+        {
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
+          break;
+        }
+      if (LocaleCompare("type",option+1) == 0)
+        {
+          /* SyncImageSettings() used to set per-image attribute. */
+          parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
+               ArgOption("undefined"));
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
+                 option,arg1);
+          _image_info->type=(ImageType) parse;
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          break;
+        }
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'u':
     {
-      if (LocaleCompare("undercolor",argv[0]+1) == 0)
+      if (LocaleCompare("undercolor",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) DeleteImageOption(image_info,argv[0]+1);
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
+               &_draw_info->undercolor,_exception);
           break;
         }
-      if (LocaleCompare("units",argv[0]+1) == 0)
+      if (LocaleCompare("units",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->units=UndefinedResolution;
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          image_info->units=(ResolutionType) ParseCommandOption(
-            MagickResolutionOptions,MagickFalse,argv[1]);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* SyncImageSettings() used to set per-image attribute.
+             Should this effect _draw_info X and Y resolution?
+             FUTURE: this probably should be part of the density setting
+          */
+          parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
+               ArgOption("undefined"));
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
+                 option,arg1);
+          _image_info->units=(ResolutionType) parse;
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'v':
     {
-      if (LocaleCompare("verbose",argv[0]+1) == 0)
+      if (LocaleCompare("verbose",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->verbose=MagickFalse;
-              break;
-            }
-          image_info->verbose=MagickTrue;
-          image_info->ping=MagickFalse;
+          /* FUTURE: Remember all options become image artifacts
+             _image_info->verbose is only used by coders.
+          */
+          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
+          _image_info->verbose= ArgBoolean;
+          _image_info->ping=MagickFalse; /* verbose can't be a ping */
           break;
         }
-      if (LocaleCompare("view",argv[0]+1) == 0)
+      if (LocaleCompare("view",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              if (image_info->view != (char *) NULL)
-                image_info->view=DestroyString(image_info->view);
-              break;
-            }
-          (void) CloneString(&image_info->view,argv[1]);
+          /* FUTURE: Convert from _image_info to ImageOption
+             Only used by coder FPX
+             And it only tests existance, not its content!
+          */
+          (void) CloneString(&_image_info->view,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("virtual-pixel",argv[0]+1) == 0)
+      if (LocaleCompare("virtual-pixel",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              image_info->virtual_pixel_method=UndefinedVirtualPixelMethod;
-              (void) SetImageOption(image_info,argv[0]+1,"undefined");
-              break;
-            }
-          image_info->virtual_pixel_method=(VirtualPixelMethod)
-            ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,argv[1]);
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* SyncImageSettings() used to set per-image attribute.
+             This is VERY deep in the image caching structure.
+          */
+          parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
+               ArgOption("undefined"));
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
+                 option,arg1);
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'w':
     {
-      if (LocaleCompare("white-point",argv[0]+1) == 0)
+      if (LocaleCompare("weight",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageOption(image_info,argv[0]+1,"0.0");
-              break;
-            }
-          (void) SetImageOption(image_info,argv[0]+1,argv[1]);
+          /* Just what does using a font 'weight' do ???
+             There is no "-list weight" output (reference manual says there is)
+          */
+          arg1=ArgOption("all");
+          _draw_info->weight=StringToUnsignedLong(arg1);
+          if (LocaleCompare(arg1,"all") == 0)
+            _draw_info->weight=0;
+          if (LocaleCompare(arg1,"bold") == 0)
+            _draw_info->weight=700;
+          if (LocaleCompare(arg1,"bolder") == 0)
+            if (_draw_info->weight <= 800)
+              _draw_info->weight+=100;
+          if (LocaleCompare(arg1,"lighter") == 0)
+            if (_draw_info->weight >= 100)
+              _draw_info->weight-=100;
+          if (LocaleCompare(arg1,"normal") == 0)
+            _draw_info->weight=400;
+          break;
+        }
+      if (LocaleCompare("white-point",option+1) == 0)
+        {
+          /* Used as a image chromaticity setting
+             SyncImageSettings() used to set per-image attribute.
+          */
+          arg1=ArgOption("0.0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     default:
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
   }
-  return(MagickTrue);
+
+#undef _image_info
+#undef _exception
+#undef _draw_info
+#undef _quantize_info
+#undef IfSetOption
+#undef ArgBoolean
+#undef ArgBooleanNot
+#undef ArgBooleanString
+#undef ArgOption
+
+  return;
 }
 \f
 /*
@@ -1496,62 +1541,80 @@ WandExport MagickBooleanType SettingsOptionInfo(ImageInfo *image_info,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+     S i m p l e O p e r a t i o n I m a g e                                 %
++     C L I S i m p l e O p e r a t o r I m a g e s                           %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  SimpleOperationImage() apply one simple operation on one image.
-%  The image however may be part of a longer list of images.
+%  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.
 %
-%  The image in the list may be modified in three different ways...
+%  It is assumed that any per-image settings are up-to-date with respect to
+%  extra settings that were already saved in the wand.
 %
-%    * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
-%    * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
-%    * replace by a list of images (-separate and -crop only!)
+%  The format of the WandSimpleOperatorImage method is:
 %
-%  In each case the result is returned into the list, and the pointer to the
-%  modified image (last image added if replaced by a list of images) is
-%  returned.  As the image pointed to may be replaced, the first image in the
-%  list may also change.  GetFirstImageInList() should be used by caller if
-%  they wish return the Image pointer to the first image in list.
+%    void CLISimpleOperatorImages(MagickCLI *cli_wand,
+%        const char *option, const char *arg1, const char *arg2)
 %
-%  The format of the SimpleOperationImage method is:
+%  A description of each parameter follows:
 %
-%    MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
-%        const int argc,const char **argv,Image **image)
+%    o cli_wand: structure holding settings and images to be operated on
 %
-%  A description of each parameter follows:
+%    o option:  The option string for the operation
+%
+%    o arg1, arg2: optional argument strings to the operation
+%
+% Any problems will be added to the 'exception' entry of the given wand.
 %
-%    o image_info: the image info..
+% Example usage...
 %
-%    o argc: Specifies a pointer to an integer describing the number of
-%      elements in the argument vector.
+%  CLISimpleOperatorImages(cli_wand, "-crop","100x100+20+30",NULL);
+%  CLISimpleOperatorImages(cli_wand, "+repage",NULL,NULL);
+%  CLISimpleOperatorImages(cli_wand, "+distort","SRT","45");
 %
-%    o argv: Specifies a pointer to a text array containing the command line
-%      arguments.
+% Or for handling command line arguments EG: +/-option ["arg1"]
 %
-%    o image: the image.
+%    cli_wand
+%    argc,argv
+%    i=index in argv
 %
-%    o exception: return any errors or warnings in this structure.
+%    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;
 %
 */
-MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
-     const int wand_unused(argc), const char **argv,Image **image,
-     ExceptionInfo *exception)
-{
-  Image *
-    new_image;
 
-  ChannelType
-    channel;
+/*
+  Internal subrountine to apply one simple image operation to the current
+  image pointed to by the CLI wand.
 
-  const char
-    *format;
+  The image in the list may be modified in three different ways...
+    * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
+    * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
+    * one image replace by a list of images (-separate and -crop only!)
 
-  DrawInfo
-    *draw_info;
+  In each case the result replaces the single original image in the list, as
+  well as the pointer to the modified image (last image added if replaced by a
+  list of images) is returned.
+
+  As the image pointed to may be replaced, the first image in the list may
+  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)
+{
+  Image *
+    new_image;
 
   GeometryInfo
     geometry_info;
@@ -1560,202 +1623,164 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
     geometry;
 
   MagickStatusType
-    status;
+    flags;
 
-  PixelInfo
-    fill;
+  ssize_t
+    parse;
 
-  MagickStatusType
-    flags;
+#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 IfNormalOp      (*option=='-')
+#define IfPlusOp        (*option!='-')
+#define normal_op       IsMagickTrue(IfNormalOp)
+#define plus_alt_op     IsMagickFalse(IfNormalOp)
 
-  QuantizeInfo
-    *quantize_info;
+  assert(cli_wand != (MagickCLI *) NULL);
+  assert(cli_wand->signature == WandSignature);
+  assert(cli_wand->wand.signature == WandSignature);
+  assert(_image != (Image *) NULL);             /* an image must be present */
+  if (IfMagickTrue(cli_wand->wand.debug))
+    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
+
+  (void) SyncImageSettings(_image_info,_image,_exception);
 
-  assert(image_info != (const ImageInfo *) NULL);
-  assert(image_info->signature == MagickSignature);
-  assert(image != (Image **) NULL);
-  assert((*image)->signature == MagickSignature);
-  if ((*image)->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
-  if (argc < 0)
-    return(MagickTrue);
-  draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
-  quantize_info=AcquireQuantizeInfo(image_info);
   SetGeometryInfo(&geometry_info);
-  GetPixelInfo(*image,&fill);
-  SetPixelInfoPacket(*image,&(*image)->background_color,&fill);
-  channel=image_info->channel;
-  format=GetImageOption(image_info,"format");
 
-  new_image = (Image *)NULL;
+  new_image = (Image *)NULL; /* the replacement image, if not null at end */
 
-  switch (*(argv[0]+1))
+  /* 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",argv[0]+1) == 0)
+      if (LocaleCompare("adaptive-blur",option+1) == 0)
         {
-          /*
-            Adaptive blur image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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 & XiValue) == 0)
-            geometry_info.xi=0.0;
-          new_image=AdaptiveBlurImage(*image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,exception);
+          new_image=AdaptiveBlurImage(_image,geometry_info.rho,
+            geometry_info.sigma,_exception);
           break;
         }
-      if (LocaleCompare("adaptive-resize",argv[0]+1) == 0)
+      if (LocaleCompare("adaptive-resize",option+1) == 0)
         {
-          /*
-            Adaptive resize image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
-          new_image=AdaptiveResizeImage(*image,geometry.width,
-            geometry.height,interpolate_method,exception);
+          /* FUTURE: Roll into a resize special operator */
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
+          new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
+            _exception);
           break;
         }
-      if (LocaleCompare("adaptive-sharpen",argv[0]+1) == 0)
+      if (LocaleCompare("adaptive-sharpen",option+1) == 0)
         {
-          /*
-            Adaptive sharpen image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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 & XiValue) == 0)
-            geometry_info.xi=0.0;
-          new_image=AdaptiveSharpenImage(*image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,exception);
-          break;
-        }
-      if (LocaleCompare("affine",argv[0]+1) == 0)
-        {
-          /*
-            Affine matrix.
-          */
-          if (*argv[0] == '+')
-            {
-              GetAffineMatrix(&draw_info->affine);
-              break;
-            }
-          (void) ParseAffineGeometry(argv[1],&draw_info->affine,exception);
+          new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
+            geometry_info.sigma,_exception);
           break;
         }
-      if (LocaleCompare("alpha",argv[0]+1) == 0)
+      if (LocaleCompare("alpha",option+1) == 0)
         {
-          AlphaChannelType
-            alpha_type;
-
-          (void) SyncImageSettings(image_info,*image);
-          alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
-            MagickFalse,argv[1]);
-          (void) SetImageAlphaChannel(*image,alpha_type,exception);
+          parse=ParseCommandOption(MagickAlphaOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelType",
+                 option,arg1);
+          (void) SetImageAlphaChannel(_image,(AlphaChannelType)parse,
+               _exception);
           break;
         }
-      if (LocaleCompare("annotate",argv[0]+1) == 0)
+      if (LocaleCompare("annotate",option+1) == 0)
         {
           char
             *text,
             geometry[MaxTextExtent];
 
-          /*
-            Annotate image.
-          */
-          (void) SyncImageSettings(image_info,*image);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           SetGeometryInfo(&geometry_info);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=geometry_info.rho;
-          text=InterpretImageProperties(image_info,*image,argv[2],
-            exception);
+          text=InterpretImageProperties(_image_info,_image,arg2,
+            _exception);
           if (text == (char *) NULL)
             break;
-          (void) CloneString(&draw_info->text,text);
+          (void) CloneString(&_draw_info->text,text);
           text=DestroyString(text);
           (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
             geometry_info.xi,geometry_info.psi);
-          (void) CloneString(&draw_info->geometry,geometry);
-          draw_info->affine.sx=cos(DegreesToRadians(
+          (void) CloneString(&_draw_info->geometry,geometry);
+          _draw_info->affine.sx=cos(DegreesToRadians(
             fmod(geometry_info.rho,360.0)));
-          draw_info->affine.rx=sin(DegreesToRadians(
+          _draw_info->affine.rx=sin(DegreesToRadians(
             fmod(geometry_info.rho,360.0)));
-          draw_info->affine.ry=(-sin(DegreesToRadians(
+          _draw_info->affine.ry=(-sin(DegreesToRadians(
             fmod(geometry_info.sigma,360.0))));
-          draw_info->affine.sy=cos(DegreesToRadians(
+          _draw_info->affine.sy=cos(DegreesToRadians(
             fmod(geometry_info.sigma,360.0)));
-          (void) AnnotateImage(*image,draw_info,exception);
-          break;
-        }
-      if (LocaleCompare("antialias",argv[0]+1) == 0)
-        {
-          draw_info->stroke_antialias=(*argv[0] == '-') ? MagickTrue :
-            MagickFalse;
-          draw_info->text_antialias=(*argv[0] == '-') ? MagickTrue :
-            MagickFalse;
+          (void) AnnotateImage(_image,_draw_info,_exception);
+          GetAffineMatrix(&_draw_info->affine);
           break;
         }
-      if (LocaleCompare("auto-gamma",argv[0]+1) == 0)
+      if (LocaleCompare("auto-gamma",option+1) == 0)
         {
-          /*
-            Auto Adjust Gamma of image based on its mean
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) AutoGammaImage(*image,exception);
+          (void) AutoGammaImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("auto-level",argv[0]+1) == 0)
+      if (LocaleCompare("auto-level",option+1) == 0)
         {
-          /*
-            Perfectly Normalize (max/min stretch) the image
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) AutoLevelImage(*image,exception);
+          (void) AutoLevelImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("auto-orient",argv[0]+1) == 0)
+      if (LocaleCompare("auto-orient",option+1) == 0)
         {
-          (void) SyncImageSettings(image_info,*image);
-          switch ((*image)->orientation)
+          /* This should probably be a MagickCore function */
+          switch (_image->orientation)
           {
             case TopRightOrientation:
             {
-              new_image=FlopImage(*image,exception);
+              new_image=FlopImage(_image,_exception);
               break;
             }
             case BottomRightOrientation:
             {
-              new_image=RotateImage(*image,180.0,exception);
+              new_image=RotateImage(_image,180.0,_exception);
               break;
             }
             case BottomLeftOrientation:
             {
-              new_image=FlipImage(*image,exception);
+              new_image=FlipImage(_image,_exception);
               break;
             }
             case LeftTopOrientation:
             {
-              new_image=TransposeImage(*image,exception);
+              new_image=TransposeImage(_image,_exception);
               break;
             }
             case RightTopOrientation:
             {
-              new_image=RotateImage(*image,90.0,exception);
+              new_image=RotateImage(_image,90.0,_exception);
               break;
             }
             case RightBottomOrientation:
             {
-              new_image=TransverseImage(*image,exception);
+              new_image=TransverseImage(_image,_exception);
               break;
             }
             case LeftBottomOrientation:
             {
-              new_image=RotateImage(*image,270.0,exception);
+              new_image=RotateImage(_image,270.0,_exception);
               break;
             }
             default:
@@ -1765,78 +1790,64 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
             new_image->orientation=TopLeftOrientation;
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'b':
     {
-      if (LocaleCompare("black-threshold",argv[0]+1) == 0)
+      if (LocaleCompare("black-threshold",option+1) == 0)
         {
-          /*
-            Black threshold image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) BlackThresholdImage(*image,argv[1],exception);
-          InheritException(exception,&(*image)->exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) BlackThresholdImage(_image,arg1,_exception);
           break;
         }
-      if (LocaleCompare("blue-shift",argv[0]+1) == 0)
+      if (LocaleCompare("blue-shift",option+1) == 0)
         {
-          /*
-            Blue shift image.
-          */
-          (void) SyncImageSettings(image_info,*image);
           geometry_info.rho=1.5;
-          if (*argv[0] == '-')
-            flags=ParseGeometry(argv[1],&geometry_info);
-          new_image=BlueShiftImage(*image,geometry_info.rho,exception);
+          if (IfNormalOp) {
+            if (IfMagickFalse(IsGeometry(arg1)))
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+            flags=ParseGeometry(arg1,&geometry_info);
+          }
+          new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
           break;
         }
-      if (LocaleCompare("blur",argv[0]+1) == 0)
+      if (LocaleCompare("blur",option+1) == 0)
         {
-          /*
-            Two pass gaussian blur of image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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 & XiValue) == 0)
-            geometry_info.xi=0.0;
-          new_image=BlurImage(*image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,exception);
+          new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
+           _exception);
           break;
         }
-      if (LocaleCompare("border",argv[0]+1) == 0)
+      if (LocaleCompare("border",option+1) == 0)
         {
-          /*
-            Surround image with a border of solid color.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
+          CompositeOperator
+            compose;
+
+          const char*
+            value;
+
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+
+          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;
-          new_image=BorderImage(*image,&geometry,compose,exception);
-          break;
-        }
-      if (LocaleCompare("bordercolor",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            {
-              (void) QueryColorCompliance(BorderColor,AllComplience,
-                &draw_info->border_color,exception);
-              break;
-            }
-          (void) QueryColorCompliance(argv[1],AllComplience,&draw_info->border_color,
-            exception);
-          break;
-        }
-      if (LocaleCompare("box",argv[0]+1) == 0)
-        {
-          (void) QueryColorCompliance(argv[1],AllComplience,&draw_info->undercolor,
-            exception);
+          new_image=BorderImage(_image,&geometry,compose,_exception);
           break;
         }
-      if (LocaleCompare("brightness-contrast",argv[0]+1) == 0)
+      if (LocaleCompare("brightness-contrast",option+1) == 0)
         {
           double
             brightness,
@@ -1848,25 +1859,22 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           MagickStatusType
             flags;
 
-          /*
-            Brightness / contrast image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
           brightness=geometry_info.rho;
           contrast=0.0;
           if ((flags & SigmaValue) != 0)
             contrast=geometry_info.sigma;
-          (void) BrightnessContrastImage(*image,brightness,contrast,
-            exception);
-          InheritException(exception,&(*image)->exception);
+          (void) BrightnessContrastImage(_image,brightness,contrast,
+            _exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'c':
     {
-      if (LocaleCompare("cdl",argv[0]+1) == 0)
+      if (LocaleCompare("cdl",option+1) == 0)
         {
           char
             *color_correction_collection;
@@ -1874,71 +1882,48 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           /*
             Color correct with a color decision list.
           */
-          (void) SyncImageSettings(image_info,*image);
-          color_correction_collection=FileToString(argv[1],~0,exception);
+          color_correction_collection=FileToString(arg1,~0,_exception);
           if (color_correction_collection == (char *) NULL)
             break;
-          (void) ColorDecisionListImage(*image,color_correction_collection,
-            exception);
-          InheritException(exception,&(*image)->exception);
+          (void) ColorDecisionListImage(_image,color_correction_collection,
+            _exception);
           break;
         }
-      if (LocaleCompare("channel",argv[0]+1) == 0)
+      if (LocaleCompare("charcoal",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            channel=DefaultChannels;
-          else
-            channel=(ChannelType) ParseChannelOption(argv[1]);
-          SetPixelChannelMap(*image,channel);
-          break;
-        }
-      if (LocaleCompare("charcoal",argv[0]+1) == 0)
-        {
-          /*
-            Charcoal image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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 & XiValue) == 0)
             geometry_info.xi=1.0;
-          new_image=CharcoalImage(*image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,exception);
+          new_image=CharcoalImage(_image,geometry_info.rho,
+            geometry_info.sigma,_exception);
           break;
         }
-      if (LocaleCompare("chop",argv[0]+1) == 0)
+      if (LocaleCompare("chop",option+1) == 0)
         {
-          /*
-            Chop the image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
-          new_image=ChopImage(*image,&geometry,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
+          new_image=ChopImage(_image,&geometry,_exception);
           break;
         }
-      if (LocaleCompare("clamp",argv[0]+1) == 0)
+      if (LocaleCompare("clamp",option+1) == 0)
         {
-          /*
-            Clamp image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ClampImage(*image);
-          InheritException(exception,&(*image)->exception);
+          (void) ClampImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("clip",argv[0]+1) == 0)
+      if (LocaleCompare("clip",option+1) == 0)
         {
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            {
-              (void) SetImageClipMask(*image,(Image *) NULL,exception);
-              break;
-            }
-          (void) ClipImage(*image,exception);
+          if (IfNormalOp)
+            (void) ClipImage(_image,_exception);
+          else /* "+mask" remove the write mask */
+            (void) SetImageMask(_image,(Image *) NULL,_exception);
           break;
         }
-      if (LocaleCompare("clip-mask",argv[0]+1) == 0)
+      if (LocaleCompare("clip-mask",option+1) == 0)
         {
           CacheView
             *mask_view;
@@ -1953,127 +1938,109 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
             x;
 
           ssize_t
-            y;
-
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            {
-              /*
-                Remove a mask.
-              */
-              (void) SetImageMask(*image,(Image *) NULL,exception);
-              break;
-            }
-          mask_image=GetImageCache(image_info,argv[1],exception);
+            y;
+
+          if (IfPlusOp) {
+            /* "+clip-mask" Remove the write mask */
+            (void) SetImageMask(_image,(Image *) NULL,_exception);
+            break;
+          }
+          mask_image=GetImageCache(_image_info,arg1,_exception);
           if (mask_image == (Image *) NULL)
             break;
-          if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
-            return(MagickFalse);
+          if (IfMagickFalse(SetImageStorageClass(mask_image,DirectClass,_exception)))
+            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);
           for (y=0; y < (ssize_t) mask_image->rows; y++)
           {
             q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
-              exception);
+              _exception);
             if (q == (Quantum *) NULL)
               break;
             for (x=0; x < (ssize_t) mask_image->columns; x++)
             {
-              if (mask_image->matte == MagickFalse)
+              if (IfMagickFalse(mask_image->matte))
                 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
               SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
               SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
               SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
               q+=GetPixelChannels(mask_image);
             }
-            if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
+            if (IfMagickFalse(SyncCacheViewAuthenticPixels(mask_view,_exception)))
               break;
           }
+          /* clean up and set the write mask */
           mask_view=DestroyCacheView(mask_view);
           mask_image->matte=MagickTrue;
-          (void) SetImageClipMask(*image,mask_image,exception);
+          (void) SetImageMask(_image,mask_image,_exception);
           mask_image=DestroyImage(mask_image);
-          InheritException(exception,&(*image)->exception);
           break;
         }
-      if (LocaleCompare("clip-path",argv[0]+1) == 0)
+      if (LocaleCompare("clip-path",option+1) == 0)
         {
-          (void) SyncImageSettings(image_info,*image);
-          (void) ClipImagePath(*image,argv[1],*argv[0] == '-' ? MagickTrue :
-            MagickFalse,exception);
+          (void) ClipImagePath(_image,arg1,normal_op,_exception);
           break;
         }
-      if (LocaleCompare("colorize",argv[0]+1) == 0)
+      if (LocaleCompare("colorize",option+1) == 0)
         {
-          /*
-            Colorize the image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=ColorizeImage(*image,argv[1],draw_info->fill,
-            exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
           break;
         }
-      if (LocaleCompare("color-matrix",argv[0]+1) == 0)
+      if (LocaleCompare("color-matrix",option+1) == 0)
         {
           KernelInfo
             *kernel;
 
-          (void) SyncImageSettings(image_info,*image);
-          kernel=AcquireKernelInfo(argv[1]);
+          kernel=AcquireKernelInfo(arg1);
           if (kernel == (KernelInfo *) NULL)
-            break;
-          new_image=ColorMatrixImage(*image,kernel,exception);
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          new_image=ColorMatrixImage(_image,kernel,_exception);
           kernel=DestroyKernelInfo(kernel);
           break;
         }
-      if (LocaleCompare("colors",argv[0]+1) == 0)
+      if (LocaleCompare("colors",option+1) == 0)
         {
-          /*
-            Reduce the number of colors in the image.
+          /* Reduce the number of colors in the image.
+             FUTURE: also provide 'plus version with image 'color counts'
           */
-          (void) SyncImageSettings(image_info,*image);
-          quantize_info->number_colors=StringToUnsignedLong(argv[1]);
-          if (quantize_info->number_colors == 0)
-            break;
-          if (((*image)->storage_class == DirectClass) ||
-              (*image)->colors > quantize_info->number_colors)
-            (void) QuantizeImage(quantize_info,*image,exception);
+          _quantize_info->number_colors=StringToUnsignedLong(arg1);
+          if (_quantize_info->number_colors == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          if ((_image->storage_class == DirectClass) ||
+              _image->colors > _quantize_info->number_colors)
+            (void) QuantizeImage(_quantize_info,_image,_exception);
           else
-            (void) CompressImageColormap(*image,exception);
+            (void) CompressImageColormap(_image,_exception);
           break;
         }
-      if (LocaleCompare("colorspace",argv[0]+1) == 0)
+      if (LocaleCompare("colorspace",option+1) == 0)
         {
-          ColorspaceType
-            colorspace;
+          /* WARNING: this is both a image_info setting (already done)
+                      and a operator to change image colorspace.
 
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            {
-              (void) TransformImageColorspace(*image,RGBColorspace);
-              InheritException(exception,&(*image)->exception);
-              break;
-            }
-          colorspace=(ColorspaceType) ParseCommandOption(
-            MagickColorspaceOptions,MagickFalse,argv[1]);
-          (void) TransformImageColorspace(*image,colorspace);
-          InheritException(exception,&(*image)->exception);
-          break;
-        }
-      if (LocaleCompare("compose",argv[0]+1) == 0)
-        {
-          (void) SyncImageSettings(image_info,*image);
-          compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
-            MagickFalse,argv[1]);
+             FUTURE: default colorspace should be sRGB!
+             Unless some type of 'linear colorspace' mode is set.
+
+             Note that +colorspace sets "undefined" or no effect on
+             new images, but forces images already in memory back to RGB!
+             That seems to be a little strange!
+          */
+          (void) TransformImageColorspace(_image,
+                    IfNormalOp ? _image_info->colorspace : RGBColorspace,
+                    _exception);
           break;
         }
-      if (LocaleCompare("contrast",argv[0]+1) == 0)
+      if (LocaleCompare("contrast",option+1) == 0)
         {
-          (void) SyncImageSettings(image_info,*image);
-          (void) ContrastImage(*image,(*argv[0] == '-') ? MagickTrue :
-            MagickFalse,exception);
+          /* DEPRECIATED: The -/+level provides far more controlled form */
+          (void) ContrastImage(_image,normal_op,_exception);
           break;
         }
-      if (LocaleCompare("contrast-stretch",argv[0]+1) == 0)
+      if (LocaleCompare("contrast-stretch",option+1) == 0)
         {
           double
             black_point,
@@ -2082,130 +2049,102 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           MagickStatusType
             flags;
 
-          /*
-            Contrast stretch image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
           black_point=geometry_info.rho;
           white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
             black_point;
-          if ((flags & PercentValue) != 0)
-            {
-              black_point*=(double) (*image)->columns*(*image)->rows/100.0;
-              white_point*=(double) (*image)->columns*(*image)->rows/100.0;
+          if ((flags & PercentValue) != 0) {
+              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=(MagickRealType) _image->columns*_image->rows-
             white_point;
-          (void) ContrastStretchImage(*image,black_point,white_point,
-            exception);
-          InheritException(exception,&(*image)->exception);
+          (void) ContrastStretchImage(_image,black_point,white_point,
+            _exception);
           break;
         }
-      if (LocaleCompare("convolve",argv[0]+1) == 0)
+      if (LocaleCompare("convolve",option+1) == 0)
         {
           KernelInfo
             *kernel_info;
 
-          (void) SyncImageSettings(image_info,*image);
-          kernel_info=AcquireKernelInfo(argv[1]);
+          kernel_info=AcquireKernelInfo(arg1);
           if (kernel_info == (KernelInfo *) NULL)
-            break;
-          kernel_info->bias=(*image)->bias;
-          new_image=ConvolveImage(*image,kernel_info,exception);
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          /* kernel_info->bias=_image->bias; -- FUTURE: check this path! */
+          new_image=ConvolveImage(_image,kernel_info,_exception);
           kernel_info=DestroyKernelInfo(kernel_info);
           break;
         }
-      if (LocaleCompare("crop",argv[0]+1) == 0)
+      if (LocaleCompare("crop",option+1) == 0)
         {
-          /*
-            Crop a image to a smaller size
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=CropImageToTiles(*image,argv[1],exception);
+          /* WARNING: This can generate multiple images! */
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          new_image=CropImageToTiles(_image,arg1,_exception);
           break;
         }
-      if (LocaleCompare("cycle",argv[0]+1) == 0)
+      if (LocaleCompare("cycle",option+1) == 0)
         {
-          /*
-            Cycle an image colormap.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) CycleColormapImage(*image,(ssize_t) StringToLong(argv[1]),
-            exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
+            _exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'd':
     {
-      if (LocaleCompare("decipher",argv[0]+1) == 0)
+      if (LocaleCompare("decipher",option+1) == 0)
         {
           StringInfo
             *passkey;
 
-          /*
-            Decipher pixels.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          passkey=FileToStringInfo(argv[1],~0,exception);
-          if (passkey != (StringInfo *) NULL)
-            {
-              (void) PasskeyDecipherImage(*image,passkey,exception);
-              passkey=DestroyStringInfo(passkey);
-            }
+          passkey=FileToStringInfo(arg1,~0,_exception);
+          if (passkey == (StringInfo *) NULL)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+
+          (void) PasskeyDecipherImage(_image,passkey,_exception);
+          passkey=DestroyStringInfo(passkey);
           break;
         }
-      if (LocaleCompare("density",argv[0]+1) == 0)
+      if (LocaleCompare("depth",option+1) == 0)
         {
-          /*
-            Set image density.
+          /* The _image_info->depth setting has already been set
+             We just need to apply it to all images in current sequence
+
+             WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
+             That is it really is an operation, not a setting! Arrgghhh
+
+             FUTURE: this should not be an operator!!!
           */
-          (void) CloneString(&draw_info->density,argv[1]);
-          break;
-        }
-      if (LocaleCompare("depth",argv[0]+1) == 0)
-        {
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            {
-              (void) SetImageDepth(*image,MAGICKCORE_QUANTUM_DEPTH);
-              break;
-            }
-          (void) SetImageDepth(*image,StringToUnsignedLong(argv[1]));
+          (void) SetImageDepth(_image,_image_info->depth,_exception);
           break;
         }
-      if (LocaleCompare("deskew",argv[0]+1) == 0)
+      if (LocaleCompare("deskew",option+1) == 0)
         {
           double
             threshold;
 
-          /*
-            Straighten the image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            threshold=40.0*QuantumRange/100.0;
+          if (IfNormalOp) {
+            if (IfMagickFalse(IsGeometry(arg1)))
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+            threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
+          }
           else
-            threshold=SiPrefixToDouble(argv[1],QuantumRange);
-          new_image=DeskewImage(*image,threshold,exception);
-          break;
-        }
-      if (LocaleCompare("despeckle",argv[0]+1) == 0)
-        {
-          /*
-            Reduce the speckles within an image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=DespeckleImage(*image,exception);
+            threshold=40.0*QuantumRange/100.0;
+          new_image=DeskewImage(_image,threshold,_exception);
           break;
         }
-      if (LocaleCompare("display",argv[0]+1) == 0)
+      if (LocaleCompare("despeckle",option+1) == 0)
         {
-          (void) CloneString(&draw_info->server_name,argv[1]);
+          new_image=DespeckleImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("distort",argv[0]+1) == 0)
+      if (LocaleCompare("distort",option+1) == 0)
         {
           char
             *args,
@@ -2214,9 +2153,6 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           const char
             *p;
 
-          DistortImageMethod
-            method;
-
           double
             *arguments;
 
@@ -2226,31 +2162,37 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           size_t
             number_arguments;
 
-          /*
-            Distort image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
-            MagickFalse,argv[1]);
-          if ( method == ResizeDistortion )
+          parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+             CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
+                                      option,arg1);
+          if ((DistortImageMethod) parse == ResizeDistortion)
             {
-               /* Special Case - Argument is actually a resize geometry!
-               ** Convert that to an appropriate distortion argument array.
-               */
                double
                  resize_args[2];
-               (void) ParseRegionGeometry(*image,argv[2],&geometry,
-                    exception);
-               resize_args[0]=(double)geometry.width;
-               resize_args[1]=(double)geometry.height;
-               new_image=DistortImage(*image,method,(size_t)2,
-                    resize_args,MagickTrue,exception);
+               /* Special Case - Argument is actually a resize geometry!
+               ** Convert that to an appropriate distortion argument array.
+               ** FUTURE: make a separate special resize operator
+                    Roll into a resize special operator */
+               if (IfMagickFalse(IsGeometry(arg2)))
+                 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
+                                           option,arg2);
+               (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
+               resize_args[0]=(double) geometry.width;
+               resize_args[1]=(double) geometry.height;
+               new_image=DistortImage(_image,(DistortImageMethod) parse,
+                    (size_t)2,resize_args,MagickTrue,_exception);
                break;
             }
-          args=InterpretImageProperties(image_info,*image,argv[2],
-            exception);
+          /* 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++)
           {
@@ -2262,257 +2204,167 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           arguments=(double *) AcquireQuantumMemory(number_arguments,
             sizeof(*arguments));
           if (arguments == (double *) NULL)
-            ThrowWandFatalException(ResourceLimitFatalError,
-              "MemoryAllocationFailed",(*image)->filename);
+            CLIWandExceptionBreak(ResourceLimitFatalError,
+                                "MemoryAllocationFailed",option);
           (void) ResetMagickMemory(arguments,0,number_arguments*
-            sizeof(*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]=InterpretLocaleValue(token,(char **) NULL);
+            arguments[x]=StringToDouble(token,(char **) NULL);
           }
           args=DestroyString(args);
-          new_image=DistortImage(*image,method,number_arguments,arguments,
-            (*argv[0] == '+') ? MagickTrue : MagickFalse,exception);
+          new_image=DistortImage(_image,(DistortImageMethod) parse,
+               number_arguments,arguments,plus_alt_op,_exception);
           arguments=(double *) RelinquishMagickMemory(arguments);
           break;
         }
-      if (LocaleCompare("dither",argv[0]+1) == 0)
+      if (LocaleCompare("draw",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              quantize_info->dither=MagickFalse;
-              break;
-            }
-          quantize_info->dither=MagickTrue;
-          quantize_info->dither_method=(DitherMethod) ParseCommandOption(
-            MagickDitherOptions,MagickFalse,argv[1]);
-          if (quantize_info->dither_method == NoDitherMethod)
-            quantize_info->dither=MagickFalse;
-          break;
-        }
-      if (LocaleCompare("draw",argv[0]+1) == 0)
-        {
-          /*
-            Draw image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) CloneString(&draw_info->primitive,argv[1]);
-          (void) DrawImage(*image,draw_info,exception);
+          (void) CloneString(&_draw_info->primitive,arg1);
+          (void) DrawImage(_image,_draw_info,_exception);
+          (void) CloneString(&_draw_info->primitive,(char *)NULL);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'e':
     {
-      if (LocaleCompare("edge",argv[0]+1) == 0)
+      if (LocaleCompare("edge",option+1) == 0)
         {
-          /*
-            Enhance edges in the image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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);
+          new_image=EdgeImage(_image,geometry_info.rho,geometry_info.sigma,
+               _exception);
           break;
         }
-      if (LocaleCompare("emboss",argv[0]+1) == 0)
+      if (LocaleCompare("emboss",option+1) == 0)
         {
-          /*
-            Gaussian embossen image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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=EmbossImage(*image,geometry_info.rho,
-            geometry_info.sigma,exception);
+          new_image=EmbossImage(_image,geometry_info.rho,
+            geometry_info.sigma,_exception);
           break;
         }
-      if (LocaleCompare("encipher",argv[0]+1) == 0)
+      if (LocaleCompare("encipher",option+1) == 0)
         {
           StringInfo
             *passkey;
 
-          /*
-            Encipher pixels.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          passkey=FileToStringInfo(argv[1],~0,exception);
+          passkey=FileToStringInfo(arg1,~0,_exception);
           if (passkey != (StringInfo *) NULL)
             {
-              (void) PasskeyEncipherImage(*image,passkey,exception);
+              (void) PasskeyEncipherImage(_image,passkey,_exception);
               passkey=DestroyStringInfo(passkey);
             }
           break;
         }
-      if (LocaleCompare("encoding",argv[0]+1) == 0)
-        {
-          (void) CloneString(&draw_info->encoding,argv[1]);
-          break;
-        }
-      if (LocaleCompare("enhance",argv[0]+1) == 0)
+      if (LocaleCompare("enhance",option+1) == 0)
         {
-          /*
-            Enhance image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=EnhanceImage(*image,exception);
+          new_image=EnhanceImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("equalize",argv[0]+1) == 0)
+      if (LocaleCompare("equalize",option+1) == 0)
         {
-          /*
-            Equalize image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) EqualizeImage(*image,exception);
+          (void) EqualizeImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("evaluate",argv[0]+1) == 0)
+      if (LocaleCompare("evaluate",option+1) == 0)
         {
           double
             constant;
 
-          MagickEvaluateOperator
-            op;
-
-          (void) SyncImageSettings(image_info,*image);
-          op=(MagickEvaluateOperator) ParseCommandOption(
-            MagickEvaluateOptions,MagickFalse,argv[1]);
-          constant=SiPrefixToDouble(argv[2],QuantumRange);
-          (void) EvaluateImage(*image,op,constant,exception);
+          parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
+                 option,arg1);
+          if (IfMagickFalse(IsGeometry(arg2)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
+          constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
+          (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
+               _exception);
           break;
         }
-      if (LocaleCompare("extent",argv[0]+1) == 0)
+      if (LocaleCompare("extent",option+1) == 0)
         {
-          /*
-            Set the image extent.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGravityGeometry(*image,argv[1],&geometry,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
           if (geometry.width == 0)
-            geometry.width=(*image)->columns;
+            geometry.width=_image->columns;
           if (geometry.height == 0)
-            geometry.height=(*image)->rows;
-          new_image=ExtentImage(*image,&geometry,exception);
+            geometry.height=_image->rows;
+          new_image=ExtentImage(_image,&geometry,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'f':
     {
-      if (LocaleCompare("family",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            {
-              if (draw_info->family != (char *) NULL)
-                draw_info->family=DestroyString(draw_info->family);
-              break;
-            }
-          (void) CloneString(&draw_info->family,argv[1]);
-          break;
-        }
-      if (LocaleCompare("features",argv[0]+1) == 0)
+      if (LocaleCompare("features",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) DeleteImageArtifact(*image,"identify:features");
-              break;
-            }
-          (void) SetImageArtifact(*image,"identify:features",argv[1]);
-          break;
-        }
-      if (LocaleCompare("fill",argv[0]+1) == 0)
-        {
-          ExceptionInfo
-            *sans;
-
-          GetPixelInfo(*image,&fill);
-          if (*argv[0] == '+')
-            {
-              (void) QueryMagickColorCompliance("none",AllCompliance,&fill,
-                exception);
-              (void) QueryColorCompliance("none",AllComplience,&draw_info->fill,
-                exception);
-              if (draw_info->fill_pattern != (Image *) NULL)
-                draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
+          /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
+          if (IfPlusOp) {
+              (void) DeleteImageArtifact(_image,"identify:features");
               break;
             }
-          sans=AcquireExceptionInfo();
-          (void) QueryMagickColorCompliance(argv[1],AllCompliance,&fill,sans);
-          status=QueryColorCompliance(argv[1],AllComplience,&draw_info->fill,sans);
-          sans=DestroyExceptionInfo(sans);
-          if (status == MagickFalse)
-            draw_info->fill_pattern=GetImageCache(image_info,argv[1],
-              exception);
+          (void) SetImageArtifact(_image,"identify:features","true");
+          (void) SetImageArtifact(_image,"verbose","true");
           break;
         }
-      if (LocaleCompare("flip",argv[0]+1) == 0)
+      if (LocaleCompare("flip",option+1) == 0)
         {
-          /*
-            Flip image scanlines.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=FlipImage(*image,exception);
+          new_image=FlipImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("flop",argv[0]+1) == 0)
+      if (LocaleCompare("flop",option+1) == 0)
         {
-          /*
-            Flop image scanlines.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=FlopImage(*image,exception);
+          new_image=FlopImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("floodfill",argv[0]+1) == 0)
+      if (LocaleCompare("floodfill",option+1) == 0)
         {
           PixelInfo
             target;
 
-          /*
-            Floodfill image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
-          (void) QueryMagickColorCompliance(argv[2],AllCompliance,&target,
-                        exception);
-          (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
-            geometry.y,*argv[0] == '-' ? MagickFalse : MagickTrue,exception);
-          break;
-        }
-      if (LocaleCompare("font",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            {
-              if (draw_info->font != (char *) NULL)
-                draw_info->font=DestroyString(draw_info->font);
-              break;
-            }
-          (void) CloneString(&draw_info->font,argv[1]);
-          break;
-        }
-      if (LocaleCompare("format",argv[0]+1) == 0)
-        {
-          format=argv[1];
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (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);
           break;
         }
-      if (LocaleCompare("frame",argv[0]+1) == 0)
+      if (LocaleCompare("frame",option+1) == 0)
         {
           FrameInfo
             frame_info;
 
-          /*
-            Surround image with an ornamental border.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
+          CompositeOperator
+            compose;
+
+          const char*
+            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 (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)
@@ -2521,12 +2373,12 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           frame_info.inner_bevel=geometry.y;
           frame_info.x=(ssize_t) frame_info.width;
           frame_info.y=(ssize_t) frame_info.height;
-          frame_info.width=(*image)->columns+2*frame_info.width;
-          frame_info.height=(*image)->rows+2*frame_info.height;
-          new_image=FrameImage(*image,&frame_info,compose,exception);
+          frame_info.width=_image->columns+2*frame_info.width;
+          frame_info.height=_image->rows+2*frame_info.height;
+          new_image=FrameImage(_image,&frame_info,compose,_exception);
           break;
         }
-      if (LocaleCompare("function",argv[0]+1) == 0)
+      if (LocaleCompare("function",option+1) == 0)
         {
           char
             *arguments,
@@ -2538,9 +2390,6 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           double
             *parameters;
 
-          MagickFunction
-            function;
-
           register ssize_t
             x;
 
@@ -2549,14 +2398,16 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
 
           /*
             Function Modify Image Values
+            FUTURE: code should be almost a duplicate of that is "distort"
           */
-          (void) SyncImageSettings(image_info,*image);
-          function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
-            MagickFalse,argv[1]);
-          arguments=InterpretImageProperties(image_info,*image,argv[2],
-            exception);
+          parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
+                 option,arg1);
+          arguments=InterpretImageProperties(_image_info,_image,arg2,
+            _exception);
           if (arguments == (char *) NULL)
-            break;
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
           p=(char *) arguments;
           for (x=0; *p != '\0'; x++)
           {
@@ -2569,188 +2420,144 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
             sizeof(*parameters));
           if (parameters == (double *) NULL)
             ThrowWandFatalException(ResourceLimitFatalError,
-              "MemoryAllocationFailed",(*image)->filename);
+              "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++)
-          {
+          for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++) {
             GetMagickToken(p,&p,token);
             if (*token == ',')
               GetMagickToken(p,&p,token);
-            parameters[x]=InterpretLocaleValue(token,(char **) NULL);
+            parameters[x]=StringToDouble(token,(char **) NULL);
           }
           arguments=DestroyString(arguments);
-          (void) FunctionImage(*image,function,number_parameters,parameters,
-            exception);
+          (void) FunctionImage(_image,(MagickFunction)parse,number_parameters,
+                  parameters,_exception);
           parameters=(double *) RelinquishMagickMemory(parameters);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'g':
     {
-      if (LocaleCompare("gamma",argv[0]+1) == 0)
+      if (LocaleCompare("gamma",option+1) == 0)
         {
-          /*
-            Gamma image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            (*image)->gamma=InterpretLocaleValue(argv[1],(char **) NULL);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          if (IfNormalOp)
+            (void) GammaImage(_image,StringToDouble(arg1,(char **) NULL),
+                 _exception);
           else
-            (void) GammaImage(*image,InterpretLocaleValue(argv[1],
-              (char **) NULL),exception);
+            _image->gamma=StringToDouble(arg1,(char **) NULL);
           break;
         }
-      if ((LocaleCompare("gaussian-blur",argv[0]+1) == 0) ||
-          (LocaleCompare("gaussian",argv[0]+1) == 0))
+      if ((LocaleCompare("gaussian-blur",option+1) == 0) ||
+          (LocaleCompare("gaussian",option+1) == 0))
         {
-          /*
-            Gaussian blur image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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 & XiValue) == 0)
-            geometry_info.xi=0.0;
-          new_image=GaussianBlurImage(*image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,exception);
+          new_image=GaussianBlurImage(_image,geometry_info.rho,
+            geometry_info.sigma,_exception);
           break;
         }
-      if (LocaleCompare("geometry",argv[0]+1) == 0)
+      if (LocaleCompare("geometry",option+1) == 0)
         {
-            /*
-              Record Image offset, Resize last image.
-            */
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            {
-              if ((*image)->geometry != (char *) NULL)
-                (*image)->geometry=DestroyString((*image)->geometry);
+          /*
+            Record Image offset for composition. (A Setting)
+            Resize last _image. (ListOperator)  -- DEPRECIATE
+            FUTURE: Why if no 'offset' does this resize ALL images?
+            Also why is the setting recorded in the IMAGE non-sense!
+          */
+          if (IfPlusOp)
+            { /* remove the previous composition geometry offset! */
+              if (_image->geometry != (char *) NULL)
+                _image->geometry=DestroyString(_image->geometry);
               break;
             }
-          flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
           if (((flags & XValue) != 0) || ((flags & YValue) != 0))
-            (void) CloneString(&(*image)->geometry,argv[1]);
+            (void) CloneString(&_image->geometry,arg1);
           else
-            new_image=ResizeImage(*image,geometry.width,geometry.height,
-              (*image)->filter,(*image)->blur,exception);
-          break;
-        }
-      if (LocaleCompare("gravity",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            {
-              draw_info->gravity=UndefinedGravity;
-              break;
-            }
-          draw_info->gravity=(GravityType) ParseCommandOption(
-            MagickGravityOptions,MagickFalse,argv[1]);
+            new_image=ResizeImage(_image,geometry.width,geometry.height,
+              _image->filter,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'h':
     {
-      if (LocaleCompare("highlight-color",argv[0]+1) == 0)
+      if (LocaleCompare("highlight-color",option+1) == 0)
         {
-          (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
+          (void) SetImageArtifact(_image,option+1,arg1);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'i':
     {
-      if (LocaleCompare("identify",argv[0]+1) == 0)
+      if (LocaleCompare("identify",option+1) == 0)
         {
-          char
+          const char
+            *format,
             *text;
 
-          (void) SyncImageSettings(image_info,*image);
+          format=GetImageOption(_image_info,"format");
           if (format == (char *) NULL)
             {
-              (void) IdentifyImage(*image,stdout,image_info->verbose,
-                exception);
+              (void) IdentifyImage(_image,stdout,_image_info->verbose,
+                _exception);
               break;
             }
-          text=InterpretImageProperties(image_info,*image,format,
-            exception);
+          text=InterpretImageProperties(_image_info,_image,format,_exception);
           if (text == (char *) NULL)
             break;
           (void) fputs(text,stdout);
           (void) fputc('\n',stdout);
-          text=DestroyString(text);
-          break;
-        }
-      if (LocaleCompare("implode",argv[0]+1) == 0)
-        {
-          /*
-            Implode image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParseGeometry(argv[1],&geometry_info);
-          new_image=ImplodeImage(*image,geometry_info.rho,
-            interpolate_method,exception);
+          text=DestroyString((char *)text);
           break;
         }
-      if (LocaleCompare("interline-spacing",argv[0]+1) == 0)
+      if (LocaleCompare("implode",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            (void) ParseGeometry("0",&geometry_info);
-          else
-            (void) ParseGeometry(argv[1],&geometry_info);
-          draw_info->interline_spacing=geometry_info.rho;
-          break;
-        }
-      if (LocaleCompare("interpolate",argv[0]+1) == 0)
-        {
-          interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
-            MagickInterpolateOptions,MagickFalse,argv[1]);
-          break;
-        }
-      if (LocaleCompare("interword-spacing",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            (void) ParseGeometry("0",&geometry_info);
-          else
-            (void) ParseGeometry(argv[1],&geometry_info);
-          draw_info->interword_spacing=geometry_info.rho;
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseGeometry(arg1,&geometry_info);
+          new_image=ImplodeImage(_image,geometry_info.rho,
+            _image->interpolate,_exception);
           break;
         }
-      break;
-    }
-    case 'k':
-    {
-      if (LocaleCompare("kerning",argv[0]+1) == 0)
+      if (LocaleCompare("interpolative-resize",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            (void) ParseGeometry("0",&geometry_info);
-          else
-            (void) ParseGeometry(argv[1],&geometry_info);
-          draw_info->kerning=geometry_info.rho;
+          /* FUTURE: New to IMv7
+               Roll into a resize special operator */
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
+          new_image=InterpolativeResizeImage(_image,geometry.width,
+               geometry.height,_image->interpolate,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'l':
     {
-      if (LocaleCompare("lat",argv[0]+1) == 0)
+      if (LocaleCompare("lat",option+1) == 0)
         {
-          /*
-            Local adaptive threshold image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & PercentValue) != 0)
             geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
-          new_image=AdaptiveThresholdImage(*image,(size_t)
-            geometry_info.rho,(size_t) geometry_info.sigma,(double)
-            geometry_info.xi,exception);
+          new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
+               (size_t) geometry_info.sigma,(double) geometry_info.xi,
+               _exception);
           break;
         }
-      if (LocaleCompare("level",argv[0]+1) == 0)
+      if (LocaleCompare("level",option+1) == 0)
         {
           MagickRealType
             black_point,
@@ -2760,11 +2567,9 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           MagickStatusType
             flags;
 
-          /*
-            Parse levels.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
           black_point=geometry_info.rho;
           white_point=(MagickRealType) QuantumRange;
           if ((flags & SigmaValue) != 0)
@@ -2779,16 +2584,13 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
             }
           if ((flags & SigmaValue) == 0)
             white_point=(MagickRealType) QuantumRange-black_point;
-          if ((*argv[0] == '+') || ((flags & AspectValue) != 0))
-            (void) LevelizeImage(*image,black_point,white_point,gamma,
-              exception);
+          if (IfPlusOp || ((flags & AspectValue) != 0))
+            (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
           else
-            (void) LevelImage(*image,black_point,white_point,gamma,
-              exception);
-          InheritException(exception,&(*image)->exception);
+            (void) LevelImage(_image,black_point,white_point,gamma,_exception);
           break;
         }
-      if (LocaleCompare("level-colors",argv[0]+1) == 0)
+      if (LocaleCompare("level-colors",option+1) == 0)
         {
           char
             token[MaxTextExtent];
@@ -2800,14 +2602,14 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
             black_point,
             white_point;
 
-          p=(const char *) argv[1];
+          p=(const char *) arg1;
           GetMagickToken(p,&p,token);  /* get black point color */
           if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
-            (void) QueryMagickColorCompliance(token,AllCompliance,
-                      &black_point,exception);
+            (void) QueryColorCompliance(token,AllCompliance,
+                      &black_point,_exception);
           else
-            (void) QueryMagickColorCompliance("#000000",AllCompliance,
-                      &black_point,exception);
+            (void) QueryColorCompliance("#000000",AllCompliance,
+                      &black_point,_exception);
           if (isalpha((int) token[0]) || (token[0] == '#'))
             GetMagickToken(p,&p,token);
           if (*token == '\0')
@@ -2817,17 +2619,17 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
               if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
                 GetMagickToken(p,&p,token); /* Get white point color. */
               if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
-                (void) QueryMagickColorCompliance(token,AllCompliance,
-                           &white_point,exception);
+                (void) QueryColorCompliance(token,AllCompliance,
+                           &white_point,_exception);
               else
-                (void) QueryMagickColorCompliance("#ffffff",AllCompliance,
-                           &white_point,exception);
+                (void) QueryColorCompliance("#ffffff",AllCompliance,
+                           &white_point,_exception);
             }
-          (void) LevelImageColors(*image,&black_point,&white_point,
-            *argv[0] == '+' ? MagickTrue : MagickFalse,exception);
+          (void) LevelImageColors(_image,&black_point,&white_point,
+                     plus_alt_op,_exception);
           break;
         }
-      if (LocaleCompare("linear-stretch",argv[0]+1) == 0)
+      if (LocaleCompare("linear-stretch",option+1) == 0)
         {
           double
             black_point,
@@ -2836,153 +2638,123 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           MagickStatusType
             flags;
 
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
           black_point=geometry_info.rho;
-          white_point=(MagickRealType) (*image)->columns*(*image)->rows;
+          white_point=(MagickRealType) _image->columns*_image->rows;
           if ((flags & SigmaValue) != 0)
             white_point=geometry_info.sigma;
           if ((flags & PercentValue) != 0)
             {
-              black_point*=(double) (*image)->columns*(*image)->rows/100.0;
-              white_point*=(double) (*image)->columns*(*image)->rows/100.0;
+              black_point*=(double) _image->columns*_image->rows/100.0;
+              white_point*=(double) _image->columns*_image->rows/100.0;
             }
           if ((flags & SigmaValue) == 0)
-            white_point=(MagickRealType) (*image)->columns*(*image)->rows-
+            white_point=(MagickRealType) _image->columns*_image->rows-
               black_point;
-          (void) LinearStretchImage(*image,black_point,white_point,exception);
-          InheritException(exception,&(*image)->exception);
-          break;
-        }
-      if (LocaleCompare("linewidth",argv[0]+1) == 0)
-        {
-          draw_info->stroke_width=InterpretLocaleValue(argv[1],
-            (char **) NULL);
+          (void) LinearStretchImage(_image,black_point,white_point,_exception);
           break;
         }
-      if (LocaleCompare("liquid-rescale",argv[0]+1) == 0)
+      if (LocaleCompare("liquid-rescale",option+1) == 0)
         {
-          /*
-            Liquid rescale image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseRegionGeometry(*image,argv[1],&geometry,exception);
+          /* FUTURE: Roll into a resize special operator */
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
           if ((flags & XValue) == 0)
             geometry.x=1;
           if ((flags & YValue) == 0)
             geometry.y=0;
-          new_image=LiquidRescaleImage(*image,geometry.width,
-            geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
+          new_image=LiquidRescaleImage(_image,geometry.width,
+            geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
           break;
         }
-      if (LocaleCompare("lowlight-color",argv[0]+1) == 0)
+      if (LocaleCompare("lowlight-color",option+1) == 0)
         {
-          (void) SetImageArtifact(*image,argv[0]+1,argv[1]);
+          (void) SetImageArtifact(_image,option+1,arg1);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'm':
     {
-      if (LocaleCompare("map",argv[0]+1) == 0)
+      if (LocaleCompare("map",option+1) == 0)
         {
           Image
             *remap_image;
 
-          /*
-            Transform image colors to match this set of colors.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            break;
-          remap_image=GetImageCache(image_info,argv[1],exception);
+          /* DEPRECIATED use -remap */
+          remap_image=GetImageCache(_image_info,arg1,_exception);
           if (remap_image == (Image *) NULL)
             break;
-          (void) RemapImage(quantize_info,*image,remap_image,exception);
+          (void) RemapImage(_quantize_info,_image,remap_image,_exception);
           remap_image=DestroyImage(remap_image);
           break;
         }
-      if (LocaleCompare("mask",argv[0]+1) == 0)
+      if (LocaleCompare("mask",option+1) == 0)
         {
           Image
             *mask;
 
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            {
-              /*
-                Remove a mask.
-              */
-              (void) SetImageMask(*image,(Image *) NULL,exception);
+          if (IfPlusOp)
+            { /* Remove a mask. */
+              (void) SetImageMask(_image,(Image *) NULL,_exception);
               break;
             }
-          /*
-            Set the image mask.
-          */
-          mask=GetImageCache(image_info,argv[1],exception);
+          /* Set the image mask. */
+          mask=GetImageCache(_image_info,arg1,_exception);
           if (mask == (Image *) NULL)
             break;
-          (void) SetImageMask(*image,mask,exception);
+          (void) SetImageMask(_image,mask,_exception);
           mask=DestroyImage(mask);
           break;
         }
-      if (LocaleCompare("matte",argv[0]+1) == 0)
+      if (LocaleCompare("matte",option+1) == 0)
         {
-          (void) SetImageAlphaChannel(*image,(*argv[0] == '-') ?
-            SetAlphaChannel : DeactivateAlphaChannel,exception);
+          /* DEPRECIATED */
+          (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
+                         DeactivateAlphaChannel, _exception);
           break;
         }
-      if (LocaleCompare("median",argv[0]+1) == 0)
+      if (LocaleCompare("median",option+1) == 0)
         {
-          /*
-            Median filter image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
-          if ((flags & SigmaValue) == 0)
-            geometry_info.sigma=geometry_info.rho;
-          new_image=StatisticImage(*image,MedianStatistic,(size_t)
-            geometry_info.rho,(size_t) geometry_info.sigma,exception);
+          /* DEPRECIATED - use -statistic Median */
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1);
           break;
         }
-      if (LocaleCompare("mode",argv[0]+1) == 0)
+      if (LocaleCompare("mode",option+1) == 0)
         {
-          /*
-            Mode image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=geometry_info.rho;
-          new_image=StatisticImage(*image,ModeStatistic,(size_t)
-            geometry_info.rho,(size_t) geometry_info.sigma,exception);
+          new_image=StatisticImage(_image,ModeStatistic,(size_t)
+            geometry_info.rho,(size_t) geometry_info.sigma,_exception);
           break;
         }
-      if (LocaleCompare("modulate",argv[0]+1) == 0)
+      if (LocaleCompare("modulate",option+1) == 0)
         {
-          (void) SyncImageSettings(image_info,*image);
-          (void) ModulateImage(*image,argv[1],exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ModulateImage(_image,arg1,_exception);
           break;
         }
-      if (LocaleCompare("monitor",argv[0]+1) == 0)
+      if (LocaleCompare("monitor",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageProgressMonitor(*image,
+          (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
                 (MagickProgressMonitor) NULL,(void *) NULL);
-              break;
-            }
-          (void) SetImageProgressMonitor(*image,MonitorProgress,
-            (void *) NULL);
           break;
         }
-      if (LocaleCompare("monochrome",argv[0]+1) == 0)
+      if (LocaleCompare("monochrome",option+1) == 0)
         {
-          (void) SyncImageSettings(image_info,*image);
-          (void) SetImageType(*image,BilevelType,exception);
+          (void) SetImageType(_image,BilevelType,_exception);
           break;
         }
-      if (LocaleCompare("morphology",argv[0]+1) == 0)
+      if (LocaleCompare("morphology",option+1) == 0)
         {
           char
             token[MaxTextExtent];
@@ -2993,200 +2765,170 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           KernelInfo
             *kernel;
 
-          MorphologyMethod
-            method;
-
           ssize_t
             iterations;
 
-          /*
-            Morphological Image Operation
-          */
-          (void) SyncImageSettings(image_info,*image);
-          p=argv[1];
+          p=arg1;
           GetMagickToken(p,&p,token);
-          method=(MorphologyMethod) ParseCommandOption(
-            MagickMorphologyOptions,MagickFalse,token);
+          parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
+                 option,arg1);
           iterations=1L;
           GetMagickToken(p,&p,token);
           if ((*p == ':') || (*p == ','))
             GetMagickToken(p,&p,token);
           if ((*p != '\0'))
             iterations=(ssize_t) StringToLong(p);
-          kernel=AcquireKernelInfo(argv[2]);
+          kernel=AcquireKernelInfo(arg2);
           if (kernel == (KernelInfo *) NULL)
-            {
-              (void) ThrowMagickException(exception,GetMagickModule(),
-                OptionError,"UnabletoParseKernel","morphology");
-              status=MagickFalse;
-              break;
-            }
-          new_image=MorphologyImage(*image,method,iterations,kernel,
-            exception);
+            CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",
+                 option,arg2);
+          new_image=MorphologyImage(_image,(MorphologyMethod)parse,
+               iterations,kernel,_exception);
           kernel=DestroyKernelInfo(kernel);
           break;
         }
-      if (LocaleCompare("motion-blur",argv[0]+1) == 0)
+      if (LocaleCompare("motion-blur",option+1) == 0)
         {
-          /*
-            Motion blur image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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=MotionBlurImage(*image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,geometry_info.psi,
-            exception);
+          new_image=MotionBlurImage(_image,geometry_info.rho,
+            geometry_info.sigma,geometry_info.xi,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'n':
     {
-      if (LocaleCompare("negate",argv[0]+1) == 0)
+      if (LocaleCompare("negate",option+1) == 0)
         {
-          (void) SyncImageSettings(image_info,*image);
-          (void) NegateImage(*image,*argv[0] == '+' ? MagickTrue :
-            MagickFalse,exception);
+          (void) NegateImage(_image, plus_alt_op, _exception);
           break;
         }
-      if (LocaleCompare("noise",argv[0]+1) == 0)
+      if (LocaleCompare("noise",option+1) == 0)
         {
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '-')
+          if (IfNormalOp)
             {
-              flags=ParseGeometry(argv[1],&geometry_info);
+              if (IfMagickFalse(IsGeometry(arg1)))
+                CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+              flags=ParseGeometry(arg1,&geometry_info);
               if ((flags & SigmaValue) == 0)
                 geometry_info.sigma=geometry_info.rho;
-              new_image=StatisticImage(*image,NonpeakStatistic,(size_t)
-                geometry_info.rho,(size_t) geometry_info.sigma,exception);
+              new_image=StatisticImage(_image,NonpeakStatistic,(size_t)
+                geometry_info.rho,(size_t) geometry_info.sigma,_exception);
             }
           else
             {
-              NoiseType
-                noise;
+              double
+                attenuate;
+
+              const char*
+                value;
+
+              parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
+              if ( parse < 0 )
+                CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
+                    option,arg1);
+              value=GetImageOption(_image_info,"attenuate");
+              if  (value != (const char *) NULL)
+                attenuate=StringToDouble(value,(char **) NULL);
+              else
+                attenuate=1.0;
 
-              noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
-                MagickFalse,argv[1]);
-              new_image=AddNoiseImage(*image,noise,exception);
+              new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
+                   _exception);
             }
           break;
         }
-      if (LocaleCompare("normalize",argv[0]+1) == 0)
+      if (LocaleCompare("normalize",option+1) == 0)
         {
-          (void) SyncImageSettings(image_info,*image);
-          (void) NormalizeImage(*image,exception);
+          (void) NormalizeImage(_image,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'o':
     {
-      if (LocaleCompare("opaque",argv[0]+1) == 0)
+      if (LocaleCompare("opaque",option+1) == 0)
         {
           PixelInfo
             target;
 
-          (void) SyncImageSettings(image_info,*image);
-          (void) QueryMagickColorCompliance(argv[1],AllCompliance,&target,
-                       exception);
-          (void) OpaquePaintImage(*image,&target,&fill,*argv[0] == '-' ?
-            MagickFalse : MagickTrue,exception);
+          (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
+          (void) OpaquePaintImage(_image,&target,&_draw_info->fill,plus_alt_op,
+               _exception);
           break;
         }
-      if (LocaleCompare("ordered-dither",argv[0]+1) == 0)
+      if (LocaleCompare("ordered-dither",option+1) == 0)
         {
-          (void) SyncImageSettings(image_info,*image);
-          (void) OrderedPosterizeImage(*image,argv[1],exception);
+          (void) OrderedPosterizeImage(_image,arg1,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'p':
     {
-      if (LocaleCompare("paint",argv[0]+1) == 0)
-        {
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParseGeometry(argv[1],&geometry_info);
-          new_image=OilPaintImage(*image,geometry_info.rho,
-            geometry_info.sigma,exception);
-          break;
-        }
-      if (LocaleCompare("pen",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            {
-              (void) QueryColorCompliance("none",AllComplience,&draw_info->fill,
-                 exception);
-              break;
-            }
-          (void) QueryColorCompliance(argv[1],AllComplience,&draw_info->fill,
-                 exception);
-          break;
-        }
-      if (LocaleCompare("pointsize",argv[0]+1) == 0)
+      if (LocaleCompare("paint",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            (void) ParseGeometry("12",&geometry_info);
-          else
-            (void) ParseGeometry(argv[1],&geometry_info);
-          draw_info->pointsize=geometry_info.rho;
+          (void) ParseGeometry(arg1,&geometry_info);
+          new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
+               _exception);
           break;
         }
-      if (LocaleCompare("polaroid",argv[0]+1) == 0)
+      if (LocaleCompare("polaroid",option+1) == 0)
         {
+          const char
+            *caption;
+
           double
             angle;
 
-          RandomInfo
+          if (IfPlusOp) {
+            RandomInfo
             *random_info;
 
-          /*
-            Simulate a Polaroid picture.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          random_info=AcquireRandomInfo();
-          angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
-          random_info=DestroyRandomInfo(random_info);
-          if (*argv[0] == '-')
-            {
-              SetGeometryInfo(&geometry_info);
-              flags=ParseGeometry(argv[1],&geometry_info);
-              angle=geometry_info.rho;
-            }
-          new_image=PolaroidImage(*image,draw_info,angle,
-            interpolate_method,exception);
+            random_info=AcquireRandomInfo();
+            angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
+            random_info=DestroyRandomInfo(random_info);
+          }
+          else {
+            if (IfMagickFalse(IsGeometry(arg1)))
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+            flags=ParseGeometry(arg1,&geometry_info);
+            angle=geometry_info.rho;
+          }
+          caption=GetImageProperty(_image,"caption",_exception);
+          new_image=PolaroidImage(_image,_draw_info,caption,angle,
+            _image->interpolate,_exception);
           break;
         }
-      if (LocaleCompare("posterize",argv[0]+1) == 0)
+      if (LocaleCompare("posterize",option+1) == 0)
         {
-          /*
-            Posterize image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) PosterizeImage(*image,StringToUnsignedLong(argv[1]),
-            quantize_info->dither,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseGeometry(arg1,&geometry_info);
+          (void) PosterizeImage(_image,(size_t) geometry_info.rho,
+               _quantize_info->dither,_exception);
           break;
         }
-      if (LocaleCompare("preview",argv[0]+1) == 0)
+      if (LocaleCompare("preview",option+1) == 0)
         {
-          PreviewType
-            preview_type;
-
-          /*
-            Preview image.
+          /* FUTURE: should be a 'Genesis' option?
+             Option however is also in WandSettingOptionInfo()
+             Why???
           */
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            preview_type=UndefinedPreview;
-          else
-            preview_type=(PreviewType) ParseCommandOption(
-              MagickPreviewOptions,MagickFalse,argv[1]);
-          new_image=PreviewImage(*image,preview_type,exception);
+          parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
+                option,arg1);
+          new_image=PreviewImage(_image,(PreviewType)parse,_exception);
           break;
         }
-      if (LocaleCompare("profile",argv[0]+1) == 0)
+      if (LocaleCompare("profile",option+1) == 0)
         {
           const char
             *name;
@@ -3200,40 +2942,33 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           ImageInfo
             *profile_info;
 
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            {
-              /*
-                Remove a profile from the image.
-              */
-              (void) ProfileImage(*image,argv[1],(const unsigned char *)
-                NULL,0,MagickTrue);
-              InheritException(exception,&(*image)->exception);
+          if (IfPlusOp)
+            { /* Remove a profile from the _image.  */
+              (void) ProfileImage(_image,arg1,(const unsigned char *)
+                NULL,0,_exception);
               break;
             }
-          /*
-            Associate a profile with the image.
-          */
-          profile_info=CloneImageInfo(image_info);
-          profile=GetImageProfile(*image,"iptc");
+          /* Associate a profile with the _image.  */
+          profile_info=CloneImageInfo(_image_info);
+          profile=GetImageProfile(_image,"iptc");
           if (profile != (StringInfo *) NULL)
             profile_info->profile=(void *) CloneStringInfo(profile);
-          profile_image=GetImageCache(profile_info,argv[1],exception);
+          profile_image=GetImageCache(profile_info,arg1,_exception);
           profile_info=DestroyImageInfo(profile_info);
           if (profile_image == (Image *) NULL)
             {
               StringInfo
                 *profile;
 
-              profile_info=CloneImageInfo(image_info);
-              (void) CopyMagickString(profile_info->filename,argv[1],
+              profile_info=CloneImageInfo(_image_info);
+              (void) CopyMagickString(profile_info->filename,arg1,
                 MaxTextExtent);
-              profile=FileToStringInfo(profile_info->filename,~0UL,exception);
+              profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
               if (profile != (StringInfo *) NULL)
                 {
-                  (void) ProfileImage(*image,profile_info->magick,
+                  (void) ProfileImage(_image,profile_info->magick,
                     GetStringInfoDatum(profile),(size_t)
-                    GetStringInfoLength(profile),MagickFalse);
+                    GetStringInfoLength(profile),_exception);
                   profile=DestroyStringInfo(profile);
                 }
               profile_info=DestroyImageInfo(profile_info);
@@ -3245,796 +2980,581 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
           {
             profile=GetImageProfile(profile_image,name);
             if (profile != (StringInfo *) NULL)
-              (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
-                (size_t) GetStringInfoLength(profile),MagickFalse);
-            name=GetNextImageProfile(profile_image);
-          }
-          profile_image=DestroyImage(profile_image);
-          break;
-        }
-      break;
-    }
-    case 'q':
-    {
-      if (LocaleCompare("quantize",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            {
-              quantize_info->colorspace=UndefinedColorspace;
-              break;
-            }
-          quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
-            MagickColorspaceOptions,MagickFalse,argv[1]);
+              (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
+                (size_t) GetStringInfoLength(profile),_exception);
+            name=GetNextImageProfile(profile_image);
+          }
+          profile_image=DestroyImage(profile_image);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'r':
     {
-      if (LocaleCompare("radial-blur",argv[0]+1) == 0)
+      if (LocaleCompare("radial-blur",option+1) == 0)
         {
-          /*
-            Radial blur image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
-          new_image=RadialBlurImage(*image,geometry_info.rho,
-            geometry_info.sigma,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
+          new_image=RadialBlurImage(_image,geometry_info.rho,_exception);
           break;
         }
-      if (LocaleCompare("raise",argv[0]+1) == 0)
+      if (LocaleCompare("raise",option+1) == 0)
         {
-          /*
-            Surround image with a raise of solid color.
-          */
-          flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
+          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,*argv[0] == '-' ? MagickTrue :
-            MagickFalse,exception);
-          break;
-        }
-      if (LocaleCompare("random-threshold",argv[0]+1) == 0)
-        {
-          /*
-            Threshold image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) RandomThresholdImage(*image,argv[1],exception);
-          break;
-        }
-      if (LocaleCompare("recolor",argv[0]+1) == 0)
-        {
-          KernelInfo
-            *kernel;
-
-          (void) SyncImageSettings(image_info,*image);
-          kernel=AcquireKernelInfo(argv[1]);
-          if (kernel == (KernelInfo *) NULL)
-            break;
-          new_image=ColorMatrixImage(*image,kernel,exception);
-          kernel=DestroyKernelInfo(kernel);
+          (void) RaiseImage(_image,&geometry,normal_op,_exception);
           break;
         }
-      if (LocaleCompare("render",argv[0]+1) == 0)
+      if (LocaleCompare("random-threshold",option+1) == 0)
         {
-          (void) SyncImageSettings(image_info,*image);
-          draw_info->render=(*argv[0] == '+') ? MagickTrue : MagickFalse;
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) RandomThresholdImage(_image,arg1,_exception);
           break;
         }
-      if (LocaleCompare("remap",argv[0]+1) == 0)
+      if (LocaleCompare("remap",option+1) == 0)
         {
           Image
             *remap_image;
 
-          /*
-            Transform image colors to match this set of colors.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            break;
-          remap_image=GetImageCache(image_info,argv[1],exception);
+          remap_image=GetImageCache(_image_info,arg1,_exception);
           if (remap_image == (Image *) NULL)
             break;
-          (void) RemapImage(quantize_info,*image,remap_image,exception);
+          (void) RemapImage(_quantize_info,_image,remap_image,_exception);
           remap_image=DestroyImage(remap_image);
           break;
         }
-      if (LocaleCompare("repage",argv[0]+1) == 0)
+      if (LocaleCompare("repage",option+1) == 0)
         {
-          if (*argv[0] == '+')
+          if (IfNormalOp)
             {
-              (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
-              break;
+              if (IfMagickFalse(IsGeometry(arg1)))
+                CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
+                  arg1);
+              (void) ResetImagePage(_image,arg1);
             }
-          (void) ResetImagePage(*image,argv[1]);
-          InheritException(exception,&(*image)->exception);
+          else
+            (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
           break;
         }
-      if (LocaleCompare("resample",argv[0]+1) == 0)
+      if (LocaleCompare("resample",option+1) == 0)
         {
-          /*
-            Resample image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          /* FUTURE: Roll into a resize special operation */
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=geometry_info.rho;
-          new_image=ResampleImage(*image,geometry_info.rho,
-            geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
+          new_image=ResampleImage(_image,geometry_info.rho,
+            geometry_info.sigma,_image->filter,_exception);
           break;
         }
-      if (LocaleCompare("resize",argv[0]+1) == 0)
+      if (LocaleCompare("resize",option+1) == 0)
         {
-          /*
-            Resize image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
-          new_image=ResizeImage(*image,geometry.width,geometry.height,
-            (*image)->filter,(*image)->blur,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
+          new_image=ResizeImage(_image,geometry.width,geometry.height,
+            _image->filter,_exception);
           break;
         }
-      if (LocaleCompare("roll",argv[0]+1) == 0)
+      if (LocaleCompare("roll",option+1) == 0)
         {
-          /*
-            Roll image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParsePageGeometry(*image,argv[1],&geometry,exception);
-          new_image=RollImage(*image,geometry.x,geometry.y,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
+          new_image=RollImage(_image,geometry.x,geometry.y,_exception);
           break;
         }
-      if (LocaleCompare("rotate",argv[0]+1) == 0)
+      if (LocaleCompare("rotate",option+1) == 0)
         {
-          char
-            *geometry;
-
-          /*
-            Check for conditional image rotation.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          if (strchr(argv[1],'>') != (char *) NULL)
-            if ((*image)->columns <= (*image)->rows)
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          if (strchr(arg1,'>') != (char *) NULL)
+            if (_image->columns <= _image->rows)
               break;
-          if (strchr(argv[1],'<') != (char *) NULL)
-            if ((*image)->columns >= (*image)->rows)
+          if (strchr(arg1,'<') != (char *) NULL)
+            if (_image->columns >= _image->rows)
               break;
-          /*
-            Rotate image.
-          */
-          geometry=ConstantString(argv[1]);
-          (void) SubstituteString(&geometry,">","");
-          (void) SubstituteString(&geometry,"<","");
-          (void) ParseGeometry(geometry,&geometry_info);
-          geometry=DestroyString(geometry);
-          new_image=RotateImage(*image,geometry_info.rho,exception);
+          (void) ParseGeometry(arg1,&geometry_info);
+          new_image=RotateImage(_image,geometry_info.rho,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 's':
     {
-      if (LocaleCompare("sample",argv[0]+1) == 0)
+      if (LocaleCompare("sample",option+1) == 0)
         {
-          /*
-            Sample image with pixel replication.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
-          new_image=SampleImage(*image,geometry.width,geometry.height,
-            exception);
+          /* FUTURE: Roll into a resize special operator */
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
+          new_image=SampleImage(_image,geometry.width,geometry.height,
+            _exception);
           break;
         }
-      if (LocaleCompare("scale",argv[0]+1) == 0)
+      if (LocaleCompare("scale",option+1) == 0)
         {
-          /*
-            Resize image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
-          new_image=ScaleImage(*image,geometry.width,geometry.height,
-            exception);
+          /* FUTURE: Roll into a resize special operator */
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
+          new_image=ScaleImage(_image,geometry.width,geometry.height,
+            _exception);
           break;
         }
-      if (LocaleCompare("selective-blur",argv[0]+1) == 0)
+      if (LocaleCompare("segment",option+1) == 0)
         {
-          /*
-            Selectively blur pixels within a contrast threshold.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
-          if ((flags & PercentValue) != 0)
-            geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
-          new_image=SelectiveBlurImage(*image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & SigmaValue) == 0)
+            geometry_info.sigma=1.0;
+          (void) SegmentImage(_image,_image->colorspace,
+            _image_info->verbose,geometry_info.rho,geometry_info.sigma,
+            _exception);
           break;
         }
-      if (LocaleCompare("separate",argv[0]+1) == 0)
+      if (LocaleCompare("selective-blur",option+1) == 0)
         {
-          /*
-            Break channels into separate images.
-            WARNING: This can generate multiple images!
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=SeparateImages(*image,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & PercentValue) != 0)
+            geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
+          new_image=SelectiveBlurImage(_image,geometry_info.rho,
+            geometry_info.sigma,geometry_info.xi,_exception);
           break;
         }
-      if (LocaleCompare("sepia-tone",argv[0]+1) == 0)
+      if (LocaleCompare("separate",option+1) == 0)
         {
-          double
-            threshold;
-
-          /*
-            Sepia-tone image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          threshold=SiPrefixToDouble(argv[1],QuantumRange);
-          new_image=SepiaToneImage(*image,threshold,exception);
+          /* WARNING: This can generate multiple images! */
+          /* FUTURE - this may be replaced by a "-channel" method */
+          new_image=SeparateImages(_image,_exception);
           break;
         }
-      if (LocaleCompare("segment",argv[0]+1) == 0)
+      if (LocaleCompare("sepia-tone",option+1) == 0)
         {
-          /*
-            Segment image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
-          if ((flags & SigmaValue) == 0)
-            geometry_info.sigma=1.0;
-          (void) SegmentImage(*image,(*image)->colorspace,
-            image_info->verbose,geometry_info.rho,geometry_info.sigma,
-            exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
+                 (double) QuantumRange+1.0),_exception);
           break;
         }
-      if (LocaleCompare("set",argv[0]+1) == 0)
+      if (LocaleCompare("set",option+1) == 0)
         {
           char
             *value;
 
-          if (*argv[0] == '+')
-            {
-              if (LocaleNCompare(argv[1],"registry:",9) == 0)
-                (void) DeleteImageRegistry(argv[1]+9);
+          if (IfPlusOp) {
+              if (LocaleNCompare(arg1,"registry:",9) == 0)
+                (void) DeleteImageRegistry(arg1+9);
               else
-                if (LocaleNCompare(argv[1],"argv[0]:",7) == 0)
+                if (LocaleNCompare(arg1,"option:",7) == 0)
                   {
-                    (void) DeleteImageOption(image_info,argv[1]+7);
-                    (void) DeleteImageArtifact(*image,argv[1]+7);
+                    (void) DeleteImageOption(_image_info,arg1+7);
+                    (void) DeleteImageArtifact(_image,arg1+7);
                   }
                 else
-                  (void) DeleteImageProperty(*image,argv[1]);
+                  (void) DeleteImageProperty(_image,arg1);
               break;
             }
-          value=InterpretImageProperties(image_info,*image,argv[2],
-            exception);
+          value=InterpretImageProperties(_image_info,_image,arg2,_exception);
           if (value == (char *) NULL)
             break;
-          if (LocaleNCompare(argv[1],"registry:",9) == 0)
-            (void) SetImageRegistry(StringRegistryType,argv[1]+9,value,
-              exception);
+          if (LocaleNCompare(arg1,"registry:",9) == 0)
+            (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
           else
-            if (LocaleNCompare(argv[1],"option:",7) == 0)
+            if (LocaleNCompare(arg1,"option:",7) == 0)
               {
-                (void) SetImageOption(image_info,argv[1]+7,value);
-                (void) SetImageArtifact(*image,argv[1]+7,value);
+                (void) SetImageOption(_image_info,arg1+7,value);
+                (void) SetImageArtifact(_image,arg1+7,value);
               }
             else
-              (void) SetImageProperty(*image,argv[1],value);
+              (void) SetImageProperty(_image,arg1,value,_exception);
           value=DestroyString(value);
           break;
         }
-      if (LocaleCompare("shade",argv[0]+1) == 0)
+      if (LocaleCompare("shade",option+1) == 0)
         {
-          /*
-            Shade image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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=ShadeImage(*image,(*argv[0] == '-') ? MagickTrue :
-            MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
+          new_image=ShadeImage(_image,normal_op,geometry_info.rho,
+               geometry_info.sigma,_exception);
           break;
         }
-      if (LocaleCompare("shadow",argv[0]+1) == 0)
+      if (LocaleCompare("shadow",option+1) == 0)
         {
-          /*
-            Shadow image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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 & XiValue) == 0)
             geometry_info.xi=4.0;
           if ((flags & PsiValue) == 0)
             geometry_info.psi=4.0;
-          new_image=ShadowImage(*image,geometry_info.rho,
-            geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
-            ceil(geometry_info.psi-0.5),exception);
+          new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
+            (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
+            ceil(geometry_info.psi-0.5),_exception);
           break;
         }
-      if (LocaleCompare("sharpen",argv[0]+1) == 0)
+      if (LocaleCompare("sharpen",option+1) == 0)
         {
-          /*
-            Sharpen image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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 & XiValue) == 0)
             geometry_info.xi=0.0;
-          new_image=SharpenImage(*image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,exception);
+          new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
+           _exception);
           break;
         }
-      if (LocaleCompare("shave",argv[0]+1) == 0)
+      if (LocaleCompare("shave",option+1) == 0)
         {
-          /*
-            Shave the image edges.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParsePageGeometry(*image,argv[1],&geometry,exception);
-          new_image=ShaveImage(*image,&geometry,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
+          new_image=ShaveImage(_image,&geometry,_exception);
           break;
         }
-      if (LocaleCompare("shear",argv[0]+1) == 0)
+      if (LocaleCompare("shear",option+1) == 0)
         {
-          /*
-            Shear image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
           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",argv[0]+1) == 0)
+      if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
         {
-          /*
-            Sigmoidal non-linearity contrast control.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
           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,(*argv[0] == '-') ?
-            MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
-            exception);
+          (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
+               geometry_info.sigma,
+            _exception);
           break;
         }
-      if (LocaleCompare("sketch",argv[0]+1) == 0)
+      if (LocaleCompare("sketch",option+1) == 0)
         {
-          /*
-            Sketch image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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=SketchImage(*image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
+          new_image=SketchImage(_image,geometry_info.rho,
+            geometry_info.sigma,geometry_info.xi,_exception);
           break;
         }
-      if (LocaleCompare("solarize",argv[0]+1) == 0)
+      if (LocaleCompare("solarize",option+1) == 0)
         {
-          double
-            threshold;
-
-          (void) SyncImageSettings(image_info,*image);
-          threshold=SiPrefixToDouble(argv[1],QuantumRange);
-          (void) SolarizeImage(*image,threshold,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
+                 QuantumRange+1.0),_exception);
           break;
         }
-      if (LocaleCompare("sparse-color",argv[0]+1) == 0)
+      if (LocaleCompare("sparse-color",option+1) == 0)
         {
-          SparseColorMethod
-            method;
-
           char
             *arguments;
 
-          /*
-            Sparse Color Interpolated Gradient
-          */
-          (void) SyncImageSettings(image_info,*image);
-          method=(SparseColorMethod) ParseCommandOption(
-            MagickSparseColorOptions,MagickFalse,argv[1]);
-          arguments=InterpretImageProperties(image_info,*image,argv[2],
-            exception);
+          parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
+                option,arg1);
+          arguments=InterpretImageProperties(_image_info,_image,arg2,_exception);
           if (arguments == (char *) NULL)
-            break;
-          new_image=SparseColorOption(*image,method,arguments,
-            argv[0][0] == '+' ? MagickTrue : MagickFalse,exception);
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
+          new_image=SparseColorOption(_image,(SparseColorMethod)parse,
+               arguments,_exception);
           arguments=DestroyString(arguments);
           break;
         }
-      if (LocaleCompare("splice",argv[0]+1) == 0)
-        {
-          /*
-            Splice a solid color into the image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParseGravityGeometry(*image,argv[1],&geometry,exception);
-          new_image=SpliceImage(*image,&geometry,exception);
-          break;
-        }
-      if (LocaleCompare("spread",argv[0]+1) == 0)
-        {
-          /*
-            Spread an image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParseGeometry(argv[1],&geometry_info);
-          new_image=SpreadImage(*image,geometry_info.rho,
-            interpolate_method,exception);
-          break;
-        }
-      if (LocaleCompare("statistic",argv[0]+1) == 0)
-        {
-          StatisticType
-            type;
-
-          (void) SyncImageSettings(image_info,*image);
-          type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
-            MagickFalse,argv[1]);
-          (void) ParseGeometry(argv[2],&geometry_info);
-          new_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
-            (size_t) geometry_info.sigma,exception);
-          break;
-        }
-      if (LocaleCompare("stretch",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            {
-              draw_info->stretch=UndefinedStretch;
-              break;
-            }
-          draw_info->stretch=(StretchType) ParseCommandOption(
-            MagickStretchOptions,MagickFalse,argv[1]);
-          break;
-        }
-      if (LocaleCompare("strip",argv[0]+1) == 0)
+      if (LocaleCompare("splice",option+1) == 0)
         {
-          /*
-            Strip image of profiles and comments.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) StripImage(*image);
-          InheritException(exception,&(*image)->exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
+          new_image=SpliceImage(_image,&geometry,_exception);
           break;
         }
-      if (LocaleCompare("stroke",argv[0]+1) == 0)
+      if (LocaleCompare("spread",option+1) == 0)
         {
-          ExceptionInfo
-            *sans;
-
-          if (*argv[0] == '+')
-            {
-              (void) QueryColorCompliance("none",AllComplience,&draw_info->stroke,
-                exception);
-              if (draw_info->stroke_pattern != (Image *) NULL)
-                draw_info->stroke_pattern=DestroyImage(
-                  draw_info->stroke_pattern);
-              break;
-            }
-          sans=AcquireExceptionInfo();
-          status=QueryColorCompliance(argv[1],AllComplience,&draw_info->stroke,sans);
-          sans=DestroyExceptionInfo(sans);
-          if (status == MagickFalse)
-            draw_info->stroke_pattern=GetImageCache(image_info,argv[1],
-              exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseGeometry(arg1,&geometry_info);
+          new_image=SpreadImage(_image,geometry_info.rho,_image->interpolate,
+               _exception);
           break;
         }
-      if (LocaleCompare("strokewidth",argv[0]+1) == 0)
+      if (LocaleCompare("statistic",option+1) == 0)
         {
-          draw_info->stroke_width=InterpretLocaleValue(argv[1],
-            (char **) NULL);
+          parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
+                 option,arg1);
+          if (IfMagickFalse(IsGeometry(arg2)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
+          (void) ParseGeometry(arg2,&geometry_info);
+          new_image=StatisticImage(_image,(StatisticType)parse,
+               (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
+               _exception);
           break;
         }
-      if (LocaleCompare("style",argv[0]+1) == 0)
+      if (LocaleCompare("strip",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              draw_info->style=UndefinedStyle;
-              break;
-            }
-          draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
-            MagickFalse,argv[1]);
+          (void) StripImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("swirl",argv[0]+1) == 0)
+      if (LocaleCompare("swirl",option+1) == 0)
         {
-          /*
-            Swirl image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParseGeometry(argv[1],&geometry_info);
-          new_image=SwirlImage(*image,geometry_info.rho,
-            interpolate_method,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseGeometry(arg1,&geometry_info);
+          new_image=SwirlImage(_image,geometry_info.rho,
+            _image->interpolate,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 't':
     {
-      if (LocaleCompare("threshold",argv[0]+1) == 0)
+      if (LocaleCompare("threshold",option+1) == 0)
         {
           double
             threshold;
 
-          /*
-            Threshold image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            threshold=(double) QuantumRange/2;
-          else
-            threshold=SiPrefixToDouble(argv[1],QuantumRange);
-          (void) BilevelImage(*image,threshold);
-          InheritException(exception,&(*image)->exception);
-          break;
-        }
-      if (LocaleCompare("thumbnail",argv[0]+1) == 0)
-        {
-          /*
-            Thumbnail image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) ParseRegionGeometry(*image,argv[1],&geometry,exception);
-          new_image=ThumbnailImage(*image,geometry.width,geometry.height,
-            exception);
+          threshold=(double) QuantumRange/2;
+          if (normal_op) {
+            if (IfMagickFalse(IsGeometry(arg1)))
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+            threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
+          }
+          (void) BilevelImage(_image,threshold,_exception);
           break;
         }
-      if (LocaleCompare("tile",argv[0]+1) == 0)
+      if (LocaleCompare("thumbnail",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              if (draw_info->fill_pattern != (Image *) NULL)
-                draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
-              break;
-            }
-          draw_info->fill_pattern=GetImageCache(image_info,argv[1],
-            exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
+          new_image=ThumbnailImage(_image,geometry.width,geometry.height,
+            _exception);
           break;
         }
-      if (LocaleCompare("tint",argv[0]+1) == 0)
+      if (LocaleCompare("tint",option+1) == 0)
         {
-          /*
-            Tint the image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=TintImage(*image,argv[1],&fill,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
           break;
         }
-      if (LocaleCompare("transform",argv[0]+1) == 0)
+      if (LocaleCompare("transform",option+1) == 0)
         {
-          /*
-            Affine transform image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=AffineTransformImage(*image,&draw_info->affine,
-            exception);
+          /* DEPRECIATED -- should really use Distort AffineProjection */
+          new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
           break;
         }
-      if (LocaleCompare("transparent",argv[0]+1) == 0)
+      if (LocaleCompare("transparent",option+1) == 0)
         {
           PixelInfo
             target;
 
-          (void) SyncImageSettings(image_info,*image);
-          (void) QueryMagickColorCompliance(argv[1],AllCompliance,&target,
-                       exception);
-          (void) TransparentPaintImage(*image,&target,(Quantum)
-            TransparentAlpha,*argv[0] == '-' ? MagickFalse : MagickTrue,
-            &(*image)->exception);
-          break;
-        }
-      if (LocaleCompare("transpose",argv[0]+1) == 0)
-        {
-          /*
-            Transpose image scanlines.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=TransposeImage(*image,exception);
+          (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
+          (void) TransparentPaintImage(_image,&target,(Quantum)
+            TransparentAlpha,plus_alt_op,_exception);
           break;
         }
-      if (LocaleCompare("transverse",argv[0]+1) == 0)
+      if (LocaleCompare("transpose",option+1) == 0)
         {
-          /*
-            Transverse image scanlines.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=TransverseImage(*image,exception);
+          new_image=TransposeImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("treedepth",argv[0]+1) == 0)
+      if (LocaleCompare("transverse",option+1) == 0)
         {
-          quantize_info->tree_depth=StringToUnsignedLong(argv[1]);
+          new_image=TransverseImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("trim",argv[0]+1) == 0)
+      if (LocaleCompare("trim",option+1) == 0)
         {
-          /*
-            Trim image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=TrimImage(*image,exception);
+          new_image=TrimImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("type",argv[0]+1) == 0)
+      if (LocaleCompare("type",option+1) == 0)
         {
-          ImageType
-            type;
-
-          (void) SyncImageSettings(image_info,*image);
-          if (*argv[0] == '+')
-            type=UndefinedType;
-          else
-            type=(ImageType) ParseCommandOption(MagickTypeOptions,MagickFalse,
-              argv[1]);
-          (*image)->type=UndefinedType;
-          (void) SetImageType(*image,type,exception);
+          /* Note that "type" setting should have already been defined */
+          (void) SetImageType(_image,_image_info->type,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'u':
     {
-      if (LocaleCompare("undercolor",argv[0]+1) == 0)
-        {
-          (void) QueryColorCompliance(argv[1],AllComplience,&draw_info->undercolor,
-            exception);
-          break;
-        }
-      if (LocaleCompare("unique",argv[0]+1) == 0)
+      if (LocaleCompare("unique",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            {
-              (void) DeleteImageArtifact(*image,"identify:unique-colors");
+          /* FUTURE: move to SyncImageSettings() and AcqireImage()???
+             Option is not documented, bt appears to be for "identify".
+             We may need a identify specific verbose!
+          */
+          if (plus_alt_op) {
+              (void) DeleteImageArtifact(_image,"identify:unique-colors");
               break;
             }
-          (void) SetImageArtifact(*image,"identify:unique-colors","true");
-          (void) SetImageArtifact(*image,"verbose","true");
+          (void) SetImageArtifact(_image,"identify:unique-colors","true");
+          (void) SetImageArtifact(_image,"verbose","true");
           break;
         }
-      if (LocaleCompare("unique-colors",argv[0]+1) == 0)
+      if (LocaleCompare("unique-colors",option+1) == 0)
         {
-          /*
-            Unique image colors.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          new_image=UniqueImageColors(*image,exception);
+          new_image=UniqueImageColors(_image,_exception);
           break;
         }
-      if (LocaleCompare("unsharp",argv[0]+1) == 0)
+      if (LocaleCompare("unsharp",option+1) == 0)
         {
-          /*
-            Unsharp mask image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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 & XiValue) == 0)
             geometry_info.xi=1.0;
           if ((flags & PsiValue) == 0)
             geometry_info.psi=0.05;
-          new_image=UnsharpMaskImage(*image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
+          new_image=UnsharpMaskImage(_image,geometry_info.rho,
+            geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'v':
     {
-      if (LocaleCompare("verbose",argv[0]+1) == 0)
+      if (LocaleCompare("verbose",option+1) == 0)
         {
-          (void) SetImageArtifact(*image,argv[0]+1,
-            *argv[0] == '+' ? "false" : "true");
+          /* FUTURE: move to SyncImageSettings() and AcquireImage()???
+             three places!   ImageArtifact   ImageOption  _image_info->verbose
+             Some how new images also get this artifact!
+          */
+          (void) SetImageArtifact(_image,option+1,
+                           IfNormalOp ? "true" : "false" );
           break;
         }
-      if (LocaleCompare("vignette",argv[0]+1) == 0)
+      if (LocaleCompare("vignette",option+1) == 0)
         {
-          /*
-            Vignette image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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 & XiValue) == 0)
-            geometry_info.xi=0.1*(*image)->columns;
+            geometry_info.xi=0.1*_image->columns;
           if ((flags & PsiValue) == 0)
-            geometry_info.psi=0.1*(*image)->rows;
-          new_image=VignetteImage(*image,geometry_info.rho,
-            geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
-            ceil(geometry_info.psi-0.5),exception);
-          break;
-        }
-      if (LocaleCompare("virtual-pixel",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            {
-              (void) SetImageVirtualPixelMethod(*image,
-                UndefinedVirtualPixelMethod);
-              break;
-            }
-          (void) SetImageVirtualPixelMethod(*image,(VirtualPixelMethod)
-            ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
-            argv[1]));
+            geometry_info.psi=0.1*_image->rows;
+          new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
+            (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
+            ceil(geometry_info.psi-0.5),_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'w':
     {
-      if (LocaleCompare("wave",argv[0]+1) == 0)
+      if (LocaleCompare("wave",option+1) == 0)
         {
-          /*
-            Wave image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          flags=ParseGeometry(argv[1],&geometry_info);
+          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=WaveImage(*image,geometry_info.rho,
-            geometry_info.sigma,interpolate_method,exception);
+          new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
+               _image->interpolate,_exception);
           break;
         }
-      if (LocaleCompare("weight",argv[0]+1) == 0)
+      if (LocaleCompare("white-threshold",option+1) == 0)
         {
-          draw_info->weight=StringToUnsignedLong(argv[1]);
-          if (LocaleCompare(argv[1],"all") == 0)
-            draw_info->weight=0;
-          if (LocaleCompare(argv[1],"bold") == 0)
-            draw_info->weight=700;
-          if (LocaleCompare(argv[1],"bolder") == 0)
-            if (draw_info->weight <= 800)
-              draw_info->weight+=100;
-          if (LocaleCompare(argv[1],"lighter") == 0)
-            if (draw_info->weight >= 100)
-              draw_info->weight-=100;
-          if (LocaleCompare(argv[1],"normal") == 0)
-            draw_info->weight=400;
-          break;
-        }
-      if (LocaleCompare("white-threshold",argv[0]+1) == 0)
-        {
-          /*
-            White threshold image.
-          */
-          (void) SyncImageSettings(image_info,*image);
-          (void) WhiteThresholdImage(*image,argv[1],exception);
-          InheritException(exception,&(*image)->exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) WhiteThresholdImage(_image,arg1,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     default:
-      break;
+      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)
   */
   if (new_image != (Image *) NULL)
-    ReplaceImageInListReturnLast(image,new_image);
+    ReplaceImageInListReturnLast(&_image,new_image);
+
+  return;
+#undef _image_info
+#undef _draw_info
+#undef _quantize_info
+#undef _image
+#undef _exception
+#undef IfNormalOp
+#undef IfPlusOp
+#undef normal_op
+#undef plus_alt_op
+}
 
-  /*
-    Free resources.
-  */
-  quantize_info=DestroyQuantizeInfo(quantize_info);
-  draw_info=DestroyDrawInfo(draw_info);
-  status=(MagickStatusType) ((*image)->exception.severity ==
-    UndefinedException ? 1 : 0);
-  return(status == 0 ? MagickFalse : MagickTrue);
+WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
+  const char *option, const char *arg1, const char *arg2)
+{
+  size_t
+    n,
+    i;
+
+  assert(cli_wand != (MagickCLI *) NULL);
+  assert(cli_wand->signature == WandSignature);
+  assert(cli_wand->wand.signature == WandSignature);
+  assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
+  if (IfMagickTrue(cli_wand->wand.debug))
+    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
+
+#if !USE_WAND_METHODS
+  /* FUTURE add appropriate tracing */
+  i=0;
+  n=GetImageListLength(cli_wand->wand.images);
+  cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
+  while (1) {
+    i++;
+    CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
+    if ( cli_wand->wand.images->next == (Image *) NULL )
+      break;
+    cli_wand->wand.images=cli_wand->wand.images->next;
+  }
+  assert( i == n );
+  cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
+#else
+  MagickResetIterator(&cli_wand->wand);
+  while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
+    CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
+  MagickResetIterator(&cli_wand->wand);
+#endif
+  return;
 }
 \f
 /*
@@ -4042,286 +3562,231 @@ MagickExport MagickBooleanType SimpleOperationImage(ImageInfo *image_info,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+     S e q u e n c e O p e r a t i o n I m a g e s                           %
++     C L I L i s t O p e r a t o r I m a g e s                               %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  SequenceOperationImages() applies a single operation that apply to the
-%  entire image list (e.g. -append, -layers, -coalesce, etc.).
+%  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.
 %
 %  The format of the MogrifyImage method is:
 %
-%    MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
-%        const int argc, const char **argv,Image **images,
-%        ExceptionInfo *exception)
+%    void CLIListOperatorImages(MagickCLI *cli_wand,
+%        const char *option, const char *arg1, const char *arg2)
 %
 %  A description of each parameter follows:
 %
-%    o image_info: the image info..
+%    o cli_wand: structure holding settings to be applied
+%
+%    o option:  The option string for the operation
 %
-%    o argc: Specifies a pointer to an integer describing the number of
-%      elements in the argument vector.
+%    o arg1, arg2: optional argument strings to the operation
+%        arg2 is currently not used
 %
-%    o argv: Specifies a pointer to a text array containing the command line
-%      arguments.
+% Example usage...
 %
-%    o images: pointer to pointer of the first image in image list.
+%  CLIListOperatorImages(cli_wand,MagickFalse,"-duplicate", "3",  NULL);
+%  CLIListOperatorImages(cli_wand,MagickTrue, "+append",    NULL, NULL);
 %
-%    o exception: return any errors or warnings in this structure.
+% 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 MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
-  const int argc,const char **argv,Image **images,ExceptionInfo *exception)
+WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
+     const char *option,const char *arg1, const char *magick_unused(arg2))
 {
+  ssize_t
+    parse;
 
-  MagickStatusType
-    status;
-
-  QuantizeInfo
-    *quantize_info;
-
-  assert(image_info != (ImageInfo *) NULL);
-  assert(image_info->signature == MagickSignature);
-  assert(images != (Image **) NULL);
-  assert((*images)->previous == (Image *) NULL);
-  assert((*images)->signature == MagickSignature);
-  if ((*images)->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
-      (*images)->filename);
-  if ((argc <= 0) || (*argv == (char *) NULL))
-    return(MagickTrue);
-  status=MagickTrue;
+  Image
+    *new_images;
+
+#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 IfNormalOp      (*option=='-')
+#define IfPlusOp        (*option!='-')
+#define normal_op       IsMagickTrue(IfNormalOp)
+
+  assert(cli_wand != (MagickCLI *) NULL);
+  assert(cli_wand->signature == WandSignature);
+  assert(cli_wand->wand.signature == WandSignature);
+  assert(_images != (Image *) NULL);             /* _images must be present */
+  if (IfMagickTrue(cli_wand->wand.debug))
+    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
 
-  switch (*(argv[0]+1))
+  (void) SyncImagesSettings(_image_info,_images,_exception);
+
+  new_images=NewImageList();
+
+  switch (*(option+1))
   {
     case 'a':
     {
-      if (LocaleCompare("affinity",argv[0]+1) == 0)
-        {
-          (void) SyncImagesSettings(image_info,*images);
-          if (*argv[0] == '+')
-            {
-              (void) RemapImages(quantize_info,*images,(Image *) NULL,
-                exception);
-              break;
-            }
-          break;
-        }
-      if (LocaleCompare("append",argv[0]+1) == 0)
+      if (LocaleCompare("append",option+1) == 0)
         {
-          Image
-            *append_image;
-
-          (void) SyncImagesSettings(image_info,*images);
-          append_image=AppendImages(*images,*argv[0] == '-' ? MagickTrue :
-            MagickFalse,exception);
-          if (append_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=append_image;
+          new_images=AppendImages(_images,normal_op,_exception);
           break;
         }
-      if (LocaleCompare("average",argv[0]+1) == 0)
+      if (LocaleCompare("average",option+1) == 0)
         {
-          Image
-            *average_image;
-
-          /*
-            Average an image sequence (deprecated).
-          */
-          (void) SyncImagesSettings(image_info,*images);
-          average_image=EvaluateImages(*images,MeanEvaluateOperator,
-            exception);
-          if (average_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=average_image;
+          /* DEPRECIATED - use -evaluate-sequence Mean */
+          CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'c':
     {
-      if (LocaleCompare("channel",argv[0]+1) == 0)
+      if (LocaleCompare("channel-fx",option+1) == 0)
         {
-          ChannelType
-            channel;
-
-          if (*argv[0] == '+')
-            {
-              channel=DefaultChannels;
-              break;
-            }
-          channel=(ChannelType) ParseChannelOption(argv[1]);
-          SetPixelChannelMap(*images,channel);
+          new_images=ChannelFxImage(_images,arg1,_exception);
           break;
         }
-      if (LocaleCompare("clut",argv[0]+1) == 0)
+      if (LocaleCompare("clut",option+1) == 0)
         {
           Image
-            *clut_image,
-            *image;
+            *clut_image;
 
-          (void) SyncImagesSettings(image_info,*images);
-          image=RemoveFirstImageFromList(images);
-          clut_image=RemoveFirstImageFromList(images);
+          /* FUTURE - make this a compose option, and thus can be used
+             with layers compose or even compose last image over all other
+             _images.
+          */
+          new_images=RemoveFirstImageFromList(&_images);
+          clut_image=RemoveLastImageFromList(&_images);
+          /* FUTURE - produce Exception, rather than silent fail */
           if (clut_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          (void) ClutImage(image,clut_image,interpolate_method,exception);
+            break;
+          (void) ClutImage(new_images,clut_image,new_images->interpolate,_exception);
           clut_image=DestroyImage(clut_image);
-          *images=DestroyImageList(*images);
-          *images=image;
           break;
         }
-      if (LocaleCompare("coalesce",argv[0]+1) == 0)
+      if (LocaleCompare("coalesce",option+1) == 0)
         {
-          Image
-            *coalesce_image;
-
-          (void) SyncImagesSettings(image_info,*images);
-          coalesce_image=CoalesceImages(*images,exception);
-          if (coalesce_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=coalesce_image;
+          new_images=CoalesceImages(_images,_exception);
           break;
         }
-      if (LocaleCompare("combine",argv[0]+1) == 0)
+      if (LocaleCompare("combine",option+1) == 0)
         {
-          Image
-            *combine_image;
-
-          (void) SyncImagesSettings(image_info,*images);
-          combine_image=CombineImages(*images,exception);
-          if (combine_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=combine_image;
+          /* FUTURE - this may be replaced by a 'channel' method */
+          new_images=CombineImages(_images,_exception);
           break;
         }
-      if (LocaleCompare("composite",argv[0]+1) == 0)
+      if (LocaleCompare("composite",option+1) == 0)
         {
+          CompositeOperator
+            compose;
+
+          const char*
+            value;
+
+          MagickBooleanType
+            clip_to_self;
+
           Image
             *mask_image,
-            *composite_image,
-            *image;
+            *source_image;
 
           RectangleInfo
             geometry;
 
-          (void) SyncImagesSettings(image_info,*images);
-          image=RemoveFirstImageFromList(images);
-          composite_image=RemoveFirstImageFromList(images);
-          if (composite_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          (void) TransformImage(&composite_image,(char *) NULL,
-            composite_image->geometry);
-          SetGeometry(composite_image,&geometry);
-          (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
-          GravityAdjustGeometry(image->columns,image->rows,image->gravity,
-            &geometry);
-          mask_image=RemoveFirstImageFromList(images);
-          if (mask_image != (Image *) NULL)
-            {
-              if ((image->compose == DisplaceCompositeOp) ||
-                  (image->compose == DistortCompositeOp))
-                {
-                  /*
-                    Merge Y displacement into X displacement image.
-                  */
-                  (void) CompositeImage(composite_image,CopyGreenCompositeOp,
-                    mask_image,0,0);
-                  mask_image=DestroyImage(mask_image);
-                }
-              else
-                {
-                  /*
-                    Set a blending mask for the composition.
-                    Posible error, what if image->mask already set.
-                  */
-                  image->mask=mask_image;
-                  (void) NegateImage(image->mask,MagickFalse,exception);
-                }
-            }
-          (void) CompositeImage(image,image->compose,composite_image,
-            geometry.x,geometry.y);
+          /* Compose value from "-compose" option only */
+          value=GetImageOption(_image_info,"compose");
+          if (value == (const char *) NULL)
+            compose=OverCompositeOp;  /* use Over not source_image->compose */
+          else
+            compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
+              MagickFalse,value);
+
+          /* Get "clip-to-self" expert setting (false is normal) */
+          value=GetImageOption(_image_info,"compose:clip-to-self");
+          if (value == (const char *) NULL)
+            clip_to_self=MagickTrue;
+          else
+            clip_to_self=IsStringTrue(GetImageOption(_image_info,
+              "compose:clip-to-self")); /* if this is true */
+          value=GetImageOption(_image_info,"compose:outside-overlay");
+          if (value != (const char *) NULL) {   /* or this false */
+            /* FUTURE: depreciate warning for "compose:outside-overlay"*/
+            clip_to_self= IsMagickFalse(IsStringNotFalse(value));
+          }
+
+          new_images=RemoveFirstImageFromList(&_images);
+          source_image=RemoveFirstImageFromList(&_images);
+          if (source_image == (Image *) NULL)
+            break; /* FUTURE - produce Exception, rather than silent fail */
+
+          /* 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);
+
+          mask_image=RemoveFirstImageFromList(&_images);
           if (mask_image != (Image *) NULL)
-            mask_image=image->mask=DestroyImage(image->mask);
-          composite_image=DestroyImage(composite_image);
-          InheritException(exception,&image->exception);
-          *images=DestroyImageList(*images);
-          *images=image;
+            { /* 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,
+                  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);
+              }
+            }
+          (void) 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;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'd':
     {
-      if (LocaleCompare("deconstruct",argv[0]+1) == 0)
+      if (LocaleCompare("deconstruct",option+1) == 0)
         {
-          Image
-            *deconstruct_image;
-
-          (void) SyncImagesSettings(image_info,*images);
-          deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
-            exception);
-          if (deconstruct_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=deconstruct_image;
+          /* DEPRECIATED - use -layers CompareAny */
+          CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
           break;
         }
-      if (LocaleCompare("delete",argv[0]+1) == 0)
+      if (LocaleCompare("delete",option+1) == 0)
         {
-          if (*argv[0] == '+')
-            DeleteImages(images,"-1",exception);
+          if (IfNormalOp)
+            DeleteImages(&_images,arg1,_exception);
           else
-            DeleteImages(images,argv[1],exception);
-          break;
-        }
-      if (LocaleCompare("dither",argv[0]+1) == 0)
-        {
-          if (*argv[0] == '+')
-            {
-              quantize_info->dither=MagickFalse;
-              break;
-            }
-          quantize_info->dither=MagickTrue;
-          quantize_info->dither_method=(DitherMethod) ParseCommandOption(
-            MagickDitherOptions,MagickFalse,argv[1]);
+            DeleteImages(&_images,"-1",_exception);
           break;
         }
-      if (LocaleCompare("duplicate",argv[0]+1) == 0)
+      if (LocaleCompare("duplicate",option+1) == 0)
         {
-          Image
-            *duplicate_images;
-
-          if (*argv[0] == '+')
-            duplicate_images=DuplicateImages(*images,1,"-1",exception);
-          else
+          if (IfNormalOp)
             {
               const char
                 *p;
@@ -4329,215 +3794,144 @@ WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
               size_t
                 number_duplicates;
 
-              number_duplicates=(size_t) StringToLong(argv[1]);
-              p=strchr(argv[1],',');
+              if (IfMagickFalse(IsGeometry(arg1)))
+                CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
+                      arg1);
+              number_duplicates=(size_t) StringToLong(arg1);
+              p=strchr(arg1,',');
               if (p == (const char *) NULL)
-                duplicate_images=DuplicateImages(*images,number_duplicates,
-                  "-1",exception);
+                new_images=DuplicateImages(_images,number_duplicates,"-1",
+                  _exception);
               else
-                duplicate_images=DuplicateImages(*images,number_duplicates,p,
-                  exception);
+                new_images=DuplicateImages(_images,number_duplicates,p,
+                  _exception);
             }
-          AppendImageToList(images, duplicate_images);
-          (void) SyncImagesSettings(image_info,*images);
+          else
+            new_images=DuplicateImages(_images,1,"-1",_exception);
+          AppendImageToList(&_images, new_images);
+          new_images=(Image *)NULL;
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'e':
     {
-      if (LocaleCompare("evaluate-sequence",argv[0]+1) == 0)
+      if (LocaleCompare("evaluate-sequence",option+1) == 0)
         {
-          Image
-            *evaluate_image;
-
-          MagickEvaluateOperator
-            op;
-
-          (void) SyncImageSettings(image_info,*images);
-          op=(MagickEvaluateOperator) ParseCommandOption(
-            MagickEvaluateOptions,MagickFalse,argv[1]);
-          evaluate_image=EvaluateImages(*images,op,exception);
-          if (evaluate_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=evaluate_image;
+          parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
+                 option,arg1);
+          new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
+               _exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'f':
     {
-      if (LocaleCompare("fft",argv[0]+1) == 0)
+      if (LocaleCompare("fft",option+1) == 0)
         {
-          Image
-            *fourier_image;
-
-          /*
-            Implements the discrete Fourier transform (DFT).
-          */
-          (void) SyncImageSettings(image_info,*images);
-          fourier_image=ForwardFourierTransformImage(*images,*argv[0] == '-' ?
-            MagickTrue : MagickFalse,exception);
-          if (fourier_image == (Image *) NULL)
-            break;
-          *images=DestroyImage(*images);
-          *images=fourier_image;
+          new_images=ForwardFourierTransformImage(_images,normal_op,_exception);
           break;
         }
-      if (LocaleCompare("flatten",argv[0]+1) == 0)
+      if (LocaleCompare("flatten",option+1) == 0)
         {
-          Image
-            *flatten_image;
-
-          (void) SyncImagesSettings(image_info,*images);
-          flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
-          if (flatten_image == (Image *) NULL)
-            break;
-          *images=DestroyImageList(*images);
-          *images=flatten_image;
+          /* REDIRECTED to use -layers flatten instead */
+          CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
           break;
         }
-      if (LocaleCompare("fx",argv[0]+1) == 0)
+      if (LocaleCompare("fx",option+1) == 0)
         {
-          Image
-            *fx_image;
-
-          (void) SyncImagesSettings(image_info,*images);
-          fx_image=FxImage(*images,argv[1],exception);
-          if (fx_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=fx_image;
+          new_images=FxImage(_images,arg1,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'h':
     {
-      if (LocaleCompare("hald-clut",argv[0]+1) == 0)
+      if (LocaleCompare("hald-clut",option+1) == 0)
         {
+          /* FUTURE - make this a compose option (and thus layers compose )
+             or perhaps compose last image over all other _images.
+          */
           Image
-            *hald_image,
-            *image;
+            *hald_image;
 
-          (void) SyncImagesSettings(image_info,*images);
-          image=RemoveFirstImageFromList(images);
-          hald_image=RemoveFirstImageFromList(images);
+          new_images=RemoveFirstImageFromList(&_images);
+          hald_image=RemoveLastImageFromList(&_images);
           if (hald_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          (void) HaldClutImage(image,hald_image,exception);
+            break;
+          (void) HaldClutImage(new_images,hald_image,_exception);
           hald_image=DestroyImage(hald_image);
-          if (*images != (Image *) NULL)
-            *images=DestroyImageList(*images);
-          *images=image;
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'i':
     {
-      if (LocaleCompare("ift",argv[0]+1) == 0)
+      if (LocaleCompare("ift",option+1) == 0)
         {
           Image
-            *fourier_image,
             *magnitude_image,
             *phase_image;
 
-          /*
-            Implements the inverse fourier discrete Fourier transform (DFT).
-          */
-          (void) SyncImagesSettings(image_info,*images);
-          magnitude_image=RemoveFirstImageFromList(images);
-          phase_image=RemoveFirstImageFromList(images);
-          if (phase_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          fourier_image=InverseFourierTransformImage(magnitude_image,
-            phase_image,*argv[0] == '-' ? MagickTrue : MagickFalse,exception);
-          if (fourier_image == (Image *) NULL)
-            break;
-          if (*images != (Image *) NULL)
-            *images=DestroyImage(*images);
-          *images=fourier_image;
+           magnitude_image=RemoveFirstImageFromList(&_images);
+           phase_image=RemoveFirstImageFromList(&_images);
+          /* FUTURE - produce Exception, rather than silent fail */
+           if (phase_image == (Image *) NULL)
+             break;
+           new_images=InverseFourierTransformImage(magnitude_image,phase_image,
+                   normal_op,_exception);
+           magnitude_image=DestroyImage(magnitude_image);
+           phase_image=DestroyImage(phase_image);
           break;
         }
-      if (LocaleCompare("insert",argv[0]+1) == 0)
+      if (LocaleCompare("insert",option+1) == 0)
         {
           Image
-            *p,
-            *q;
+            *insert_image,
+            *index_image;
+
+          ssize_t
+            index;
 
+          if (IfNormalOp && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           index=0;
-          if (*argv[0] != '+')
-            index=(ssize_t) StringToLong(argv[1]);
-          p=RemoveLastImageFromList(images);
-          if (p == (Image *) NULL)
-            {
-              (void) ThrowMagickException(exception,GetMagickModule(),
-                OptionError,"NoSuchImage","`%s'",argv[1]);
-              status=MagickFalse;
-              break;
-            }
-          q=p;
+          insert_image=RemoveLastImageFromList(&_images);
+          if (IfNormalOp)
+            index=(ssize_t) StringToLong(arg1);
+          index_image=insert_image;
           if (index == 0)
-            PrependImageToList(images,q);
+            PrependImageToList(&_images,insert_image);
+          else if (index == (ssize_t) GetImageListLength(_images))
+            AppendImageToList(&_images,insert_image);
           else
-            if (index == (ssize_t) GetImageListLength(*images))
-              AppendImageToList(images,q);
-            else
-              {
-                 q=GetImageFromList(*images,index-1);
-                 if (q == (Image *) NULL)
-                   {
-                     (void) ThrowMagickException(exception,GetMagickModule(),
-                       OptionError,"NoSuchImage","`%s'",argv[1]);
-                     status=MagickFalse;
-                     break;
-                   }
-                InsertImageInList(&q,p);
-              }
-          *images=GetFirstImageInList(q);
-          break;
-        }
-      if (LocaleCompare("interpolate",argv[0]+1) == 0)
-        {
-          interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
-            MagickInterpolateOptions,MagickFalse,argv[1]);
+            {
+               index_image=GetImageFromList(_images,index-1);
+               if (index_image == (Image *) NULL)
+                 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
+              InsertImageInList(&index_image,insert_image);
+            }
+          _images=GetFirstImageInList(index_image);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'l':
     {
-      if (LocaleCompare("layers",argv[0]+1) == 0)
+      if (LocaleCompare("layers",option+1) == 0)
         {
-          Image
-            *layers;
-
-          ImageLayerMethod
-            method;
-
-          (void) SyncImagesSettings(image_info,*images);
-          layers=(Image *) NULL;
-          method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
-            MagickFalse,argv[1]);
-          switch (method)
+          parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
+                 option,arg1);
+          switch ((ImageLayerMethod) parse)
           {
             case CoalesceLayer:
             {
-              layers=CoalesceImages(*images,exception);
+              new_images=CoalesceImages(_images,_exception);
               break;
             }
             case CompareAnyLayer:
@@ -4545,7 +3939,8 @@ WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
             case CompareOverlayLayer:
             default:
             {
-              layers=CompareImagesLayers(*images,method,exception);
+              new_images=CompareImagesLayers(_images,(ImageLayerMethod) parse,
+                   _exception);
               break;
             }
             case MergeLayer:
@@ -4553,81 +3948,77 @@ WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
             case MosaicLayer:
             case TrimBoundsLayer:
             {
-              layers=MergeImageLayers(*images,method,exception);
+              new_images=MergeImageLayers(_images,(ImageLayerMethod) parse,
+                   _exception);
               break;
             }
             case DisposeLayer:
             {
-              layers=DisposeImages(*images,exception);
+              new_images=DisposeImages(_images,_exception);
               break;
             }
             case OptimizeImageLayer:
             {
-              layers=OptimizeImageLayers(*images,exception);
+              new_images=OptimizeImageLayers(_images,_exception);
               break;
             }
             case OptimizePlusLayer:
             {
-              layers=OptimizePlusImageLayers(*images,exception);
+              new_images=OptimizePlusImageLayers(_images,_exception);
               break;
             }
             case OptimizeTransLayer:
             {
-              OptimizeImageTransparency(*images,exception);
+              OptimizeImageTransparency(_images,_exception);
               break;
             }
             case RemoveDupsLayer:
             {
-              RemoveDuplicateLayers(images,exception);
+              RemoveDuplicateLayers(&_images,_exception);
               break;
             }
             case RemoveZeroLayer:
             {
-              RemoveZeroDelayLayers(images,exception);
+              RemoveZeroDelayLayers(&_images,_exception);
               break;
             }
             case OptimizeLayer:
-            {
-              /*
-                General Purpose, GIF Animation Optimizer.
-              */
-              layers=CoalesceImages(*images,exception);
-              if (layers == (Image *) NULL)
-                {
-                  status=MagickFalse;
-                  break;
-                }
-              *images=DestroyImageList(*images);
-              *images=layers;
-              layers=OptimizeImageLayers(*images,exception);
-              if (layers == (Image *) NULL)
-                {
-                  status=MagickFalse;
-                  break;
-                }
-              *images=DestroyImageList(*images);
-              *images=layers;
-              layers=(Image *) NULL;
-              OptimizeImageTransparency(*images,exception);
-              (void) RemapImages(quantize_info,*images,(Image *) NULL,
-                exception);
+            { /* General Purpose, GIF Animation Optimizer.  */
+              new_images=CoalesceImages(_images,_exception);
+              if (new_images == (Image *) NULL)
+                break;
+              _images=DestroyImageList(_images);
+              _images=OptimizeImageLayers(new_images,_exception);
+              if (_images == (Image *) NULL)
+                break;
+              new_images=DestroyImageList(new_images);
+              OptimizeImageTransparency(_images,_exception);
+              (void) RemapImages(_quantize_info,_images,(Image *) NULL,
+                _exception);
               break;
             }
             case CompositeLayer:
             {
-              CompositeOperator
-                compose;
-
               Image
                 *source;
 
               RectangleInfo
                 geometry;
 
-              /*
-                Split image sequence at the first 'NULL:' image.
-              */
-              source=(*images);
+              CompositeOperator
+                compose;
+
+              const char*
+                value;
+
+              value=GetImageOption(_image_info,"compose");
+              compose=OverCompositeOp;  /* Default to Over */
+              if (value != (const char *) NULL)
+                compose=(CompositeOperator) ParseCommandOption(
+                      MagickComposeOptions,MagickFalse,value);
+
+              /* Split image sequence at the first 'NULL:' image. */
+              source=_images;
               while (source != (Image *) NULL)
               {
                 source=GetNextImageInList(source);
@@ -4641,156 +4032,86 @@ WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
                       (GetNextImageInList(source) == (Image *) NULL))
                     source=(Image *) NULL;
                   else
-                    {
-                      /*
-                        Separate the two lists, junk the null: image.
-                      */
+                    { /* Separate the two lists, junk the null: image.  */
                       source=SplitImageList(source->previous);
                       DeleteImageFromList(&source);
                     }
                 }
               if (source == (Image *) NULL)
                 {
-                  (void) ThrowMagickException(exception,GetMagickModule(),
+                  (void) ThrowMagickException(_exception,GetMagickModule(),
                     OptionError,"MissingNullSeparator","layers Composite");
-                  status=MagickFalse;
                   break;
                 }
-              /*
-                Adjust offset with gravity and virtual canvas.
-              */
-              SetGeometry(*images,&geometry);
-              (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
+              /* Adjust offset with gravity and virtual canvas.  */
+              SetGeometry(_images,&geometry);
+              (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
               geometry.width=source->page.width != 0 ?
                 source->page.width : source->columns;
               geometry.height=source->page.height != 0 ?
                source->page.height : source->rows;
-              GravityAdjustGeometry((*images)->page.width != 0 ?
-                (*images)->page.width : (*images)->columns,
-                (*images)->page.height != 0 ? (*images)->page.height :
-                (*images)->rows,(*images)->gravity,&geometry);
-              compose=OverCompositeOp;
-              argv[0]=GetImageOption(image_info,"compose");
-              if (argv[0] != (const char *) NULL)
-                compose=(CompositeOperator) ParseCommandOption(
-                  MagickComposeOptions,MagickFalse,argv[0]);
-              CompositeLayers(*images,compose,source,geometry.x,geometry.y,
-                exception);
+              GravityAdjustGeometry(_images->page.width != 0 ?
+                _images->page.width : _images->columns,
+                _images->page.height != 0 ? _images->page.height :
+                _images->rows,_images->gravity,&geometry);
+
+              /* Compose the two image sequences together */
+              CompositeLayers(_images,compose,source,geometry.x,geometry.y,
+                _exception);
               source=DestroyImageList(source);
               break;
             }
           }
-          if (layers == (Image *) NULL)
-            break;
-          InheritException(exception,&layers->exception);
-          *images=DestroyImageList(*images);
-          *images=layers;
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'm':
     {
-      if (LocaleCompare("map",argv[0]+1) == 0)
-        {
-          (void) SyncImagesSettings(image_info,*images);
-          if (*argv[0] == '+')
-            {
-              (void) RemapImages(quantize_info,*images,(Image *) NULL,
-                exception);
-              break;
-            }
-          break;
-        }
-      if (LocaleCompare("maximum",argv[0]+1) == 0)
-        {
-          Image
-            *maximum_image;
-
-          /*
-            Maximum image sequence (deprecated).
-          */
-          (void) SyncImagesSettings(image_info,*images);
-          maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
-          if (maximum_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=maximum_image;
-          break;
-        }
-      if (LocaleCompare("minimum",argv[0]+1) == 0)
+      if (LocaleCompare("map",option+1) == 0)
         {
-          Image
-            *minimum_image;
-
-          /*
-            Minimum image sequence (deprecated).
-          */
-          (void) SyncImagesSettings(image_info,*images);
-          minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
-          if (minimum_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=minimum_image;
+          /* DEPRECIATED use +remap */
+          (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
           break;
         }
-      if (LocaleCompare("morph",argv[0]+1) == 0)
+      if (LocaleCompare("morph",option+1) == 0)
         {
           Image
             *morph_image;
 
-          (void) SyncImagesSettings(image_info,*images);
-          morph_image=MorphImages(*images,StringToUnsignedLong(argv[1]),
-            exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
+            _exception);
           if (morph_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=morph_image;
+            break;
+          _images=DestroyImageList(_images);
+          _images=morph_image;
           break;
         }
-      if (LocaleCompare("mosaic",argv[0]+1) == 0)
+      if (LocaleCompare("mosaic",option+1) == 0)
         {
-          Image
-            *mosaic_image;
-
-          (void) SyncImagesSettings(image_info,*images);
-          mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
-          if (mosaic_image == (Image *) NULL)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=mosaic_image;
+          /* REDIRECTED to use -layers mosaic instead */
+          CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'p':
     {
-      if (LocaleCompare("print",argv[0]+1) == 0)
+      if (LocaleCompare("print",option+1) == 0)
         {
           char
             *string;
 
-          (void) SyncImagesSettings(image_info,*images);
-          string=InterpretImageProperties(image_info,*images,argv[1],
-            exception);
+          string=InterpretImageProperties(_image_info,_images,arg1,_exception);
           if (string == (char *) NULL)
             break;
           (void) FormatLocaleFile(stdout,"%s",string);
           string=DestroyString(string);
+          break;
         }
-      if (LocaleCompare("process",argv[0]+1) == 0)
+      if (LocaleCompare("process",option+1) == 0)
         {
           char
             **arguments;
@@ -4799,11 +4120,10 @@ WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
             j,
             number_arguments;
 
-          (void) SyncImagesSettings(image_info,*images);
-          arguments=StringToArgv(argv[1],&number_arguments);
+          arguments=StringToArgv(arg1,&number_arguments);
           if (arguments == (char **) NULL)
             break;
-          if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
+          if (strchr(arguments[1],'=') != (char *) NULL)
             {
               char
                 breaker,
@@ -4824,9 +4144,9 @@ WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
                 *token_info;
 
               /*
-                Support old style syntax, filter="-option arg".
+                Support old style syntax, filter="-option arg1".
               */
-              length=strlen(argv[1]);
+              length=strlen(arg1);
               token=(char *) NULL;
               if (~length >= (MaxTextExtent-1))
                 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
@@ -4834,7 +4154,7 @@ WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
               if (token == (char *) NULL)
                 break;
               next=0;
-              arguments=argv[1];
+              arguments=arg1;
               token_info=AcquireTokenInfo();
               status=Tokenizer(token_info,0,token,length,arguments,"","=",
                 "\"",'\0',&breaker,&next,&quote);
@@ -4845,35 +4165,39 @@ WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
                     *argv;
 
                   argv=(&(arguments[next]));
-                  (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
-                    exception);
+                  (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
+                    _exception);
                 }
               token=DestroyString(token);
               break;
             }
           (void) SubstituteString(&arguments[1],"-","");
-          (void) InvokeDynamicImageFilter(arguments[1],&(*images),
-            number_arguments-2,(const char **) arguments+2,exception);
+          (void) InvokeDynamicImageFilter(arguments[1],&_images,
+            number_arguments-2,(const char **) arguments+2,_exception);
           for (j=0; j < number_arguments; j++)
             arguments[j]=DestroyString(arguments[j]);
           arguments=(char **) RelinquishMagickMemory(arguments);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'r':
     {
-      if (LocaleCompare("reverse",argv[0]+1) == 0)
+      if (LocaleCompare("remap",option+1) == 0)
         {
-          ReverseImageList(images);
-          InheritException(exception,&(*images)->exception);
+          (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
           break;
         }
-      break;
+      if (LocaleCompare("reverse",option+1) == 0)
+        {
+          ReverseImageList(&_images);
+          break;
+        }
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 's':
     {
-      if (LocaleCompare("smush",argv[0]+1) == 0)
+      if (LocaleCompare("smush",option+1) == 0)
         {
           Image
             *smush_image;
@@ -4881,99 +4205,472 @@ WandExport MagickBooleanType SequenceOperationImages(ImageInfo *image_info,
           ssize_t
             offset;
 
-          (void) SyncImagesSettings(image_info,*images);
-          offset=(ssize_t) StringToLong(argv[1]);
-          smush_image=SmushImages(*images,*argv[0] == '-' ? MagickTrue :
-            MagickFalse,offset,exception);
+          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)
-            {
-              status=MagickFalse;
-              break;
-            }
-          *images=DestroyImageList(*images);
-          *images=smush_image;
+            break;
+          _images=DestroyImageList(_images);
+          _images=smush_image;
           break;
         }
-      if (LocaleCompare("swap",argv[0]+1) == 0)
-        {
-          Image
-            *p,
-            *q,
-            *swap;
+      if (LocaleCompare("swap",option+1) == 0) {
+        Image
+          *p,
+          *q,
+          *swap;
 
-          ssize_t
-            swap_index;
+        ssize_t
+          index,
+          swap_index;
 
-          index=(-1);
-          swap_index=(-2);
-          if (*argv[0] != '+')
-            {
-              GeometryInfo
-                geometry_info;
+        index=-1;
+        swap_index=-2;
+        if (IfNormalOp) {
+          GeometryInfo
+            geometry_info;
 
-              MagickStatusType
-                flags;
+          MagickStatusType
+            flags;
 
-              swap_index=(-1);
-              flags=ParseGeometry(argv[1],&geometry_info);
-              index=(ssize_t) geometry_info.rho;
-              if ((flags & SigmaValue) != 0)
-                swap_index=(ssize_t) geometry_info.sigma;
-            }
-          p=GetImageFromList(*images,index);
-          q=GetImageFromList(*images,swap_index);
-          if ((p == (Image *) NULL) || (q == (Image *) NULL))
-            {
-              (void) ThrowMagickException(exception,GetMagickModule(),
-                OptionError,"NoSuchImage","`%s'",(*images)->filename);
-              status=MagickFalse;
-              break;
-            }
-          if (p == q)
-            break;
-          swap=CloneImage(p,0,0,MagickTrue,exception);
-          ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
-          ReplaceImageInList(&q,swap);
-          *images=GetFirstImageInList(q);
-          break;
+          swap_index=(-1);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          flags=ParseGeometry(arg1,&geometry_info);
+          index=(ssize_t) geometry_info.rho;
+          if ((flags & SigmaValue) != 0)
+            swap_index=(ssize_t) geometry_info.sigma;
         }
-      break;
+        p=GetImageFromList(_images,index);
+        q=GetImageFromList(_images,swap_index);
+        if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
+          if (IfNormalOp)
+            CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
+          else
+            CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
+        }
+        if (p == q)
+          CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
+        swap=CloneImage(p,0,0,MagickTrue,_exception);
+        ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
+        ReplaceImageInList(&q,swap);
+        _images=GetFirstImageInList(q);
+        break;
+      }
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
-    case 'w':
-    {
-      if (LocaleCompare("write",argv[0]+1) == 0)
-        {
-          char
-            key[MaxTextExtent];
+    default:
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
+  }
+  if (new_images == (Image *) NULL)
+    return;
+
+  if (_images != (Image *) NULL)
+    _images=DestroyImageList(_images);
+  _images=GetFirstImageInList(new_images);
+  return;
+
+#undef _image_info
+#undef _images
+#undef _exception
+#undef _draw_info
+#undef _quantize_info
+#undef IfNormalOp
+#undef IfPlusOp
+#undef normal_op
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
++   C L I S p e c i a l 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.
+%
+%  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.
+%
+%  Note: unlike other Operators, these may involve other special 'option'
+%  character prefixes, other than simply '-' or '+'.
+%
+%  The format of the CLISpecialOption method is:
+%
+%      void CLISpecialOption(MagickCLI *cli_wand,const char *option,
+%           const char *arg1)
+%
+%  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 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;
+%
+*/
 
-          Image
-            *write_images;
+WandExport void CLISpecialOperator(MagickCLI *cli_wand,
+  const char *option, const char *arg1)
+{
+#define _image_info     (cli_wand->wand.image_info)
+#define _images         (cli_wand->wand.images)
+#define _exception      (cli_wand->wand.exception)
+#define IfNormalOp      (*option=='-')
+#define IfPlusOp        (*option!='-')
 
-          ImageInfo
-            *write_info;
+  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);
 
-          (void) SyncImagesSettings(image_info,*images);
-          (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[1]);
-          (void) DeleteImageRegistry(key);
-          write_images=(*images);
-          if (*argv[0] == '+')
-            write_images=CloneImageList(*images,exception);
-          write_info=CloneImageInfo(image_info);
-          status&=WriteImages(write_info,write_images,argv[1],exception);
-          write_info=DestroyImageInfo(write_info);
-          if (*argv[0] == '+')
-            write_images=DestroyImageList(write_images);
-          break;
-        }
-      break;
+  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
     }
-    default:
-      break;
+    /* FUTURE: how do I free the expanded filename arguments??? */
+
+    return;
   }
-  quantize_info=DestroyQuantizeInfo(quantize_info);
+  /*
+    Image Writing  (no-images present is valid in specific cases)
+  */
+  if (LocaleCompare("write",option+1) == 0) {
+    char
+      key[MaxTextExtent];
 
-  status=(MagickStatusType) ((*image)->exception.severity ==
-    UndefinedException ? 1 : 0);
-  return(status != 0 ? MagickTrue : MagickFalse);
-}
+    Image
+      *write_images;
+
+    ImageInfo
+      *write_info;
+
+    /* 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);
+    }
+
+    (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;
+    }
+
+    node->next = cli_wand->image_info_stack;
+    cli_wand->image_info_stack = node;
+
+    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;
+      }
+    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) 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);
+
+    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;
+    }
+  /*
+    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;
+    }
+    switch (list)
+    {
+      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;
+    }
+    return;
+  }
+
+#if 0
+  // Other 'special' options this should handle
+  //    "region"  "reset"  "arg"
+  if ( ( process_flags & ProcessUnknownOptionError ) != 0 )
 #endif
+    CLIWandException(OptionError,"UnrecognizedOption",option);
+
+#undef _image_info
+#undef _images
+#undef _exception
+#undef IfNormalOp
+#undef IfPlusOp
+}