]> granicus.if.org Git - imagemagick/blobdiff - MagickWand/operation.c
(no commit message)
[imagemagick] / MagickWand / operation.c
index ada9bc538a6c42de11cce6587b2e8be75d537bb4..65982cb716501a09dc8cc79273e730762e2cdfb7 100644 (file)
@@ -3,17 +3,17 @@
 %                                                                             %
 %                                                                             %
 %                                                                             %
-%             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                                %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 % 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
 */
 \f
 /*
@@ -50,6 +50,9 @@
 #include "MagickWand/studio.h"
 #include "MagickWand/MagickWand.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"
 /*
   Define declarations.
 */
-#define UndefinedCompressionQuality  0UL
+#define USE_WAND_METHODS  0
+#define MAX_STACK_DEPTH  32
+#define UNDEFINED_COMPRESSION_QUALITY  0UL
+
 /*
   Constant declaration. (temporary exports)
 */
@@ -72,7 +78,7 @@ static const char
 */
 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,6 +178,8 @@ 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,
@@ -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++;
 
   /*
@@ -213,17 +244,15 @@ static Image *SparseColorOption(const Image *image,
     if ( token[0] == ',' ) continue;
     if ( isalpha((int) token[0]) || token[0] == '#' )
       x += number_colors;  /* color argument found */
-    else {
+    else
       x++;   /* floating point argument */
-    }
   }
-  error=MagickTrue;
   /* control points and color values */
-  error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
+  error = IsMagickTrue( x % (2+number_colors) );
   number_arguments=x;
-  if ( error ) {
+  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);
   }
@@ -246,7 +275,7 @@ 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;
@@ -257,7 +286,7 @@ 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 Y-coord");
       error = MagickTrue;
       break;
@@ -280,7 +309,7 @@ static Image *SparseColorOption(const Image *image,
           (image->colorspace == CMYKColorspace))
         sparse_arguments[x++] = QuantumScale*color.black;
       if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
-          (image->matte != MagickFalse))
+          IfMagickTrue(image->matte))
         sparse_arguments[x++] = QuantumScale*color.alpha;
     }
     else {
@@ -320,7 +349,7 @@ static Image *SparseColorOption(const Image *image,
         token[0] = ','; /* used this token - get another */
       }
       if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
-          (image->matte != MagickFalse))
+          IfMagickTrue(image->matte))
         {
         while ( token[0] == ',' ) GetMagickToken(p,&p,token);
         if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
@@ -332,7 +361,7 @@ static Image *SparseColorOption(const Image *image,
   }
   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);
   }
@@ -351,400 +380,451 @@ static Image *SparseColorOption(const Image *image,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+   W a n d S e t t i n g O p t i o n I n f I n f o                           %
++   C L I S e t t i n g O p t i o n I n f o                                   %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  WandSettingOptionInfo() applies a single settings option into a CLI wand
+%  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 also found within the wand.
+%  used when processing the images.
 %
-%  These options do no require images to be present in the wand for them to be
-%  able to be set, in which case they will be applied to
+%  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
 %
 %  Options handled by this function are listed in CommandOptions[] of
 %  "option.c" that is one of "SettingOptionFlags" option flags.
 %
-%  The format of the WandSettingOptionInfo method is:
+%  The format of the CLISettingOptionInfo method is:
 %
-%    void WandSettingOptionInfo(MagickWand *wand,const char *option,
-%               const char *arg)
+%    void CLISettingOptionInfo(MagickCLI *cli_wand,
+%               const char *option, const char *arg1, const char *arg2)
 %
 %  A description of each parameter follows:
 %
-%    o wand: structure holding settings to be applied
+%    o cli_wand: structure holding settings to be applied
 %
 %    o option: The option string to be set
 %
-%    o arg: The single argument used to set this option.
-%           If NULL the setting is reset to its default value.
-%           For boolean (no argument) settings false=NULL, true=any_string
+%    o arg1, arg2: optional argument strings to the operation
+%        arg2 is currently only used by "-limit"
 %
 % Example usage...
 %
-%    WandSettingOptionInfo(wand, "background", MagickTrue, "Red");
-%    WandSettingOptionInfo(wand, "adjoin", "true");
-%    WandSettingOptionInfo(wand, "adjoin", NULL);
+%    CLISettingOptionInfo(cli_wand, "-background", "Red", NULL); // set value
+%    CLISettingOptionInfo(cli_wand, "-adjoin", NULL, NULL);      // set boolean
+%    CLISettingOptionInfo(cli_wand, "+adjoin", NULL, NULL);      // unset
 %
-% Or for handling command line arguments EG: +/-option ["arg"]
+% Or for handling command line arguments EG: +/-option ["arg1"]
 %
 %    argc,argv
 %    i=index in argv
 %
-%    count=ParseCommandOption(MagickCommandOptions,MagickFalse,argv[i]);
-%    flags=GetCommandOptionFlags(MagickCommandOptions,MagickFalse,argv[i]);
-%    if ( (flags & SettingOptionFlags) != 0 )
-%      WandSettingOptionInfo(wand, argv[i]+1,
-%            (((*argv[i])!='-') ? (char *)NULL
-%                   : (count>0) ? argv[i+1] : "true") );
+%    option_info = GetCommandOptionInfo(argv[i]);
+%    count=option_info->type;
+%    option_type=option_info->flags;
+%
+%    if ( (option_type & SettingOperatorOptionFlags) != 0 )
+%      CLISettingOptionInfo(cli_wand, argv[i],
+%                   (count>=1) ? argv[i+1] : (char *)NULL,
+%                   (count>=2) ? argv[i+2] : (char *)NULL);
 %    i += count+1;
 %
 */
-WandExport void WandSettingOptionInfo(MagickWand *wand,const char *option,
-     const char *arg)
+WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
+     const char *option,const char *arg1, const char *arg2)
 {
-  assert(wand != (MagickWand *) NULL);
-  assert(wand->signature == WandSignature);
-  assert(wand->draw_info != (DrawInfo *) NULL); /* ensure it is a CLI wand */
-  if (wand->debug != MagickFalse)
-    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
-
-#define image_info      (wand->image_info)
-#define draw_info       (wand->draw_info)
-#define quantize_info   (wand->quantize_info)
-#define exception       (wand->exception)
-#define IfSetOption     (arg!=(char *)NULL)
-#define ArgOption(def)  (IfSetOption?arg:(const char *)(def))
-#define ArgBoolean      (IfSetOption?MagickTrue:MagickFalse)
-
-  switch (*option)
+  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",option) == 0)
+      if (LocaleCompare("adjoin",option+1) == 0)
         {
-          image_info->adjoin = ArgBoolean;
+          _image_info->adjoin = ArgBoolean;
           break;
         }
-      if (LocaleCompare("affine",option) == 0)
+      if (LocaleCompare("affine",option+1) == 0)
         {
-          /* DEPRECIATED: draw_info setting only: for -draw and -transform */
+          /* DEPRECIATED: _draw_info setting only: for -draw and -transform */
           if (IfSetOption)
-            (void) ParseAffineGeometry(arg,&draw_info->affine,exception);
+            (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
           else
-            GetAffineMatrix(&draw_info->affine);
+            GetAffineMatrix(&_draw_info->affine);
           break;
         }
-      if (LocaleCompare("antialias",option) == 0)
+      if (LocaleCompare("antialias",option+1) == 0)
         {
-          image_info->antialias =
-            draw_info->stroke_antialias =
-              draw_info->text_antialias = ArgBoolean;
+          _image_info->antialias =
+            _draw_info->stroke_antialias =
+              _draw_info->text_antialias = ArgBoolean;
           break;
         }
       if (LocaleCompare("attenuate",option+1) == 0)
         {
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
           break;
         }
-      if (LocaleCompare("authenticate",option) == 0)
+      if (LocaleCompare("authenticate",option+1) == 0)
         {
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'b':
     {
-      if (LocaleCompare("background",option) == 0)
+      if (LocaleCompare("background",option+1) == 0)
         {
-          /* FUTURE: both image_info attribute & ImageOption in use!
-             image_info only used directly for generating new images.
+          /* 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 image
-             Note that +background, means fall-back to image background
-             and only if not set fall back to BackgroundColor const.
+             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,ArgOption(NULL));
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           (void) QueryColorCompliance(ArgOption(BackgroundColor),AllCompliance,
-             &image_info->background_color,exception);
+             &_image_info->background_color,_exception);
           break;
         }
-      if (LocaleCompare("bias",option) == 0)
+      if (LocaleCompare("bias",option+1) == 0)
         {
-          /* FUTURE: bias OBSOLETED, replaced by "convolve:bias"
+          /* 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.
           */
-          (void) SetImageOption(image_info,option,ArgOption("0"));
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("black-point-compensation",option) == 0)
+      if (LocaleCompare("black-point-compensation",option+1) == 0)
         {
           /* Used as a image chromaticity setting
              SyncImageSettings() used to set per-image attribute.
           */
-          (void) SetImageOption(image_info,option,
-               IfSetOption ? "true" : "false" );
+          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
           break;
         }
-      if (LocaleCompare("blue-primary",option) == 0)
+      if (LocaleCompare("blue-primary",option+1) == 0)
         {
           /* Image chromaticity X,Y  NB: Y=X if Y not defined
              Used by many coders including PNG
              SyncImageSettings() used to set per-image attribute.
           */
-          (void) SetImageOption(image_info,option,ArgOption("0.0"));
+          arg1=ArgOption("0.0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("bordercolor",option) == 0)
+      if (LocaleCompare("bordercolor",option+1) == 0)
         {
-          /* FUTURE: both image_info attribute & ImageOption in use!
+          /* FUTURE: both _image_info attribute & ImageOption in use!
              SyncImageSettings() used to set per-image attribute.
+             Better error checking of QueryColorCompliance().
           */
           if (IfSetOption)
             {
-              (void) SetImageOption(image_info,option,arg);
-              (void) QueryColorCompliance(arg,AllCompliance,
-                  &image_info->border_color,exception);
-              (void) QueryColorCompliance(arg,AllCompliance,
-                  &draw_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) DeleteImageOption(image_info,option);
+          (void) DeleteImageOption(_image_info,option+1);
           (void) QueryColorCompliance(BorderColor,AllCompliance,
-            &image_info->border_color,exception);
+            &_image_info->border_color,_exception);
           (void) QueryColorCompliance(BorderColor,AllCompliance,
-            &draw_info->border_color,exception);
+            &_draw_info->border_color,_exception);
           break;
         }
-      if (LocaleCompare("box",option) == 0)
+      if (LocaleCompare("box",option+1) == 0)
         {
           /* DEPRECIATED - now "undercolor" */
-          WandSettingOptionInfo(wand,"undercolor",arg);
+          CLISettingOptionInfo(cli_wand,"undercolor",arg1, arg2);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'c':
     {
-      if (LocaleCompare("cache",option) == 0)
+      if (LocaleCompare("cache",option+1) == 0)
         {
           MagickSizeType
             limit;
 
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           limit=MagickResourceInfinity;
-          if (LocaleCompare("unlimited",arg) != 0)
-            limit=(MagickSizeType) SiPrefixToDoubleInterval(arg,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",option) == 0)
+      if (LocaleCompare("caption",option+1) == 0)
         {
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("channel",option) == 0)
+      if (LocaleCompare("channel",option+1) == 0)
         {
-          /* This is applied to images in SimpleImageOperator!!!
-             FUTURE: move it to SyncImageSettings() - or alternative
-          */
-          image_info->channel=(ChannelType) (
-               IfSetOption ? ParseChannelOption(arg) : DefaultChannels );
+          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",option) == 0)
+      if (LocaleCompare("colorspace",option+1) == 0)
         {
           /* 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 */
-          image_info->colorspace=(ColorspaceType) ParseCommandOption(
-               MagickColorspaceOptions,MagickFalse,ArgOption("undefined"));
+          parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,
+                        ArgOption("undefined"));
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
+                                    option,arg1);
+          _image_info->colorspace=(ColorspaceType) parse;
           break;
         }
-      if (LocaleCompare("comment",option) == 0)
+      if (LocaleCompare("comment",option+1) == 0)
         {
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("compose",option) == 0)
+      if (LocaleCompare("compose",option+1) == 0)
         {
-          /* FUTURE: image_info should be used,
+          /* 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
+             "-layer" operators shoud use _image_info if defined otherwise
              they should use a per-image compose setting.
           */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
-          image_info->compose=(CompositeOperator) ParseCommandOption(
-               MagickComposeOptions,MagickFalse,ArgOption("undefined"));
+          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",option) == 0)
+      if (LocaleCompare("compress",option+1) == 0)
         {
-          /* FUTURE: What should be used?  image_info  or ImageOption ???
+          /* 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
+             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".
           */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
-          image_info->compression=(CompressionType) ParseCommandOption(
-                MagickCompressOptions,MagickFalse,ArgOption("undefined"));
+          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",option) == 0)
+      if (LocaleCompare("debug",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute. */
-          (void) SetLogEventMask(ArgOption("none"));
-          image_info->debug=IsEventLogging(); /* extract logging*/
-          wand->debug=IsEventLogging();
+          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",option) == 0)
+      if (LocaleCompare("define",option+1) == 0)
         {
-          /* DefineImageOption() equals SetImageOption() but with '='
-             It does not however set individual image options.
-             -set will set individual image options as well!
-          */
-          if (LocaleNCompare(arg,"registry:",9) == 0)
+          if (LocaleNCompare(arg1,"registry:",9) == 0)
             {
               if (IfSetOption)
-                (void) DefineImageRegistry(StringRegistryType,arg+9,
-                    exception);
+                (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
               else
-                (void) DeleteImageRegistry(arg+9);
+                (void) DeleteImageRegistry(arg1+9);
               break;
             }
+          /* DefineImageOption() equals SetImageOption() but with '=' */
           if (IfSetOption)
-            (void) DefineImageOption(image_info,arg);
-          else
-            (void) DeleteImageOption(image_info,arg);
+            (void) DefineImageOption(_image_info,arg1);
+          else if (IsMagickFalse(DeleteImageOption(_image_info,arg1)))
+            CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
           break;
         }
-      if (LocaleCompare("delay",option) == 0)
+      if (LocaleCompare("delay",option+1) == 0)
         {
           /* Only used for new images via AcquireImage()
              FUTURE: Option should also be used for "-morph" (color morphing)
           */
-          (void) SetImageOption(image_info,option,ArgOption("0"));
+          arg1=ArgOption("0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("density",option) == 0)
+      if (LocaleCompare("density",option+1) == 0)
         {
-          /* FUTURE: strings used in image_info attr and draw_info!
+          /* 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.
           */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
-          (void) CloneString(&image_info->density,ArgOption(NULL));
-          (void) CloneString(&draw_info->density,image_info->density);
+          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",option) == 0)
+      if (LocaleCompare("depth",option+1) == 0)
         {
           /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
              SyncImageSettings() used to set per-image attribute.
           */
-          image_info->depth=IfSetOption?StringToUnsignedLong(arg)
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
                                        :MAGICKCORE_QUANTUM_DEPTH;
           break;
         }
-      if (LocaleCompare("direction",option) == 0)
+      if (LocaleCompare("direction",option+1) == 0)
         {
-          /* Image Option is only used to set draw_info */
-          (void) SetImageOption(image_info,option,ArgOption("undefined"));
-          draw_info->direction=(DirectionType) ParseCommandOption(
-                         MagickDirectionOptions,MagickFalse,
-                         ArgOption("undefined"));
+          /* 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",option) == 0)
+      if (LocaleCompare("display",option+1) == 0)
         {
-          (void) CloneString(&image_info->server_name,ArgOption(NULL));
-          (void) CloneString(&draw_info->server_name,image_info->server_name);
+          (void) CloneString(&_image_info->server_name,ArgOption(NULL));
+          (void) CloneString(&_draw_info->server_name,_image_info->server_name);
           break;
         }
-      if (LocaleCompare("dispose",option) == 0)
+      if (LocaleCompare("dispose",option+1) == 0)
         {
           /* only used in setting new images */
-          (void) SetImageOption(image_info,option,ArgOption("undefined"));
+          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",option) == 0)
+      if (LocaleCompare("dither",option+1) == 0)
         {
-          /* image_info attr (on/off), quantize_info attr (on/off)
-             but also ImageInfo and quantize_info method!
+          /* _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,ArgOption("none"));
-          quantize_info->dither_method=(DitherMethod) ParseCommandOption(
+          _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;
+          if (_quantize_info->dither_method == NoDitherMethod)
+            _image_info->dither = _quantize_info->dither = MagickFalse;
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'e':
     {
-      if (LocaleCompare("encoding",option) == 0)
+      if (LocaleCompare("encoding",option+1) == 0)
         {
-          (void) CloneString(&draw_info->encoding,ArgOption("undefined"));
-          (void) SetImageOption(image_info,option,draw_info->encoding);
+          (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
+          (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
           break;
         }
-      if (LocaleCompare("endian",option) == 0)
+      if (LocaleCompare("endian",option+1) == 0)
         {
-          /* Both image_info attr and ImageInfo */
-          (void) SetImageOption(image_info,option,ArgOption("undefined"));
-          image_info->endian=(EndianType) ParseCommandOption(
-              MagickEndianOptions,MagickFalse,ArgOption("undefined"));
+          /* 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",option) == 0)
+      if (LocaleCompare("extract",option+1) == 0)
         {
-          (void) CloneString(&image_info->extract,ArgOption(NULL));
+          (void) CloneString(&_image_info->extract,ArgOption(NULL));
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'f':
     {
-      if (LocaleCompare("family",option) == 0)
+      if (LocaleCompare("family",option+1) == 0)
         {
-          (void) CloneString(&draw_info->family,ArgOption(NULL));
+          (void) CloneString(&_draw_info->family,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("fill",option) == 0)
+      if (LocaleCompare("fill",option+1) == 0)
         {
-          /* Set "fill" OR "fill-pattern" in draw_info
+          /* 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".
           */
-          const char
-            *value;
-
           MagickBooleanType
             status;
 
@@ -754,300 +834,269 @@ WandExport void WandSettingOptionInfo(MagickWand *wand,const char *option,
           PixelInfo
             color;
 
-          value = ArgOption("none");
-          (void) SetImageOption(image_info,option,value);
-          if (draw_info->fill_pattern != (Image *) NULL)
-            draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
+          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(value,AllCompliance,&color,sans);
+          status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
           sans=DestroyExceptionInfo(sans);
 
-          if (status == MagickFalse)
-            draw_info->fill_pattern=GetImageCache(image_info,value,exception);
+          if (IfMagickFalse(status))
+            _draw_info->fill_pattern=GetImageCache(_image_info,arg1,_exception);
           else
-            draw_info->fill=color;
+            _draw_info->fill=color;
           break;
         }
-      if (LocaleCompare("filter",option) == 0)
+      if (LocaleCompare("filter",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute. */
-          (void) SetImageOption(image_info,option,ArgOption("undefined"));
+          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) == 0)
+      if (LocaleCompare("font",option+1) == 0)
         {
-          (void) CloneString(&draw_info->font,ArgOption(NULL));
-          (void) CloneString(&image_info->font,draw_info->font);
+          (void) CloneString(&_draw_info->font,ArgOption(NULL));
+          (void) CloneString(&_image_info->font,_draw_info->font);
           break;
         }
-      if (LocaleCompare("format",option) == 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(arg,'%'); 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;
+              _image_info->ping=MagickFalse;
           */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("fuzz",option) == 0)
+      if (LocaleCompare("fuzz",option+1) == 0)
         {
           /* 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.
 
-             Can't find anything else using image_info->fuzz directly!
+             FUTURE: Can't find anything else using _image_info->fuzz directly!
+                     remove direct sttribute from image_info
           */
-          if (IfSetOption)
-            {
-              image_info->fuzz=StringToDoubleInterval(arg,(double)
+          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,arg);
-              break;
-            }
-          image_info->fuzz=0.0;
-          (void) SetImageOption(image_info,option,"0");
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'g':
     {
-      if (LocaleCompare("gravity",option) == 0)
+      if (LocaleCompare("gravity",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute. */
-          (void) SetImageOption(image_info,option,ArgOption("none"));
-          draw_info->gravity=(GravityType) ParseCommandOption(
-                   MagickGravityOptions,MagickFalse,ArgOption("none"));
+          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",option) == 0)
+      if (LocaleCompare("green-primary",option+1) == 0)
         {
           /* Image chromaticity X,Y  NB: Y=X if Y not defined
              SyncImageSettings() used to set per-image attribute.
              Used directly by many coders
           */
-          (void) SetImageOption(image_info,option,ArgOption("0.0"));
+          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",option) == 0)
+      if (LocaleCompare("intent",option+1) == 0)
         {
           /* Only used by coders: MIFF, MPC, BMP, PNG
              and for image profile call to AcquireTransformThreadSet()
              SyncImageSettings() used to set per-image attribute.
           */
-          (void) SetImageOption(image_info,option,ArgOption("undefined"));
+          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",option) == 0)
+      if (LocaleCompare("interlace",option+1) == 0)
         {
-          /* image_info is directly used by coders (so why an image setting?)
+          /* _image_info is directly used by coders (so why an image setting?)
              SyncImageSettings() used to set per-image attribute.
           */
-          (void) SetImageOption(image_info,option,ArgOption("undefined"));
-          image_info->interlace=(InterlaceType) ParseCommandOption(
-                MagickInterlaceOptions,MagickFalse,ArgOption("undefined"));
+          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",option) == 0)
+      if (LocaleCompare("interline-spacing",option+1) == 0)
         {
-          (void) SetImageOption(image_info,option, ArgOption(NULL));
-          draw_info->interline_spacing=StringToDouble(ArgOption("0"),
+          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",option) == 0)
+      if (LocaleCompare("interpolate",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute. */
-          (void) SetImageOption(image_info,option,ArgOption("undefined"));
+          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",option) == 0)
+      if (LocaleCompare("interword-spacing",option+1) == 0)
         {
-          (void) SetImageOption(image_info,option, ArgOption(NULL));
-          draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
+          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",option) == 0)
+      if (LocaleCompare("kerning",option+1) == 0)
         {
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
-          draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
+          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",option) == 0)
+      if (LocaleCompare("label",option+1) == 0)
         {
           /* only used for new images - not in SyncImageOptions() */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("list",option) == 0)
+      if (LocaleCompare("limit",option+1) == 0)
         {
-          ssize_t
-            list;
+          MagickSizeType
+            limit;
 
-          list=ParseCommandOption(MagickListOptions,MagickFalse,
-               ArgOption("list"));
-          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;
-            }
-          }
+          limit=MagickResourceInfinity;
+          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("log",option) == 0)
+      if (LocaleCompare("log",option+1) == 0)
         {
-          if (IfSetOption)
-            (void) SetLogFormat(arg);
+          if (IfSetOption) {
+            if ((strchr(arg1,'%') == (char *) NULL))
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+            (void) SetLogFormat(arg1);
+          }
           break;
         }
-      if (LocaleCompare("loop",option) == 0)
+      if (LocaleCompare("loop",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute. */
-          (void) SetImageOption(image_info,option,ArgOption("0"));
+          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("mattecolor",option) == 0)
+      if (LocaleCompare("mattecolor",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute. */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
-             &image_info->matte_color,exception);
+             &_image_info->matte_color,_exception);
           break;
         }
-      if (LocaleCompare("monitor",option) == 0)
+      if (LocaleCompare("monitor",option+1) == 0)
         {
-          (void) SetImageInfoProgressMonitor(image_info, IfSetOption?
+          (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
                 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
           break;
         }
-      if (LocaleCompare("monochrome",option) == 0)
+      if (LocaleCompare("monochrome",option+1) == 0)
         {
-          /* Setting (for some input coders)
-             But also a special 'type' operator
+          /* Setting (used by some input coders!) -- why?
+             Warning: This is also Special '-type' SimpleOperator
           */
-          image_info->monochrome= ArgBoolean;
+          _image_info->monochrome= ArgBoolean;
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'o':
     {
-      if (LocaleCompare("orient",option) == 0)
+      if (LocaleCompare("orient",option+1) == 0)
         {
           /* 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.
           */
-          (void) SetImageOption(image_info,option, ArgOption(NULL));
-          image_info->orientation=(InterlaceType) ParseCommandOption(
-            MagickOrientationOptions,MagickFalse,ArgOption("undefined"));
+          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",option) == 0)
+      if (LocaleCompare("page",option+1) == 0)
         {
-          /* Only used for new images and image generators
+          /* 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,
@@ -1064,15 +1113,15 @@ WandExport void WandSettingOptionInfo(MagickWand *wand,const char *option,
 
           if (!IfSetOption)
             {
-              (void) DeleteImageOption(image_info,option);
-              (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(arg);
+          canonical_page=GetPageGeometry(arg1);
           flags=ParseAbsoluteGeometry(canonical_page,&geometry);
           canonical_page=DestroyString(canonical_page);
           (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
@@ -1081,61 +1130,78 @@ WandExport void WandSettingOptionInfo(MagickWand *wand,const char *option,
             (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,option,page);
-          (void) CloneString(&image_info->page,page);
+          (void) SetImageOption(_image_info,option+1,page);
+          (void) CloneString(&_image_info->page,page);
           break;
         }
-      if (LocaleCompare("ping",option) == 0)
+      if (LocaleCompare("ping",option+1) == 0)
         {
-          image_info->ping = ArgBoolean;
+          _image_info->ping = ArgBoolean;
           break;
         }
-      if (LocaleCompare("pointsize",option) == 0)
+      if (LocaleCompare("pointsize",option+1) == 0)
         {
-          image_info->pointsize=draw_info->pointsize=
-                   StringToDouble(ArgOption("12"),(char **) NULL);
+          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",option) == 0)
+      if (LocaleCompare("precision",option+1) == 0)
         {
-          (void) SetMagickPrecision(StringToInteger(ArgOption("-1")));
+          arg1=ArgOption("-1");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetMagickPrecision(StringToInteger(arg1));
           break;
         }
       /* FUTURE: Only the 'preview' coder appears to use this
-       * Depreciate the coder?  Leaving only the 'preview' operator.
-      if (LocaleCompare("preview",option) == 0)
+       * DEPRECIATE the coder?  Leaving only the 'preview' operator.
+      if (LocaleCompare("preview",option+1) == 0)
         {
-          image_info->preview_type=UndefinedPreview;
+          _image_info->preview_type=UndefinedPreview;
           if (IfSetOption)
-            image_info->preview_type=(PreviewType) ParseCommandOption(
-                MagickPreviewOptions,MagickFalse,arg);
+            _image_info->preview_type=(PreviewType) ParseCommandOption(
+                MagickPreviewOptions,MagickFalse,arg1);
           break;
         }
       */
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'q':
     {
-      if (LocaleCompare("quality",option) == 0)
+      if (LocaleCompare("quality",option+1) == 0)
         {
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
-          image_info->quality=UndefinedCompressionQuality;
-          if (IfSetOption)
-            image_info->quality=StringToUnsignedLong(arg);
+          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("quantize",option) == 0)
+      if (LocaleCompare("quantize",option+1) == 0)
         {
-          /* Just a set direct in quantize_info */
-          quantize_info->colorspace=UndefinedColorspace;
-          if (IfSetOption)
-            quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
-                 MagickColorspaceOptions,MagickFalse,arg);
+          /* 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) == 0)
+      if (LocaleCompare("quiet",option+1) == 0)
         {
-          /* FUTURE: if two -quiet is performed you can not do +quiet! */
+          /* FUTURE: if two -quiet is performed you can not do +quiet!
+             This needs to be checked over thoughly.
+          */
           static WarningHandler
             warning_handler = (WarningHandler) NULL;
 
@@ -1148,74 +1214,93 @@ WandExport void WandSettingOptionInfo(MagickWand *wand,const char *option,
             warning_handler=SetWarningHandler(warning_handler);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'r':
     {
-      if (LocaleCompare("red-primary",option) == 0)
+      if (LocaleCompare("red-primary",option+1) == 0)
         {
           /* Image chromaticity X,Y  NB: Y=X if Y not defined
              Used by many coders
              SyncImageSettings() used to set per-image attribute.
           */
-          (void) SetImageOption(image_info,option,ArgOption("0.0"));
+          arg1=ArgOption("0.0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("render",option) == 0)
+      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= IfSetOption ? MagickFalse : MagickTrue;
+          /* _draw_info only setting */
+          _draw_info->render= ArgBooleanNot;
           break;
         }
-      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",option) == 0)
+      if (LocaleCompare("sampling-factor",option+1) == 0)
         {
           /* FUTURE: should be converted to jpeg:sampling_factor */
-          (void) CloneString(&image_info->sampling_factor,ArgOption(NULL));
+          if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("scene",option) == 0)
+      if (LocaleCompare("scene",option+1) == 0)
         {
-          /* SyncImageSettings() used to set per-image attribute.
+          /* SyncImageSettings() used to set this as a per-image attribute.
              What ??? Why ????
           */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
-          image_info->scene=StringToUnsignedLong(ArgOption("0"));
+          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",option) == 0)
+      if (LocaleCompare("seed",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           SeedPseudoRandomGenerator(
-               IfSetOption ? (size_t) StringToUnsignedLong(arg)
+               IfSetOption ? (size_t) StringToUnsignedLong(arg1)
                            : (size_t) time((time_t *) NULL) );
           break;
         }
-      if (LocaleCompare("size",option) == 0)
+      if (LocaleCompare("size",option+1) == 0)
         {
-          /* FUTURE: string in image_info -- convert to Option ???
+          /* FUTURE: string in _image_info -- convert to Option ???
              Look at the special handling for "size" in SetImageOption()
            */
-          (void) CloneString(&image_info->size,ArgOption(NULL));
+          (void) CloneString(&_image_info->size,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("stretch",option) == 0)
+      if (LocaleCompare("stretch",option+1) == 0)
         {
-          draw_info->stretch=(StretchType) ParseCommandOption(
-              MagickStretchOptions,MagickFalse,ArgOption("undefined"));
+          arg1=ArgOption("undefined");
+          parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
+                 option,arg1);
+          _draw_info->stretch=(StretchType) parse;
           break;
         }
-      if (LocaleCompare("stroke",option) == 0)
+      if (LocaleCompare("stroke",option+1) == 0)
         {
           /* 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.
            */
-          const char
-            *value;
-
           MagickBooleanType
             status;
 
@@ -1225,196 +1310,228 @@ WandExport void WandSettingOptionInfo(MagickWand *wand,const char *option,
           PixelInfo
             color;
 
-          value = ArgOption("none");
-          (void) SetImageOption(image_info,option,value);
-          if (draw_info->stroke_pattern != (Image *) NULL)
-            draw_info->stroke_pattern=DestroyImage(draw_info->stroke_pattern);
+          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(value,AllCompliance,&color,sans);
+          status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
           sans=DestroyExceptionInfo(sans);
 
-          if (status == MagickFalse)
-            draw_info->stroke_pattern=GetImageCache(image_info,value,exception);
+          if (IfMagickFalse(status))
+            _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
           else
-            draw_info->stroke=color;
+            _draw_info->stroke=color;
           break;
         }
-      if (LocaleCompare("strokewidth",option) == 0)
+      if (LocaleCompare("strokewidth",option+1) == 0)
         {
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
-          draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
+          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;
         }
-      if (LocaleCompare("style",option) == 0)
+      if (LocaleCompare("style",option+1) == 0)
         {
-          draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
-               MagickFalse,ArgOption("undefined"));
+          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) == 0)
+      if (LocaleCompare("synchronize",option+1) == 0)
         {
-          image_info->synchronize = ArgBoolean;
+          /* FUTURE: syncronize to storage - but what does that mean? */
+          _image_info->synchronize = ArgBoolean;
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 't':
     {
-      if (LocaleCompare("taint",option) == 0)
+      if (LocaleCompare("taint",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute. */
-          (void) SetImageOption(image_info,option,
-               IfSetOption ? "true" : "false");
+          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
           break;
         }
-      if (LocaleCompare("texture",option) == 0)
+      if (LocaleCompare("texture",option+1) == 0)
         {
-          /* FUTURE: move image_info string to option splay-tree */
-          (void) CloneString(&image_info->texture,ArgOption(NULL));
+          /* 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",option) == 0)
+      if (LocaleCompare("tile",option+1) == 0)
         {
-          draw_info->fill_pattern=IfSetOption
-                                 ?GetImageCache(image_info,arg,exception)
-                                 :DestroyImage(draw_info->fill_pattern);
+          _draw_info->fill_pattern=IfSetOption
+                                 ?GetImageCache(_image_info,arg1,_exception)
+                                 :DestroyImage(_draw_info->fill_pattern);
           break;
         }
-      if (LocaleCompare("tile-offset",option) == 0)
+      if (LocaleCompare("tile-offset",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute. ??? */
-          (void) SetImageOption(image_info,option,ArgOption("0"));
+          arg1=ArgOption("0");
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
           break;
         }
-      if (LocaleCompare("transparent-color",option) == 0)
+      if (LocaleCompare("transparent-color",option+1) == 0)
         {
-          /* FUTURE: both image_info attribute & ImageOption in use!
-             image_info only used for generating new images.
+          /* 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.
           */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
+          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);
+              &_image_info->transparent_color,_exception);
           break;
         }
-      if (LocaleCompare("treedepth",option) == 0)
+      if (LocaleCompare("treedepth",option+1) == 0)
         {
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
-          quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
           break;
         }
-      if (LocaleCompare("type",option) == 0)
+      if (LocaleCompare("type",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute. */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
-          image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
-                 MagickFalse,ArgOption("undefined"));
+          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;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'u':
     {
-      if (LocaleCompare("undercolor",option) == 0)
+      if (LocaleCompare("undercolor",option+1) == 0)
         {
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
-               &draw_info->undercolor,exception);
+               &_draw_info->undercolor,_exception);
           break;
         }
-      if (LocaleCompare("units",option) == 0)
+      if (LocaleCompare("units",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute.
-             Should this effect draw_info X and Y resolution?
+             Should this effect _draw_info X and Y resolution?
              FUTURE: this probably should be part of the density setting
           */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
-          image_info->units=(ResolutionType) ParseCommandOption(
-                MagickResolutionOptions,MagickFalse,ArgOption("undefined"));
+          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",option) == 0)
+      if (LocaleCompare("verbose",option+1) == 0)
         {
-          /* FUTURE: Also an image artifact, set in Simple Operators.
-             But artifact is only used in verbose output.
+          /* FUTURE: Remember all options become image artifacts
+             _image_info->verbose is only used by coders.
           */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
-          image_info->verbose= ArgBoolean;
-          image_info->ping=MagickFalse; /* verbose can't be a ping */
+          (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",option) == 0)
+      if (LocaleCompare("view",option+1) == 0)
         {
-          /* FUTURE: Convert from image_info to ImageOption
+          /* 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));
+          (void) CloneString(&_image_info->view,ArgOption(NULL));
           break;
         }
-      if (LocaleCompare("virtual-pixel",option) == 0)
+      if (LocaleCompare("virtual-pixel",option+1) == 0)
         {
           /* SyncImageSettings() used to set per-image attribute.
              This is VERY deep in the image caching structure.
           */
-          (void) SetImageOption(image_info,option,ArgOption(NULL));
+          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("weight",option) == 0)
+      if (LocaleCompare("weight",option+1) == 0)
         {
           /* Just what does using a font 'weight' do ???
              There is no "-list weight" output (reference manual says there is)
           */
-          if (!IfSetOption)
-            break;
-          draw_info->weight=StringToUnsignedLong(arg);
-          if (LocaleCompare(arg,"all") == 0)
-            draw_info->weight=0;
-          if (LocaleCompare(arg,"bold") == 0)
-            draw_info->weight=700;
-          if (LocaleCompare(arg,"bolder") == 0)
-            if (draw_info->weight <= 800)
-              draw_info->weight+=100;
-          if (LocaleCompare(arg,"lighter") == 0)
-            if (draw_info->weight >= 100)
-              draw_info->weight-=100;
-          if (LocaleCompare(arg,"normal") == 0)
-            draw_info->weight=400;
-          break;
-        }
-      if (LocaleCompare("white-point",option) == 0)
+          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.
           */
-          (void) SetImageOption(image_info,option,ArgOption("0.0"));
+          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);
   }
-#undef image_info
-#undef draw_info
-#undef quantize_info
-#undef exception
+
+#undef _image_info
+#undef _exception
+#undef _draw_info
+#undef _quantize_info
 #undef IfSetOption
-#undef ArgOption
 #undef ArgBoolean
+#undef ArgBooleanNot
+#undef ArgBooleanString
+#undef ArgOption
 
   return;
 }
@@ -1424,30 +1541,27 @@ WandExport void WandSettingOptionInfo(MagickWand *wand,const char *option,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+     W a n d S i m p l e O p e r a t o r I m a g e s                         %
++     C L I S i m p l e O p e r a t o r I m a g e s                           %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  WandSimpleOperatorImages() applys one simple image operation given to all
-%  the images in the current wand,  with the settings that are saved in the
-%  CLI wand.
+%  the images in the CLI wand,  with the settings that was previously saved in
+%  the CLI wand.
 %
 %  It is assumed that any per-image settings are up-to-date with respect to
-%  extra settings that have been saved in the wand.
+%  extra settings that were already saved in the wand.
 %
 %  The format of the WandSimpleOperatorImage method is:
 %
-%    void WandSimpleOperatorImages(MagickWand *wand,
-%        const MagickBooleanType plus_alt_op, const char *option,
-%        const char *arg1, const char *arg2)
+%    void CLISimpleOperatorImages(MagickCLI *cli_wand,
+%        const char *option, const char *arg1, const char *arg2)
 %
 %  A description of each parameter follows:
 %
-%    o wand: structure holding settings to be applied
-%
-%    o plus_alt_op:  request the 'plus' or alturnative form of the operation
+%    o cli_wand: structure holding settings and images to be operated on
 %
 %    o option:  The option string for the operation
 %
@@ -1457,24 +1571,22 @@ WandExport void WandSettingOptionInfo(MagickWand *wand,const char *option,
 %
 % Example usage...
 %
-%  WandSimpleOperatorImages(wand,MagickFalse,"crop","100x100+20+30",NULL);
-%  WandSimpleOperatorImages(wand,MagickTrue,"repage",NULL,NULL);
-%  WandSimpleOperatorImages(wand,MagickTrue,"distort","SRT","45");
-%  if ( wand->exception->severity != UndefinedException ) {
-%    CatchException(exception);
-%    exit(1);
-%  }
+%  CLISimpleOperatorImages(cli_wand, "-crop","100x100+20+30",NULL);
+%  CLISimpleOperatorImages(cli_wand, "+repage",NULL,NULL);
+%  CLISimpleOperatorImages(cli_wand, "+distort","SRT","45");
 %
-% Or for handling command line arguments EG: +/-option ["arg"]
+% Or for handling command line arguments EG: +/-option ["arg1"]
 %
+%    cli_wand
 %    argc,argv
 %    i=index in argv
 %
-%    count=ParseCommandOption(MagickCommandOptions,MagickFalse,argv[i]);
-%    flags=GetCommandOptionFlags(MagickCommandOptions,MagickFalse,argv[i]);
-%    if ( flags == SimpleOperatorOptionFlag )
-%      WandSimpleOperatorImages(wand,
-%          (MagickBooleanType)(*argv[i])=='+'), argv[i]+1,
+%    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;
@@ -1483,24 +1595,23 @@ WandExport void WandSettingOptionInfo(MagickWand *wand,const char *option,
 
 /*
   Internal subrountine to apply one simple image operation to the current
-  image pointed to by the wand.
+  image pointed to by the CLI wand.
 
   The image in the list may be modified in three different ways...
     * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
     * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
     * one image replace by a list of images (-separate and -crop only!)
 
-  In each case the result replaces the 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.
+  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 WandSimpleOperatorImage(MagickWand *wand,
-  const MagickBooleanType plus_alt_op, const char *option,
-  const char *arg1, const char *arg2)
+static void CLISimpleOperatorImage(MagickCLI *cli_wand,
+  const char *option, const char *arg1, const char *arg2)
 {
   Image *
     new_image;
@@ -1514,21 +1625,27 @@ static void WandSimpleOperatorImage(MagickWand *wand,
   MagickStatusType
     flags;
 
-#define image_info      (wand->image_info)
-#define draw_info       (wand->draw_info)
-#define quantize_info   (wand->quantize_info)
-#define image           (wand->images)
-#define exception       (wand->exception)
-#define normal_op       (plus_alt_op?MagickFalse:MagickTrue)
+  ssize_t
+    parse;
+
+#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)
 
-  assert(image_info != (const ImageInfo *) NULL);
-  assert(image_info->signature == MagickSignature);
-  assert(draw_info != (DrawInfo *) NULL);      /* ensure it is a CLI wand */
-  assert(image != (Image *) NULL);             /* there is an image */
-  assert(image->signature == MagickSignature); /* and is a valid image */
+  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);
 
-  if (wand->debug != MagickFalse)
-    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
+  (void) SyncImageSettings(_image_info,_image,_exception);
 
   SetGeometryInfo(&geometry_info);
 
@@ -1537,129 +1654,133 @@ static void WandSimpleOperatorImage(MagickWand *wand,
   /* FUTURE: We may need somthing a little more optimized than this!
      Perhaps, do the 'sync' if 'settings tainted' before next operator.
   */
-  (void) SyncImageSettings(image_info,image,exception);
-
-  switch (*option)
+  switch (*(option+1))
   {
     case 'a':
     {
-      if (LocaleCompare("adaptive-blur",option) == 0)
+      if (LocaleCompare("adaptive-blur",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
-          if ((flags & 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",option) == 0)
+      if (LocaleCompare("adaptive-resize",option+1) == 0)
         {
-          (void) ParseRegionGeometry(image,arg1,&geometry,exception);
-          new_image=AdaptiveResizeImage(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=AdaptiveResizeImage(_image,geometry.width,geometry.height,
+            _exception);
           break;
         }
-      if (LocaleCompare("adaptive-sharpen",option) == 0)
+      if (LocaleCompare("adaptive-sharpen",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
-          if ((flags & XiValue) == 0)
-            geometry_info.xi=0.0;
-          new_image=AdaptiveSharpenImage(image,geometry_info.rho,
-            geometry_info.sigma,geometry_info.xi,exception);
+          new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
+            geometry_info.sigma,_exception);
           break;
         }
-      if (LocaleCompare("alpha",option) == 0)
+      if (LocaleCompare("alpha",option+1) == 0)
         {
-          AlphaChannelType
-            alpha_type;
-
-          alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
-            MagickFalse,arg1);
-          (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",option) == 0)
+      if (LocaleCompare("annotate",option+1) == 0)
         {
           char
             *text,
             geometry[MaxTextExtent];
 
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           SetGeometryInfo(&geometry_info);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=geometry_info.rho;
-          text=InterpretImageProperties(image_info,image,arg2,
-            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);
-          GetAffineMatrix(&draw_info->affine);
+          (void) AnnotateImage(_image,_draw_info,_exception);
+          GetAffineMatrix(&_draw_info->affine);
           break;
         }
-      if (LocaleCompare("auto-gamma",option) == 0)
+      if (LocaleCompare("auto-gamma",option+1) == 0)
         {
-          (void) AutoGammaImage(image,exception);
+          (void) AutoGammaImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("auto-level",option) == 0)
+      if (LocaleCompare("auto-level",option+1) == 0)
         {
-          (void) AutoLevelImage(image,exception);
+          (void) AutoLevelImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("auto-orient",option) == 0)
+      if (LocaleCompare("auto-orient",option+1) == 0)
         {
-          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:
@@ -1669,36 +1790,40 @@ static void WandSimpleOperatorImage(MagickWand *wand,
             new_image->orientation=TopLeftOrientation;
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'b':
     {
-      if (LocaleCompare("black-threshold",option) == 0)
+      if (LocaleCompare("black-threshold",option+1) == 0)
         {
-          (void) BlackThresholdImage(image,arg1,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) BlackThresholdImage(_image,arg1,_exception);
           break;
         }
-      if (LocaleCompare("blue-shift",option) == 0)
+      if (LocaleCompare("blue-shift",option+1) == 0)
         {
           geometry_info.rho=1.5;
-          if (plus_alt_op == MagickFalse)
+          if (IfNormalOp) {
+            if (IfMagickFalse(IsGeometry(arg1)))
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
             flags=ParseGeometry(arg1,&geometry_info);
-          new_image=BlueShiftImage(image,geometry_info.rho,exception);
+          }
+          new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
           break;
         }
-      if (LocaleCompare("blur",option) == 0)
+      if (LocaleCompare("blur",option+1) == 0)
         {
-          /* FUTURE: use of "bias" in a blur is non-sensible */
+          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",option) == 0)
+      if (LocaleCompare("border",option+1) == 0)
         {
           CompositeOperator
             compose;
@@ -1706,20 +1831,23 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           const char*
             value;
 
-          value=GetImageOption(image_info,"compose");
+          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 */
+            compose=OverCompositeOp;  /* use Over not _image->compose */
 
-          flags=ParsePageGeometry(image,arg1,&geometry,exception);
+          flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
           if ((flags & SigmaValue) == 0)
             geometry.height=geometry.width;
-          new_image=BorderImage(image,&geometry,compose,exception);
+          new_image=BorderImage(_image,&geometry,compose,_exception);
           break;
         }
-      if (LocaleCompare("brightness-contrast",option) == 0)
+      if (LocaleCompare("brightness-contrast",option+1) == 0)
         {
           double
             brightness,
@@ -1731,20 +1859,22 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           MagickStatusType
             flags;
 
+          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);
+          (void) BrightnessContrastImage(_image,brightness,contrast,
+            _exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'c':
     {
-      if (LocaleCompare("cdl",option) == 0)
+      if (LocaleCompare("cdl",option+1) == 0)
         {
           char
             *color_correction_collection;
@@ -1752,53 +1882,48 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           /*
             Color correct with a color decision list.
           */
-          color_correction_collection=FileToString(arg1,~0,exception);
+          color_correction_collection=FileToString(arg1,~0,_exception);
           if (color_correction_collection == (char *) NULL)
             break;
-          (void) ColorDecisionListImage(image,color_correction_collection,
-            exception);
-          break;
-        }
-      if (LocaleCompare("channel",option) == 0)
-        {
-          /* The "channel" setting has already been set
-             FUTURE: This probably should be part of WandSettingOptionInfo()
-             or SyncImageSettings().
-          */
-          SetPixelChannelMapMask(image,image_info->channel);
+          (void) ColorDecisionListImage(_image,color_correction_collection,
+            _exception);
           break;
         }
-      if (LocaleCompare("charcoal",option) == 0)
+      if (LocaleCompare("charcoal",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           if ((flags & 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",option) == 0)
+      if (LocaleCompare("chop",option+1) == 0)
         {
-          (void) ParseGravityGeometry(image,arg1,&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",option) == 0)
+      if (LocaleCompare("clamp",option+1) == 0)
         {
-          (void) ClampImage(image,exception);
+          (void) ClampImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("clip",option) == 0)
+      if (LocaleCompare("clip",option+1) == 0)
         {
-          if (plus_alt_op == MagickFalse)
-            (void) ClipImage(image,exception);
-          else /* "+clip" remove the write mask */
-            (void) SetImageMask(image,(Image *) NULL,exception);
+          if (IfNormalOp)
+            (void) ClipImage(_image,_exception);
+          else /* "+mask" remove the write mask */
+            (void) SetImageMask(_image,(Image *) NULL,_exception);
           break;
         }
-      if (LocaleCompare("clip-mask",option) == 0)
+      if (LocaleCompare("clip-mask",option+1) == 0)
         {
           CacheView
             *mask_view;
@@ -1815,84 +1940,84 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           ssize_t
             y;
 
-          if (plus_alt_op != MagickFalse)
-          { /* "+clip-mask" Remove the write mask */
-              (void) SetImageMask(image,(Image *) NULL,exception);
-              break;
-            }
-          mask_image=GetImageCache(image_info,arg1,exception);
+          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)
+          if (IfMagickFalse(SetImageStorageClass(mask_image,DirectClass,_exception)))
             break;
-          /* Create a write mask from clip-mask image */
+          /* 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) SetImageMask(image,mask_image,exception);
+          (void) SetImageMask(_image,mask_image,_exception);
           mask_image=DestroyImage(mask_image);
           break;
         }
-      if (LocaleCompare("clip-path",option) == 0)
+      if (LocaleCompare("clip-path",option+1) == 0)
         {
-          (void) ClipImagePath(image,arg1,
-               (MagickBooleanType)(!(int)plus_alt_op),exception);
+          (void) ClipImagePath(_image,arg1,normal_op,_exception);
           break;
         }
-      if (LocaleCompare("colorize",option) == 0)
+      if (LocaleCompare("colorize",option+1) == 0)
         {
-          new_image=ColorizeImage(image,arg1,&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",option) == 0)
+      if (LocaleCompare("color-matrix",option+1) == 0)
         {
           KernelInfo
             *kernel;
 
           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",option) == 0)
+      if (LocaleCompare("colors",option+1) == 0)
         {
           /* Reduce the number of colors in the image.
              FUTURE: also provide 'plus version with image 'color counts'
           */
-          quantize_info->number_colors=StringToUnsignedLong(arg1);
-          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",option) == 0)
+      if (LocaleCompare("colorspace",option+1) == 0)
         {
           /* WARNING: this is both a image_info setting (already done)
                       and a operator to change image colorspace.
@@ -1904,18 +2029,18 @@ static void WandSimpleOperatorImage(MagickWand *wand,
              new images, but forces images already in memory back to RGB!
              That seems to be a little strange!
           */
-          (void) TransformImageColorspace(image,
-                    plus_alt_op ? RGBColorspace : image_info->colorspace,
-                    exception);
+          (void) TransformImageColorspace(_image,
+                    IfNormalOp ? _image_info->colorspace : RGBColorspace,
+                    _exception);
           break;
         }
-      if (LocaleCompare("contrast",option) == 0)
+      if (LocaleCompare("contrast",option+1) == 0)
         {
-          (void) ContrastImage(image,
-               (MagickBooleanType)(!(int)plus_alt_op),exception);
+          /* DEPRECIATED: The -/+level provides far more controlled form */
+          (void) ContrastImage(_image,normal_op,_exception);
           break;
         }
-      if (LocaleCompare("contrast-stretch",option) == 0)
+      if (LocaleCompare("contrast-stretch",option+1) == 0)
         {
           double
             black_point,
@@ -1924,66 +2049,71 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           MagickStatusType
             flags;
 
+          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);
+          (void) ContrastStretchImage(_image,black_point,white_point,
+            _exception);
           break;
         }
-      if (LocaleCompare("convolve",option) == 0)
+      if (LocaleCompare("convolve",option+1) == 0)
         {
           KernelInfo
             *kernel_info;
 
           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",option) == 0)
+      if (LocaleCompare("crop",option+1) == 0)
         {
           /* WARNING: This can generate multiple images! */
-          new_image=CropImageToTiles(image,arg1,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          new_image=CropImageToTiles(_image,arg1,_exception);
           break;
         }
-      if (LocaleCompare("cycle",option) == 0)
+      if (LocaleCompare("cycle",option+1) == 0)
         {
-          (void) CycleColormapImage(image,(ssize_t) StringToLong(arg1),
-            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",option) == 0)
+      if (LocaleCompare("decipher",option+1) == 0)
         {
           StringInfo
             *passkey;
 
-          passkey=FileToStringInfo(arg1,~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("depth",option) == 0)
+      if (LocaleCompare("depth",option+1) == 0)
         {
-          /* The image_info->depth setting has already been set
+          /* 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!
@@ -1991,27 +2121,30 @@ static void WandSimpleOperatorImage(MagickWand *wand,
 
              FUTURE: this should not be an operator!!!
           */
-          (void) SetImageDepth(image,image_info->depth,exception);
+          (void) SetImageDepth(_image,_image_info->depth,_exception);
           break;
         }
-      if (LocaleCompare("deskew",option) == 0)
+      if (LocaleCompare("deskew",option+1) == 0)
         {
           double
             threshold;
 
-          if (plus_alt_op != MagickFalse)
-            threshold=40.0*QuantumRange/100.0;
-          else
+          if (IfNormalOp) {
+            if (IfMagickFalse(IsGeometry(arg1)))
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
             threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
-          new_image=DeskewImage(image,threshold,exception);
+          }
+          else
+            threshold=40.0*QuantumRange/100.0;
+          new_image=DeskewImage(_image,threshold,_exception);
           break;
         }
-      if (LocaleCompare("despeckle",option) == 0)
+      if (LocaleCompare("despeckle",option+1) == 0)
         {
-          new_image=DespeckleImage(image,exception);
+          new_image=DespeckleImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("distort",option) == 0)
+      if (LocaleCompare("distort",option+1) == 0)
         {
           char
             *args,
@@ -2020,9 +2153,6 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           const char
             *p;
 
-          DistortImageMethod
-            method;
-
           double
             *arguments;
 
@@ -2032,27 +2162,30 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           size_t
             number_arguments;
 
-          method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
-            MagickFalse,arg1);
-          if (method == ResizeDistortion)
+          parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+             CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
+                                      option,arg1);
+          if ((DistortImageMethod) parse == ResizeDistortion)
             {
                double
                  resize_args[2];
                /* Special Case - Argument is actually a resize geometry!
                ** Convert that to an appropriate distortion argument array.
                ** FUTURE: make a separate special resize operator
-               */
-               (void) ParseRegionGeometry(image,arg2,&geometry,
-                 exception);
+                    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,method,(size_t)2,
-                 resize_args,MagickTrue,exception);
+               new_image=DistortImage(_image,(DistortImageMethod) parse,
+                    (size_t)2,resize_args,MagickTrue,_exception);
                break;
             }
           /* handle percent arguments */
-          args=InterpretImageProperties(image_info,image,arg2,
-            exception);
+          args=InterpretImageProperties(_image_info,_image,arg2,_exception);
           if (args == (char *) NULL)
             break;
           /* convert arguments into an array of doubles
@@ -2071,10 +2204,10 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           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++)
           {
@@ -2084,125 +2217,134 @@ static void WandSimpleOperatorImage(MagickWand *wand,
             arguments[x]=StringToDouble(token,(char **) NULL);
           }
           args=DestroyString(args);
-          new_image=DistortImage(image,method,number_arguments,arguments,
-                        plus_alt_op,exception);
+          new_image=DistortImage(_image,(DistortImageMethod) parse,
+               number_arguments,arguments,plus_alt_op,_exception);
           arguments=(double *) RelinquishMagickMemory(arguments);
           break;
         }
-      if (LocaleCompare("draw",option) == 0)
+      if (LocaleCompare("draw",option+1) == 0)
         {
-          (void) CloneString(&draw_info->primitive,arg1);
-          (void) DrawImage(image,draw_info,exception);
-          (void) CloneString(&draw_info->primitive,(char *)NULL);
+          (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",option) == 0)
+      if (LocaleCompare("edge",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
-          new_image=EdgeImage(image,geometry_info.rho,
-            geometry_info.sigma,exception);
+          new_image=EdgeImage(_image,geometry_info.rho,geometry_info.sigma,
+               _exception);
           break;
         }
-      if (LocaleCompare("emboss",option) == 0)
+      if (LocaleCompare("emboss",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
-          new_image=EmbossImage(image,geometry_info.rho,
-            geometry_info.sigma,exception);
+          new_image=EmbossImage(_image,geometry_info.rho,
+            geometry_info.sigma,_exception);
           break;
         }
-      if (LocaleCompare("encipher",option) == 0)
+      if (LocaleCompare("encipher",option+1) == 0)
         {
           StringInfo
             *passkey;
 
-          passkey=FileToStringInfo(arg1,~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("enhance",option) == 0)
+      if (LocaleCompare("enhance",option+1) == 0)
         {
-          new_image=EnhanceImage(image,exception);
+          new_image=EnhanceImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("equalize",option) == 0)
+      if (LocaleCompare("equalize",option+1) == 0)
         {
-          (void) EqualizeImage(image,exception);
+          (void) EqualizeImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("evaluate",option) == 0)
+      if (LocaleCompare("evaluate",option+1) == 0)
         {
           double
             constant;
 
-          MagickEvaluateOperator
-            op;
-
-          op=(MagickEvaluateOperator) ParseCommandOption(
-            MagickEvaluateOptions,MagickFalse,arg1);
+          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,op,constant,exception);
+          (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
+               _exception);
           break;
         }
-      if (LocaleCompare("extent",option) == 0)
+      if (LocaleCompare("extent",option+1) == 0)
         {
-          flags=ParseGravityGeometry(image,arg1,&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("features",option) == 0)
+      if (LocaleCompare("features",option+1) == 0)
         {
           /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
-          if (plus_alt_op != MagickFalse)
-            {
-              (void) DeleteImageArtifact(image,"identify:features");
+          if (IfPlusOp) {
+              (void) DeleteImageArtifact(_image,"identify:features");
               break;
             }
-          (void) SetImageArtifact(image,"identify:features","true");
-          (void) SetImageArtifact(image,"verbose","true");
+          (void) SetImageArtifact(_image,"identify:features","true");
+          (void) SetImageArtifact(_image,"verbose","true");
           break;
         }
-      if (LocaleCompare("flip",option) == 0)
+      if (LocaleCompare("flip",option+1) == 0)
         {
-          new_image=FlipImage(image,exception);
+          new_image=FlipImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("flop",option) == 0)
+      if (LocaleCompare("flop",option+1) == 0)
         {
-          new_image=FlopImage(image,exception);
+          new_image=FlopImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("floodfill",option) == 0)
+      if (LocaleCompare("floodfill",option+1) == 0)
         {
           PixelInfo
             target;
 
-          (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);
+          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",option) == 0)
+      if (LocaleCompare("frame",option+1) == 0)
         {
           FrameInfo
             frame_info;
@@ -2213,14 +2355,16 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           const char*
             value;
 
-          value=GetImageOption(image_info,"compose");
+          value=GetImageOption(_image_info,"compose");
           if (value != (const char *) NULL)
             compose=(CompositeOperator) ParseCommandOption(
                  MagickComposeOptions,MagickFalse,value);
           else
-            compose=OverCompositeOp;  /* use Over not image->compose */
+            compose=OverCompositeOp;  /* use Over not _image->compose */
 
-          flags=ParsePageGeometry(image,arg1,&geometry,exception);
+          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)
@@ -2229,12 +2373,12 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           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",option) == 0)
+      if (LocaleCompare("function",option+1) == 0)
         {
           char
             *arguments,
@@ -2246,9 +2390,6 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           double
             *parameters;
 
-          MagickFunction
-            function;
-
           register ssize_t
             x;
 
@@ -2259,12 +2400,14 @@ static void WandSimpleOperatorImage(MagickWand *wand,
             Function Modify Image Values
             FUTURE: code should be almost a duplicate of that is "distort"
           */
-          function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
-            MagickFalse,arg1);
-          arguments=InterpretImageProperties(image_info,image,arg2,
-            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++)
           {
@@ -2277,95 +2420,100 @@ static void WandSimpleOperatorImage(MagickWand *wand,
             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]=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",option) == 0)
+      if (LocaleCompare("gamma",option+1) == 0)
         {
-          if (plus_alt_op != MagickFalse)
-            image->gamma=StringToDouble(arg1,(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,StringToDouble(arg1,(char **) NULL),
-                 exception);
+            _image->gamma=StringToDouble(arg1,(char **) NULL);
           break;
         }
-      if ((LocaleCompare("gaussian-blur",option) == 0) ||
-          (LocaleCompare("gaussian",option) == 0))
+      if ((LocaleCompare("gaussian-blur",option+1) == 0) ||
+          (LocaleCompare("gaussian",option+1) == 0))
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
-          new_image=GaussianBlurImage(image,geometry_info.rho,
-            geometry_info.sigma,exception);
+          new_image=GaussianBlurImage(_image,geometry_info.rho,
+            geometry_info.sigma,_exception);
           break;
         }
-      if (LocaleCompare("geometry",option) == 0)
+      if (LocaleCompare("geometry",option+1) == 0)
         {
           /*
             Record Image offset for composition. (A Setting)
-            Resize last image. (ListOperator)
+            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 (plus_alt_op != MagickFalse)
+          if (IfPlusOp)
             { /* remove the previous composition geometry offset! */
-              if (image->geometry != (char *) NULL)
-                image->geometry=DestroyString(image->geometry);
+              if (_image->geometry != (char *) NULL)
+                _image->geometry=DestroyString(_image->geometry);
               break;
             }
-          flags=ParseRegionGeometry(image,arg1,&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,arg1);
+            (void) CloneString(&_image->geometry,arg1);
           else
-            new_image=ResizeImage(image,geometry.width,geometry.height,
-              image->filter,image->blur,exception);
+            new_image=ResizeImage(_image,geometry.width,geometry.height,
+              _image->filter,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'h':
     {
-      if (LocaleCompare("highlight-color",option) == 0)
+      if (LocaleCompare("highlight-color",option+1) == 0)
         {
-          (void) SetImageArtifact(image,option,arg1);
+          (void) SetImageArtifact(_image,option+1,arg1);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'i':
     {
-      if (LocaleCompare("identify",option) == 0)
+      if (LocaleCompare("identify",option+1) == 0)
         {
           const char
             *format,
             *text;
 
-          format=GetImageOption(image_info,"format");
+          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);
@@ -2373,35 +2521,43 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           text=DestroyString((char *)text);
           break;
         }
-      if (LocaleCompare("implode",option) == 0)
+      if (LocaleCompare("implode",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           (void) ParseGeometry(arg1,&geometry_info);
-          new_image=ImplodeImage(image,geometry_info.rho,
-            image->interpolate,exception);
+          new_image=ImplodeImage(_image,geometry_info.rho,
+            _image->interpolate,_exception);
           break;
         }
-      if (LocaleCompare("interpolative-resize",option) == 0)
+      if (LocaleCompare("interpolative-resize",option+1) == 0)
         {
-          (void) ParseRegionGeometry(image,arg1,&geometry,exception);
-          new_image=InterpolativeResizeImage(image,geometry.width,
-               geometry.height,image->interpolate,exception);
+          /* 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",option) == 0)
+      if (LocaleCompare("lat",option+1) == 0)
         {
+          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,
+          new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
                (size_t) geometry_info.sigma,(double) geometry_info.xi,
-               exception);
+               _exception);
           break;
         }
-      if (LocaleCompare("level",option) == 0)
+      if (LocaleCompare("level",option+1) == 0)
         {
           MagickRealType
             black_point,
@@ -2411,6 +2567,8 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           MagickStatusType
             flags;
 
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           black_point=geometry_info.rho;
           white_point=(MagickRealType) QuantumRange;
@@ -2426,15 +2584,13 @@ static void WandSimpleOperatorImage(MagickWand *wand,
             }
           if ((flags & SigmaValue) == 0)
             white_point=(MagickRealType) QuantumRange-black_point;
-          if (plus_alt_op || ((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);
+            (void) LevelImage(_image,black_point,white_point,gamma,_exception);
           break;
         }
-      if (LocaleCompare("level-colors",option) == 0)
+      if (LocaleCompare("level-colors",option+1) == 0)
         {
           char
             token[MaxTextExtent];
@@ -2450,10 +2606,10 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           GetMagickToken(p,&p,token);  /* get black point color */
           if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
             (void) QueryColorCompliance(token,AllCompliance,
-                      &black_point,exception);
+                      &black_point,_exception);
           else
             (void) QueryColorCompliance("#000000",AllCompliance,
-                      &black_point,exception);
+                      &black_point,_exception);
           if (isalpha((int) token[0]) || (token[0] == '#'))
             GetMagickToken(p,&p,token);
           if (*token == '\0')
@@ -2464,16 +2620,16 @@ static void WandSimpleOperatorImage(MagickWand *wand,
                 GetMagickToken(p,&p,token); /* Get white point color. */
               if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
                 (void) QueryColorCompliance(token,AllCompliance,
-                           &white_point,exception);
+                           &white_point,_exception);
               else
                 (void) QueryColorCompliance("#ffffff",AllCompliance,
-                           &white_point,exception);
+                           &white_point,_exception);
             }
-          (void) LevelImageColors(image,&black_point,&white_point,
-                     plus_alt_op,exception);
+          (void) LevelImageColors(_image,&black_point,&white_point,
+                     plus_alt_op,_exception);
           break;
         }
-      if (LocaleCompare("linear-stretch",option) == 0)
+      if (LocaleCompare("linear-stretch",option+1) == 0)
         {
           double
             black_point,
@@ -2482,106 +2638,123 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           MagickStatusType
             flags;
 
+          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);
+          (void) LinearStretchImage(_image,black_point,white_point,_exception);
           break;
         }
-      if (LocaleCompare("liquid-rescale",option) == 0)
+      if (LocaleCompare("liquid-rescale",option+1) == 0)
         {
-          flags=ParseRegionGeometry(image,arg1,&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",option) == 0)
+      if (LocaleCompare("lowlight-color",option+1) == 0)
         {
-          (void) SetImageArtifact(image,option,arg1);
+          (void) SetImageArtifact(_image,option+1,arg1);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'm':
     {
-      if (LocaleCompare("map",option) == 0)
+      if (LocaleCompare("map",option+1) == 0)
         {
           Image
             *remap_image;
 
           /* DEPRECIATED use -remap */
-          remap_image=GetImageCache(image_info,arg1,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("mask",option) == 0)
+      if (LocaleCompare("mask",option+1) == 0)
         {
           Image
             *mask;
 
-          if (plus_alt_op != MagickFalse)
+          if (IfPlusOp)
             { /* Remove a mask. */
-              (void) SetImageMask(image,(Image *) NULL,exception);
+              (void) SetImageMask(_image,(Image *) NULL,_exception);
               break;
             }
           /* Set the image mask. */
-          mask=GetImageCache(image_info,arg1,exception);
+          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",option) == 0)
+      if (LocaleCompare("matte",option+1) == 0)
         {
           /* DEPRECIATED */
-          (void) SetImageAlphaChannel(image,plus_alt_op ?
-            DeactivateAlphaChannel:SetAlphaChannel ,exception);
+          (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
+                         DeactivateAlphaChannel, _exception);
           break;
         }
-      if (LocaleCompare("mode",option) == 0)
+      if (LocaleCompare("median",option+1) == 0)
         {
+          /* DEPRECIATED - use -statistic Median */
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1);
+          break;
+        }
+      if (LocaleCompare("mode",option+1) == 0)
+        {
+          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",option) == 0)
+      if (LocaleCompare("modulate",option+1) == 0)
         {
-          (void) ModulateImage(image,arg1,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) ModulateImage(_image,arg1,_exception);
           break;
         }
-      if (LocaleCompare("monitor",option) == 0)
+      if (LocaleCompare("monitor",option+1) == 0)
         {
-          (void) SetImageProgressMonitor(image, plus_alt_op?
-                (MagickProgressMonitor) NULL:MonitorProgress,(void *) NULL);
+          (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
+                (MagickProgressMonitor) NULL,(void *) NULL);
           break;
         }
-      if (LocaleCompare("monochrome",option) == 0)
+      if (LocaleCompare("monochrome",option+1) == 0)
         {
-          (void) SetImageType(image,BilevelType,exception);
+          (void) SetImageType(_image,BilevelType,_exception);
           break;
         }
-      if (LocaleCompare("morphology",option) == 0)
+      if (LocaleCompare("morphology",option+1) == 0)
         {
           char
             token[MaxTextExtent];
@@ -2592,16 +2765,15 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           KernelInfo
             *kernel;
 
-          MorphologyMethod
-            method;
-
           ssize_t
             iterations;
 
           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 == ','))
@@ -2610,104 +2782,104 @@ static void WandSimpleOperatorImage(MagickWand *wand,
             iterations=(ssize_t) StringToLong(p);
           kernel=AcquireKernelInfo(arg2);
           if (kernel == (KernelInfo *) NULL)
-            {
-              (void) ThrowMagickException(exception,GetMagickModule(),
-                   OptionError,"UnabletoParseKernel","morphology");
-              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",option) == 0)
+      if (LocaleCompare("motion-blur",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
-          new_image=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",option) == 0)
+      if (LocaleCompare("negate",option+1) == 0)
         {
-          (void) NegateImage(image, plus_alt_op, exception);
+          (void) NegateImage(_image, plus_alt_op, _exception);
           break;
         }
-      if (LocaleCompare("noise",option) == 0)
+      if (LocaleCompare("noise",option+1) == 0)
         {
-          if (plus_alt_op == MagickFalse)
+          if (IfNormalOp)
             {
+              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;
 
-              noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
-                          MagickFalse,arg1),
-
-              value=GetImageOption(image_info,"attenuate");
+              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;
 
-              new_image=AddNoiseImage(image,noise,attenuate,exception);
+              new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
+                   _exception);
             }
           break;
         }
-      if (LocaleCompare("normalize",option) == 0)
+      if (LocaleCompare("normalize",option+1) == 0)
         {
-          (void) NormalizeImage(image,exception);
+          (void) NormalizeImage(_image,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'o':
     {
-      if (LocaleCompare("opaque",option) == 0)
+      if (LocaleCompare("opaque",option+1) == 0)
         {
           PixelInfo
             target;
 
-          (void) QueryColorCompliance(arg1,AllCompliance,&target,exception);
-          (void) OpaquePaintImage(image,&target,&draw_info->fill,plus_alt_op,
-               exception);
+          (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
+          (void) OpaquePaintImage(_image,&target,&_draw_info->fill,plus_alt_op,
+               _exception);
           break;
         }
-      if (LocaleCompare("ordered-dither",option) == 0)
+      if (LocaleCompare("ordered-dither",option+1) == 0)
         {
-          (void) OrderedPosterizeImage(image,arg1,exception);
+          (void) OrderedPosterizeImage(_image,arg1,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'p':
     {
-      if (LocaleCompare("paint",option) == 0)
+      if (LocaleCompare("paint",option+1) == 0)
         {
           (void) ParseGeometry(arg1,&geometry_info);
-          new_image=OilPaintImage(image,geometry_info.rho,geometry_info.sigma,
-               exception);
+          new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
+               _exception);
           break;
         }
-      if (LocaleCompare("polaroid",option) == 0)
+      if (LocaleCompare("polaroid",option+1) == 0)
         {
           const char
             *caption;
@@ -2715,49 +2887,48 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           double
             angle;
 
-          if (plus_alt_op != MagickFalse)
-            {
-              RandomInfo
-              *random_info;
+          if (IfPlusOp) {
+            RandomInfo
+            *random_info;
 
-              random_info=AcquireRandomInfo();
-              angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
-              random_info=DestroyRandomInfo(random_info);
-            }
-          else
-            {
-              SetGeometryInfo(&geometry_info);
-              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);
+            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",option) == 0)
+      if (LocaleCompare("posterize",option+1) == 0)
         {
+          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);
+          (void) PosterizeImage(_image,(size_t) geometry_info.rho,
+               _quantize_info->dither,_exception);
           break;
         }
-      if (LocaleCompare("preview",option) == 0)
+      if (LocaleCompare("preview",option+1) == 0)
         {
-          PreviewType
-            preview_type;
-
           /* FUTURE: should be a 'Genesis' option?
              Option however is also in WandSettingOptionInfo()
+             Why???
           */
-          preview_type=UndefinedPreview;
-          if (plus_alt_op == MagickFalse)
-            preview_type=(PreviewType) ParseCommandOption(MagickPreviewOptions,
-                  MagickFalse,arg1);
-          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",option) == 0)
+      if (LocaleCompare("profile",option+1) == 0)
         {
           const char
             *name;
@@ -2771,33 +2942,33 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           ImageInfo
             *profile_info;
 
-          if (plus_alt_op != MagickFalse)
-            { /* Remove a profile from the image.  */
-              (void) ProfileImage(image,arg1,(const unsigned char *)
-                NULL,0,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,arg1,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);
+              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),exception);
+                    GetStringInfoLength(profile),_exception);
                   profile=DestroyStringInfo(profile);
                 }
               profile_info=DestroyImageInfo(profile_info);
@@ -2809,194 +2980,221 @@ static void WandSimpleOperatorImage(MagickWand *wand,
           {
             profile=GetImageProfile(profile_image,name);
             if (profile != (StringInfo *) NULL)
-              (void) ProfileImage(image,name,GetStringInfoDatum(profile),
-                (size_t) GetStringInfoLength(profile),exception);
+              (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",option) == 0)
+      if (LocaleCompare("radial-blur",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
-          new_image=RadialBlurImage(image,geometry_info.rho,
-            geometry_info.sigma,exception);
+          new_image=RadialBlurImage(_image,geometry_info.rho,_exception);
           break;
         }
-      if (LocaleCompare("raise",option) == 0)
+      if (LocaleCompare("raise",option+1) == 0)
         {
-          flags=ParsePageGeometry(image,arg1,&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,normal_op,exception);
+          (void) RaiseImage(_image,&geometry,normal_op,_exception);
           break;
         }
-      if (LocaleCompare("random-threshold",option) == 0)
+      if (LocaleCompare("random-threshold",option+1) == 0)
         {
-          (void) RandomThresholdImage(image,arg1,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) RandomThresholdImage(_image,arg1,_exception);
           break;
         }
-      if (LocaleCompare("remap",option) == 0)
+      if (LocaleCompare("remap",option+1) == 0)
         {
           Image
             *remap_image;
 
-          remap_image=GetImageCache(image_info,arg1,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",option) == 0)
+      if (LocaleCompare("repage",option+1) == 0)
         {
-          if (plus_alt_op == MagickFalse)
-            (void) ResetImagePage(image,arg1);
+          if (IfNormalOp)
+            {
+              if (IfMagickFalse(IsGeometry(arg1)))
+                CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
+                  arg1);
+              (void) ResetImagePage(_image,arg1);
+            }
           else
-            (void) ParseAbsoluteGeometry("0x0+0+0",&image->page);
+            (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
           break;
         }
-      if (LocaleCompare("resample",option) == 0)
+      if (LocaleCompare("resample",option+1) == 0)
         {
-          /* FUTURE: remove blur arguemnt - no longer used */
+          /* 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",option) == 0)
+      if (LocaleCompare("resize",option+1) == 0)
         {
-          /* FUTURE: remove blur argument - no longer used */
-          (void) ParseRegionGeometry(image,arg1,&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",option) == 0)
+      if (LocaleCompare("roll",option+1) == 0)
         {
-          (void) ParsePageGeometry(image,arg1,&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",option) == 0)
+      if (LocaleCompare("rotate",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           if (strchr(arg1,'>') != (char *) NULL)
-            if (image->columns <= image->rows)
+            if (_image->columns <= _image->rows)
               break;
           if (strchr(arg1,'<') != (char *) NULL)
-            if (image->columns >= image->rows)
+            if (_image->columns >= _image->rows)
               break;
-
           (void) ParseGeometry(arg1,&geometry_info);
-          new_image=RotateImage(image,geometry_info.rho,exception);
+          new_image=RotateImage(_image,geometry_info.rho,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 's':
     {
-      if (LocaleCompare("sample",option) == 0)
+      if (LocaleCompare("sample",option+1) == 0)
         {
-          (void) ParseRegionGeometry(image,arg1,&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",option) == 0)
+      if (LocaleCompare("scale",option+1) == 0)
         {
-          (void) ParseRegionGeometry(image,arg1,&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",option) == 0)
+      if (LocaleCompare("segment",option+1) == 0)
         {
+          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,geometry_info.psi,exception);
+          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",option) == 0)
+      if (LocaleCompare("selective-blur",option+1) == 0)
         {
-          /* WARNING: This can generate multiple images! */
-          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",option) == 0)
+      if (LocaleCompare("separate",option+1) == 0)
         {
-          double
-            threshold;
-
-          threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
-          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",option) == 0)
+      if (LocaleCompare("sepia-tone",option+1) == 0)
         {
-          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);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
+                 (double) QuantumRange+1.0),_exception);
           break;
         }
-      if (LocaleCompare("set",option) == 0)
+      if (LocaleCompare("set",option+1) == 0)
         {
           char
             *value;
 
-          if (plus_alt_op != MagickFalse)
-            {
+          if (IfPlusOp) {
               if (LocaleNCompare(arg1,"registry:",9) == 0)
                 (void) DeleteImageRegistry(arg1+9);
               else
                 if (LocaleNCompare(arg1,"option:",7) == 0)
                   {
-                    (void) DeleteImageOption(image_info,arg1+7);
-                    (void) DeleteImageArtifact(image,arg1+7);
+                    (void) DeleteImageOption(_image_info,arg1+7);
+                    (void) DeleteImageArtifact(_image,arg1+7);
                   }
                 else
-                  (void) DeleteImageProperty(image,arg1);
+                  (void) DeleteImageProperty(_image,arg1);
               break;
             }
-          value=InterpretImageProperties(image_info,image,arg2,
-            exception);
+          value=InterpretImageProperties(_image_info,_image,arg2,_exception);
           if (value == (char *) NULL)
             break;
           if (LocaleNCompare(arg1,"registry:",9) == 0)
-            (void) SetImageRegistry(StringRegistryType,arg1+9,value,
-              exception);
+            (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
           else
             if (LocaleNCompare(arg1,"option:",7) == 0)
               {
-                (void) SetImageOption(image_info,arg1+7,value);
-                (void) SetImageArtifact(image,arg1+7,value);
+                (void) SetImageOption(_image_info,arg1+7,value);
+                (void) SetImageArtifact(_image,arg1+7,value);
               }
             else
-              (void) SetImageProperty(image,arg1,value,exception);
+              (void) SetImageProperty(_image,arg1,value,_exception);
           value=DestroyString(value);
           break;
         }
-      if (LocaleCompare("shade",option) == 0)
+      if (LocaleCompare("shade",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
-          new_image=ShadeImage(image,normal_op,geometry_info.rho,
-               geometry_info.sigma,exception);
+          new_image=ShadeImage(_image,normal_op,geometry_info.rho,
+               geometry_info.sigma,_exception);
           break;
         }
-      if (LocaleCompare("shadow",option) == 0)
+      if (LocaleCompare("shadow",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
@@ -3004,209 +3202,237 @@ static void WandSimpleOperatorImage(MagickWand *wand,
             geometry_info.xi=4.0;
           if ((flags & PsiValue) == 0)
             geometry_info.psi=4.0;
-          new_image=ShadowImage(image,geometry_info.rho,
-            geometry_info.sigma,image->bias,(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",option) == 0)
+      if (LocaleCompare("sharpen",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           if ((flags & 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",option) == 0)
+      if (LocaleCompare("shave",option+1) == 0)
         {
-          flags=ParsePageGeometry(image,arg1,&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",option) == 0)
+      if (LocaleCompare("shear",option+1) == 0)
         {
+          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",option) == 0)
+      if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
         {
+          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,normal_op,geometry_info.rho,
+          (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
                geometry_info.sigma,
-            exception);
+            _exception);
           break;
         }
-      if (LocaleCompare("sketch",option) == 0)
+      if (LocaleCompare("sketch",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
-          new_image=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",option) == 0)
+      if (LocaleCompare("solarize",option+1) == 0)
         {
-          (void) SolarizeImage(image,StringToDoubleInterval(arg1,(double)
-                 QuantumRange+1.0),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",option) == 0)
+      if (LocaleCompare("sparse-color",option+1) == 0)
         {
-          SparseColorMethod
-            method;
-
           char
             *arguments;
 
-          method=(SparseColorMethod) ParseCommandOption(
-            MagickSparseColorOptions,MagickFalse,arg1);
-          arguments=InterpretImageProperties(image_info,image,arg2,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,exception);
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
+          new_image=SparseColorOption(_image,(SparseColorMethod)parse,
+               arguments,_exception);
           arguments=DestroyString(arguments);
           break;
         }
-      if (LocaleCompare("splice",option) == 0)
+      if (LocaleCompare("splice",option+1) == 0)
         {
-          (void) ParseGravityGeometry(image,arg1,&geometry,exception);
-          new_image=SpliceImage(image,&geometry,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("spread",option) == 0)
+      if (LocaleCompare("spread",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           (void) ParseGeometry(arg1,&geometry_info);
-          new_image=SpreadImage(image,geometry_info.rho,image->interpolate,
-               exception);
+          new_image=SpreadImage(_image,geometry_info.rho,_image->interpolate,
+               _exception);
           break;
         }
-      if (LocaleCompare("statistic",option) == 0)
+      if (LocaleCompare("statistic",option+1) == 0)
         {
-          StatisticType
-            type;
-
-          type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
-            MagickFalse,arg1);
+          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,type,(size_t) geometry_info.rho,
-            (size_t) geometry_info.sigma,exception);
+          new_image=StatisticImage(_image,(StatisticType)parse,
+               (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
+               _exception);
           break;
         }
-      if (LocaleCompare("strip",option) == 0)
+      if (LocaleCompare("strip",option+1) == 0)
         {
-          (void) StripImage(image,exception);
+          (void) StripImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("swirl",option) == 0)
+      if (LocaleCompare("swirl",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           (void) ParseGeometry(arg1,&geometry_info);
-          new_image=SwirlImage(image,geometry_info.rho,
-            image->interpolate,exception);
+          new_image=SwirlImage(_image,geometry_info.rho,
+            _image->interpolate,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 't':
     {
-      if (LocaleCompare("threshold",option) == 0)
+      if (LocaleCompare("threshold",option+1) == 0)
         {
           double
             threshold;
 
-          if (plus_alt_op != MagickFalse)
-            threshold=(double) QuantumRange/2;
-          else
+          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);
+          }
+          (void) BilevelImage(_image,threshold,_exception);
           break;
         }
-      if (LocaleCompare("thumbnail",option) == 0)
+      if (LocaleCompare("thumbnail",option+1) == 0)
         {
-          (void) ParseRegionGeometry(image,arg1,&geometry,exception);
-          new_image=ThumbnailImage(image,geometry.width,geometry.height,
-            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",option) == 0)
+      if (LocaleCompare("tint",option+1) == 0)
         {
-          new_image=TintImage(image,arg1,&draw_info->fill,exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
           break;
         }
-      if (LocaleCompare("transform",option) == 0)
+      if (LocaleCompare("transform",option+1) == 0)
         {
-          /* DEPRECIATED */
-          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",option) == 0)
+      if (LocaleCompare("transparent",option+1) == 0)
         {
           PixelInfo
             target;
 
-          (void) QueryColorCompliance(arg1,AllCompliance,&target,exception);
-          (void) TransparentPaintImage(image,&target,(Quantum)
-            TransparentAlpha,plus_alt_op,exception);
+          (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
+          (void) TransparentPaintImage(_image,&target,(Quantum)
+            TransparentAlpha,plus_alt_op,_exception);
           break;
         }
-      if (LocaleCompare("transpose",option) == 0)
+      if (LocaleCompare("transpose",option+1) == 0)
         {
-          new_image=TransposeImage(image,exception);
+          new_image=TransposeImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("transverse",option) == 0)
+      if (LocaleCompare("transverse",option+1) == 0)
         {
-          new_image=TransverseImage(image,exception);
+          new_image=TransverseImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("trim",option) == 0)
+      if (LocaleCompare("trim",option+1) == 0)
         {
-          new_image=TrimImage(image,exception);
+          new_image=TrimImage(_image,_exception);
           break;
         }
-      if (LocaleCompare("type",option) == 0)
+      if (LocaleCompare("type",option+1) == 0)
         {
           /* Note that "type" setting should have already been defined */
-          (void) SetImageType(image,image_info->type,exception);
+          (void) SetImageType(_image,_image_info->type,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'u':
     {
-      if (LocaleCompare("unique",option) == 0)
+      if (LocaleCompare("unique",option+1) == 0)
         {
-          /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
-          if (plus_alt_op != MagickFalse)
-            {
-              (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",option) == 0)
+      if (LocaleCompare("unique-colors",option+1) == 0)
         {
-          new_image=UniqueImageColors(image,exception);
+          new_image=UniqueImageColors(_image,_exception);
           break;
         }
-      if (LocaleCompare("unsharp",option) == 0)
+      if (LocaleCompare("unsharp",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
@@ -3214,104 +3440,120 @@ static void WandSimpleOperatorImage(MagickWand *wand,
             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",option) == 0)
+      if (LocaleCompare("verbose",option+1) == 0)
         {
-          /* FUTURE: move to SyncImageSettings() and AcqireImage()???
-             three places!   ImageArtifact   ImageOption  image_info->verbose
-             Some how new images also get this artifact -- how???
+          /* 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,
-                 (plus_alt_op != MagickFalse) ? "false" : "true" );
+          (void) SetImageArtifact(_image,option+1,
+                           IfNormalOp ? "true" : "false" );
           break;
         }
-      if (LocaleCompare("vignette",option) == 0)
+      if (LocaleCompare("vignette",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
           if ((flags & 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,
-            image->bias,(ssize_t) ceil(geometry_info.xi-0.5),
-            (ssize_t) ceil(geometry_info.psi-0.5),exception);
+            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",option) == 0)
+      if (LocaleCompare("wave",option+1) == 0)
         {
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=1.0;
-          new_image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
-               image->interpolate,exception);
+          new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
+               _image->interpolate,_exception);
           break;
         }
-      if (LocaleCompare("white-threshold",option) == 0)
+      if (LocaleCompare("white-threshold",option+1) == 0)
         {
-          (void) WhiteThresholdImage(image,arg1,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 _image_info
+#undef _draw_info
+#undef _quantize_info
+#undef _image
+#undef _exception
+#undef IfNormalOp
+#undef IfPlusOp
 #undef normal_op
+#undef plus_alt_op
 }
 
-WandExport void WandSimpleOperatorImages(MagickWand *wand,
-  const MagickBooleanType plus_alt_op, const char *option,
-  const char *arg1, const char *arg2)
+WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
+  const char *option, const char *arg1, const char *arg2)
 {
   size_t
-    n;
-
-  register ssize_t
+    n,
     i;
 
-  assert(wand->image_info != (const ImageInfo *) NULL);
-  assert(wand->image_info->signature == MagickSignature);
-  assert(wand->draw_info != (DrawInfo *) NULL);   /* ensure it is a CLI wand */
-  assert(wand->images != (Image *) NULL);         /* there is one image */
+  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(wand->images);
-  wand->images=GetFirstImageInList(wand->images);
-  for ( ; ; )
-  {
-    WandSimpleOperatorImage(wand, plus_alt_op, option, arg1, arg2);
-    if ( wand->images->next == (Image *) NULL )
-      break;
-    wand->images=wand->images->next;
+  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;
   }
-  wand->images=GetFirstImageInList(wand->images);
+  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
@@ -3320,108 +3562,145 @@ WandExport void WandSimpleOperatorImages(MagickWand *wand,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+     W a n d L i s t O p e r a t o r 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                               %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  WandListOperatorImages() applies a single operation that is apply to the
+%  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:
 %
-%    void WandListOperatorImages(MagickWand *wand,
-%        const MagickBooleanType plus_alt_op, const char *option,
-%        const char *arg1, const char *arg2)
+%    void CLIListOperatorImages(MagickCLI *cli_wand,
+%        const char *option, const char *arg1, const char *arg2)
 %
 %  A description of each parameter follows:
 %
-%    o wand: structure holding settings to be applied
-%
-%    o plus_alt_op:  request the 'plus' or alturnative form of the operation
+%    o cli_wand: structure holding settings to be applied
 %
 %    o option:  The option string for the operation
 %
 %    o arg1, arg2: optional argument strings to the operation
+%        arg2 is currently not used
+%
+% Example usage...
+%
+%  CLIListOperatorImages(cli_wand,MagickFalse,"-duplicate", "3",  NULL);
+%  CLIListOperatorImages(cli_wand,MagickTrue, "+append",    NULL, NULL);
+%
+% Or for handling command line arguments EG: +/-option ["arg1"]
+%
+%    cli_wand
+%    argc,argv
+%    i=index in argv
+%
+%    option_info = GetCommandOptionInfo(argv[i]);
+%    count=option_info->type;
+%    option_type=option_info->flags;
+%
+%    if ( (option_type & ListOperatorOptionFlag) != 0 )
+%      CLIListOperatorImages(cli_wand,argv[i],
+%          count>=1 ? argv[i+1] : (char *)NULL,
+%          count>=2 ? argv[i+2] : (char *)NULL );
+%    i += count+1;
 %
 */
-WandExport void WandListOperatorImages(MagickWand *wand,
-  const MagickBooleanType plus_alt_op, const char *option,
-  const char *arg1, const char *arg2)
+WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
+     const char *option,const char *arg1, const char *magick_unused(arg2))
 {
+  ssize_t
+    parse;
+
   Image
     *new_images;
 
-#define image_info      (wand->image_info)
-#define draw_info       (wand->draw_info)
-#define quantize_info   (wand->quantize_info)
-#define images          (wand->images)
-#define exception       (wand->exception)
-#define normal_op       (plus_alt_op?MagickFalse:MagickTrue)
-
-  assert(image_info != (const ImageInfo *) NULL);
-  assert(image_info->signature == MagickSignature);
-  assert(draw_info != (DrawInfo *) NULL);       /* ensure it is a CLI wand */
-  assert(images != (Image *) NULL);             /* there is an image */
-  assert(images->signature == MagickSignature); /* and is a valid image */
+#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)
 
-  if (wand->debug != MagickFalse)
-    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
+  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);
 
-  (void) SyncImagesSettings(image_info,images,exception);
+  (void) SyncImagesSettings(_image_info,_images,_exception);
 
   new_images=NewImageList();
 
-  switch (*option)
+  switch (*(option+1))
   {
     case 'a':
     {
-      if (LocaleCompare("append",option) == 0)
+      if (LocaleCompare("append",option+1) == 0)
         {
-          new_images=AppendImages(images,normal_op,exception);
+          new_images=AppendImages(_images,normal_op,_exception);
           break;
         }
-      if (LocaleCompare("average",option) == 0)
+      if (LocaleCompare("average",option+1) == 0)
         {
           /* DEPRECIATED - use -evaluate-sequence Mean */
-          WandListOperatorImages(wand,plus_alt_op,"evaluate-sequence","Mean",
-               NULL);
+          CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'c':
     {
-      if (LocaleCompare("clut",option) == 0)
+      if (LocaleCompare("channel-fx",option+1) == 0)
+        {
+          new_images=ChannelFxImage(_images,arg1,_exception);
+          break;
+        }
+      if (LocaleCompare("clut",option+1) == 0)
         {
-          /* FUTURE - make this a compose option (and thus layers compose )
-             or perhaps compose last image over all other images.
-          */
           Image
             *clut_image;
 
-          new_images=RemoveFirstImageFromList(&images);
-          clut_image=RemoveLastImageFromList(&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)
-              break;
-          (void) ClutImage(new_images,clut_image,images->interpolate,exception);
+            break;
+          (void) ClutImage(new_images,clut_image,new_images->interpolate,_exception);
           clut_image=DestroyImage(clut_image);
           break;
         }
-      if (LocaleCompare("coalesce",option) == 0)
+      if (LocaleCompare("coalesce",option+1) == 0)
         {
-          new_images=CoalesceImages(images,exception);
+          new_images=CoalesceImages(_images,_exception);
           break;
         }
-      if (LocaleCompare("combine",option) == 0)
+      if (LocaleCompare("combine",option+1) == 0)
         {
-          new_images=CombineImages(images,exception);
+          /* FUTURE - this may be replaced by a 'channel' method */
+          new_images=CombineImages(_images,_exception);
           break;
         }
-      if (LocaleCompare("composite",option) == 0)
+      if (LocaleCompare("composite",option+1) == 0)
         {
+          CompositeOperator
+            compose;
+
+          const char*
+            value;
+
+          MagickBooleanType
+            clip_to_self;
+
           Image
             *mask_image,
             *source_image;
@@ -3429,84 +3708,85 @@ WandExport void WandListOperatorImages(MagickWand *wand,
           RectangleInfo
             geometry;
 
-          CompositeOperator
-            compose;
-
-          const char*
-            value;
+          /* 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);
 
-          value=GetImageOption(image_info,"compose");
-          if (value != (const char *) NULL)
-            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
-            compose=OverCompositeOp;  /* use Over not source_image->compose */
+            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);
+          new_images=RemoveFirstImageFromList(&_images);
+          source_image=RemoveFirstImageFromList(&_images);
           if (source_image == (Image *) NULL)
-            break;
+            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);
+            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);
+          mask_image=RemoveFirstImageFromList(&_images);
           if (mask_image != (Image *) NULL)
             { /* handle a third write mask image */
               if ((compose == DisplaceCompositeOp) ||
-                  (compose == DistortCompositeOp))
-                { /* Merge Y displacement into X displace/distort map. */
-                  (void) CompositeImage(source_image,CopyGreenCompositeOp,
-                    mask_image,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);
-                }
+                  (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,compose,source_image,geometry.x,
-                     geometry.y,exception);
-          (void) SetImageMask(new_images,(Image *) NULL,exception);
+          (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",option) == 0)
+      if (LocaleCompare("deconstruct",option+1) == 0)
         {
           /* DEPRECIATED - use -layers CompareAny */
-          WandListOperatorImages(wand,plus_alt_op,"layer","CompareAny",NULL);
+          CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
           break;
         }
-      if (LocaleCompare("delete",option) == 0)
+      if (LocaleCompare("delete",option+1) == 0)
         {
-          if (plus_alt_op != MagickFalse)
-            DeleteImages(&images,"-1",exception);
+          if (IfNormalOp)
+            DeleteImages(&_images,arg1,_exception);
           else
-            DeleteImages(&images,arg1,exception);
+            DeleteImages(&_images,"-1",_exception);
           break;
         }
-      if (LocaleCompare("duplicate",option) == 0)
+      if (LocaleCompare("duplicate",option+1) == 0)
         {
-          Image
-            *duplicate_images;
-
-          if (plus_alt_op != MagickFalse)
-            duplicate_images=DuplicateImages(images,1,"-1",exception);
-          else
+          if (IfNormalOp)
             {
               const char
                 *p;
@@ -3514,93 +3794,100 @@ WandExport void WandListOperatorImages(MagickWand *wand,
               size_t
                 number_duplicates;
 
+              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);
+          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",option) == 0)
+      if (LocaleCompare("evaluate-sequence",option+1) == 0)
         {
-          MagickEvaluateOperator
-            method;
-
-          method=(MagickEvaluateOperator) ParseCommandOption(
-            MagickEvaluateOptions,MagickFalse,arg1);
-          new_images=EvaluateImages(images,method,exception);
+          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",option) == 0)
+      if (LocaleCompare("fft",option+1) == 0)
         {
-          new_images=ForwardFourierTransformImage(images,normal_op,exception);
+          new_images=ForwardFourierTransformImage(_images,normal_op,_exception);
           break;
         }
-      if (LocaleCompare("flatten",option) == 0)
+      if (LocaleCompare("flatten",option+1) == 0)
         {
-          /* DEPRECIATED use -layers mosaic instead */
-          WandListOperatorImages(wand,plus_alt_op,"layer",option,NULL);
+          /* REDIRECTED to use -layers flatten instead */
+          CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
           break;
         }
-      if (LocaleCompare("fx",option) == 0)
+      if (LocaleCompare("fx",option+1) == 0)
         {
-          new_images=FxImage(images,arg1,exception);
+          new_images=FxImage(_images,arg1,_exception);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'h':
     {
-      if (LocaleCompare("hald-clut",option) == 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.
+             or perhaps compose last image over all other _images.
           */
           Image
             *hald_image;
 
-          new_images=RemoveFirstImageFromList(&images);
-          hald_image=RemoveLastImageFromList(&images);
+          new_images=RemoveFirstImageFromList(&_images);
+          hald_image=RemoveLastImageFromList(&_images);
           if (hald_image == (Image *) NULL)
             break;
-          (void) HaldClutImage(new_images,hald_image,exception);
+          (void) HaldClutImage(new_images,hald_image,_exception);
           hald_image=DestroyImage(hald_image);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'i':
     {
-      if (LocaleCompare("ift",option) == 0)
+      if (LocaleCompare("ift",option+1) == 0)
         {
           Image
             *magnitude_image,
             *phase_image;
 
-           magnitude_image=RemoveFirstImageFromList(&images);
-           phase_image=RemoveFirstImageFromList(&images);
+           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);
+                   normal_op,_exception);
            magnitude_image=DestroyImage(magnitude_image);
            phase_image=DestroyImage(phase_image);
           break;
         }
-      if (LocaleCompare("insert",option) == 0)
+      if (LocaleCompare("insert",option+1) == 0)
         {
           Image
             *insert_image,
@@ -3609,45 +3896,42 @@ WandExport void WandListOperatorImages(MagickWand *wand,
           ssize_t
             index;
 
+          if (IfNormalOp && IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           index=0;
-          insert_image=RemoveLastImageFromList(&images);
-          if (plus_alt_op == MagickFalse)
+          insert_image=RemoveLastImageFromList(&_images);
+          if (IfNormalOp)
             index=(ssize_t) StringToLong(arg1);
+          index_image=insert_image;
           if (index == 0)
-            PrependImageToList(&images,insert_image);
+            PrependImageToList(&_images,insert_image);
+          else if (index == (ssize_t) GetImageListLength(_images))
+            AppendImageToList(&_images,insert_image);
           else
-            if (index == (ssize_t) GetImageListLength(images))
-              AppendImageToList(&images,insert_image);
-            else
-              {
-                 index_image=GetImageFromList(images,index-1);
-                 if (index_image == (Image *) NULL)
-                   {
-                     (void) ThrowMagickException(exception,GetMagickModule(),
-                       OptionError,"NoSuchImage","`%s'",arg1);
-                     break;
-                   }
-                InsertImageInList(&index_image,insert_image);
-              }
-          images=GetFirstImageInList(index_image);
+            {
+               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",option) == 0)
+      if (LocaleCompare("layers",option+1) == 0)
         {
-          ImageLayerMethod
-            method;
-
-          method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
-            MagickFalse,arg1);
-          switch (method)
+          parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
+                 option,arg1);
+          switch ((ImageLayerMethod) parse)
           {
             case CoalesceLayer:
             {
-              new_images=CoalesceImages(images,exception);
+              new_images=CoalesceImages(_images,_exception);
               break;
             }
             case CompareAnyLayer:
@@ -3655,7 +3939,8 @@ WandExport void WandListOperatorImages(MagickWand *wand,
             case CompareOverlayLayer:
             default:
             {
-              new_images=CompareImagesLayers(images,method,exception);
+              new_images=CompareImagesLayers(_images,(ImageLayerMethod) parse,
+                   _exception);
               break;
             }
             case MergeLayer:
@@ -3663,52 +3948,53 @@ WandExport void WandListOperatorImages(MagickWand *wand,
             case MosaicLayer:
             case TrimBoundsLayer:
             {
-              new_images=MergeImageLayers(images,method,exception);
+              new_images=MergeImageLayers(_images,(ImageLayerMethod) parse,
+                   _exception);
               break;
             }
             case DisposeLayer:
             {
-              new_images=DisposeImages(images,exception);
+              new_images=DisposeImages(_images,_exception);
               break;
             }
             case OptimizeImageLayer:
             {
-              new_images=OptimizeImageLayers(images,exception);
+              new_images=OptimizeImageLayers(_images,_exception);
               break;
             }
             case OptimizePlusLayer:
             {
-              new_images=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.  */
-              new_images=CoalesceImages(images,exception);
+              new_images=CoalesceImages(_images,_exception);
               if (new_images == (Image *) NULL)
                 break;
-              images=DestroyImageList(images);
-              images=OptimizeImageLayers(new_images,exception);
-              if (images == (Image *) NULL)
+              _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);
+              OptimizeImageTransparency(_images,_exception);
+              (void) RemapImages(_quantize_info,_images,(Image *) NULL,
+                _exception);
               break;
             }
             case CompositeLayer:
@@ -3725,14 +4011,14 @@ WandExport void WandListOperatorImages(MagickWand *wand,
               const char*
                 value;
 
-              value=GetImageOption(image_info,"compose");
+              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;
+              source=_images;
               while (source != (Image *) NULL)
               {
                 source=GetNextImageInList(source);
@@ -3753,93 +4039,79 @@ WandExport void WandListOperatorImages(MagickWand *wand,
                 }
               if (source == (Image *) NULL)
                 {
-                  (void) ThrowMagickException(exception,GetMagickModule(),
+                  (void) ThrowMagickException(_exception,GetMagickModule(),
                     OptionError,"MissingNullSeparator","layers Composite");
                   break;
                 }
               /* Adjust offset with gravity and virtual canvas.  */
-              SetGeometry(images,&geometry);
-              (void) ParseAbsoluteGeometry(images->geometry,&geometry);
+              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);
+              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);
+              CompositeLayers(_images,compose,source,geometry.x,geometry.y,
+                _exception);
               source=DestroyImageList(source);
               break;
             }
           }
           break;
         }
-      if (LocaleCompare("limit",option) == 0)
-        {
-          MagickSizeType
-            limit;
-
-          ResourceType
-            type;
-
-          type=(ResourceType) ParseCommandOption(MagickResourceOptions,
-            MagickFalse,arg1);
-          limit=MagickResourceInfinity;
-          if (LocaleCompare("unlimited",arg2) != 0)
-            limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
-          (void) SetMagickResourceLimit(type,limit);
-          break;
-        }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'm':
     {
-      if (LocaleCompare("map",option) == 0)
+      if (LocaleCompare("map",option+1) == 0)
         {
           /* DEPRECIATED use +remap */
-          (void) RemapImages(quantize_info,images,(Image *) NULL,exception);
+          (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
           break;
         }
-      if (LocaleCompare("morph",option) == 0)
+      if (LocaleCompare("morph",option+1) == 0)
         {
           Image
             *morph_image;
 
-          morph_image=MorphImages(images,StringToUnsignedLong(arg1),
-            exception);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
+            _exception);
           if (morph_image == (Image *) NULL)
             break;
-          images=DestroyImageList(images);
-          images=morph_image;
+          _images=DestroyImageList(_images);
+          _images=morph_image;
           break;
         }
-      if (LocaleCompare("mosaic",option) == 0)
+      if (LocaleCompare("mosaic",option+1) == 0)
         {
-          /* DEPRECIATED use -layers mosaic instead */
-          WandListOperatorImages(wand,plus_alt_op,"layer",option,NULL);
+          /* REDIRECTED to use -layers mosaic instead */
+          CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'p':
     {
-      if (LocaleCompare("print",option) == 0)
+      if (LocaleCompare("print",option+1) == 0)
         {
           char
             *string;
 
-          string=InterpretImageProperties(image_info,images,arg1,
-            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",option) == 0)
+      if (LocaleCompare("process",option+1) == 0)
         {
           char
             **arguments;
@@ -3872,7 +4144,7 @@ WandExport void WandListOperatorImages(MagickWand *wand,
                 *token_info;
 
               /*
-                Support old style syntax, filter="-option arg".
+                Support old style syntax, filter="-option arg1".
               */
               length=strlen(arg1);
               token=(char *) NULL;
@@ -3893,40 +4165,39 @@ WandExport void WandListOperatorImages(MagickWand *wand,
                     *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("remap",option) == 0)
+      if (LocaleCompare("remap",option+1) == 0)
         {
-              (void) RemapImages(quantize_info,images,(Image *) NULL,exception);
-          (void) RemapImages(quantize_info,images,(Image *) NULL,exception);
+          (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
           break;
         }
-      if (LocaleCompare("reverse",option) == 0)
+      if (LocaleCompare("reverse",option+1) == 0)
         {
-          ReverseImageList(&images);
+          ReverseImageList(&_images);
           break;
         }
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 's':
     {
-      if (LocaleCompare("smush",option) == 0)
+      if (LocaleCompare("smush",option+1) == 0)
         {
           Image
             *smush_image;
@@ -3934,101 +4205,472 @@ WandExport void WandListOperatorImages(MagickWand *wand,
           ssize_t
             offset;
 
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
           offset=(ssize_t) StringToLong(arg1);
-          smush_image=SmushImages(images,normal_op,offset,exception);
+          smush_image=SmushImages(_images,normal_op,offset,_exception);
           if (smush_image == (Image *) NULL)
             break;
-          images=DestroyImageList(images);
-          images=smush_image;
+          _images=DestroyImageList(_images);
+          _images=smush_image;
           break;
         }
-      if (LocaleCompare("swap",option) == 0)
-        {
-          Image
-            *p,
-            *q,
-            *swap;
+      if (LocaleCompare("swap",option+1) == 0) {
+        Image
+          *p,
+          *q,
+          *swap;
 
-          ssize_t
-            index,
-            swap_index;
-
-          index=-1;
-          swap_index=-2;
-          if (plus_alt_op == MagickFalse)
-            {
-              GeometryInfo
-                geometry_info;
-
-              MagickStatusType
-                flags;
-
-              swap_index=(-1);
-              flags=ParseGeometry(arg1,&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);
-              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;
-        }
-      break;
-    }
-    case 'w':
-    {
-      if (LocaleCompare("write",option) == 0)
-        {
-          char
-            key[MaxTextExtent];
+        ssize_t
+          index,
+          swap_index;
 
-          Image
-            *write_images;
+        index=-1;
+        swap_index=-2;
+        if (IfNormalOp) {
+          GeometryInfo
+            geometry_info;
 
-          ImageInfo
-            *write_info;
+          MagickStatusType
+            flags;
 
-          (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
-          (void) DeleteImageRegistry(key);
-          write_images=images;
-          if (plus_alt_op != MagickFalse)
-            write_images=CloneImageList(images,exception);
-          write_info=CloneImageInfo(image_info);
-          (void) WriteImages(write_info,write_images,arg1,exception);
-          write_info=DestroyImageInfo(write_info);
-          if (plus_alt_op != MagickFalse)
-            write_images=DestroyImageList(write_images);
-          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);
     }
     default:
-      break;
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
   }
   if (new_images == (Image *) NULL)
     return;
 
-  if (images != (Image *) NULL)
-    images=DestroyImageList(images);
-  images=new_images;
+  if (_images != (Image *) NULL)
+    _images=DestroyImageList(_images);
+  _images=GetFirstImageInList(new_images);
   return;
 
-#undef image_info
-#undef draw_info
-#undef quantize_info
-#undef images
-#undef exception
+#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;
+%
+*/
+
+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!='-')
+
+  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);
+
+  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
+    }
+    /* FUTURE: how do I free the expanded filename arguments??? */
+
+    return;
+  }
+  /*
+    Image Writing  (no-images present is valid in specific cases)
+  */
+  if (LocaleCompare("write",option+1) == 0) {
+    char
+      key[MaxTextExtent];
+
+    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
+}