]> granicus.if.org Git - imagemagick/blobdiff - MagickWand/operation.c
Revert -spread behavior
[imagemagick] / MagickWand / operation.c
index d9e0c10bb49c10899650c70b9f5ff65d18e97800..e2174a8fc1c2b86d7cd25ab1490ffaf0966e3e45 100644 (file)
@@ -92,8 +92,8 @@ static MagickBooleanType MonitorProgress(const char *text,
   void *wand_unused(cli_wandent_data))
 {
   char
-    message[MaxTextExtent],
-    tag[MaxTextExtent];
+    message[MagickPathExtent],
+    tag[MagickPathExtent];
 
   const char
     *locale_message;
@@ -103,11 +103,11 @@ static MagickBooleanType MonitorProgress(const char *text,
 
   if (extent < 2)
     return(MagickTrue);
-  (void) CopyMagickMemory(tag,text,MaxTextExtent);
+  (void) CopyMagickMemory(tag,text,MagickPathExtent);
   p=strrchr(tag,'/');
   if (p != (char *) NULL)
     *p='\0';
-  (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
+  (void) FormatLocaleString(message,MagickPathExtent,"Monitor/%s",tag);
   locale_message=GetLocaleMessage(message);
   if (locale_message == message)
     locale_message=tag;
@@ -133,7 +133,7 @@ static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
   ExceptionInfo *exception)
 {
   char
-    key[MaxTextExtent];
+    key[MagickPathExtent];
 
   ExceptionInfo
     *sans_exception;
@@ -144,7 +144,7 @@ static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
   ImageInfo
     *read_info;
 
-  (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
+  (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",path);
   sans_exception=AcquireExceptionInfo();
   image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
   sans_exception=DestroyExceptionInfo(sans_exception);
@@ -152,7 +152,7 @@ static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
     return(image);
   read_info=CloneImageInfo(image_info);
   if (path != (const char *) NULL)
-    (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
+    (void) CopyMagickString(read_info->filename,path,MagickPathExtent);
   image=ReadImage(read_info,exception);
   read_info=DestroyImageInfo(read_info);
   if (image != (Image *) NULL)
@@ -174,7 +174,7 @@ static Image *SparseColorOption(const Image *image,
   const SparseColorMethod method,const char *arguments,ExceptionInfo *exception)
 {
   char
-    token[MaxTextExtent];
+    token[MagickPathExtent];
 
   const char
     *p;
@@ -199,11 +199,11 @@ static Image *SparseColorOption(const Image *image,
     number_colors;
 
   assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
+  assert(image->signature == MagickCoreSignature);
   if (IfMagickTrue(image->debug))
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(exception != (ExceptionInfo *) NULL);
-  assert(exception->signature == MagickSignature);
+  assert(exception->signature == MagickCoreSignature);
   /*
     Limit channels according to image
     add up number of values needed per color.
@@ -237,14 +237,15 @@ static Image *SparseColorOption(const Image *image,
       x++;   /* floating point argument */
   }
   /* control points and color values */
-  error = IsMagickTrue( x % (2+number_colors) );
+  if ((x % (2+number_colors)) != 0)
+    {
+      (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+        "InvalidArgument","'%s': %s", "sparse-color",
+        "Invalid number of Arguments");
+      return( (Image *) NULL);
+    }
+  error=MagickFalse;
   number_arguments=x;
-  if ( IfMagickTrue(error) ) {
-    (void) ThrowMagickException(exception,GetMagickModule(),
-               OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
-               "Invalid number of Arguments");
-    return( (Image *)NULL);
-  }
 
   /* Allocate and fill in the floating point arguments */
   sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
@@ -252,7 +253,7 @@ static Image *SparseColorOption(const Image *image,
   if (sparse_arguments == (double *) NULL) {
     (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
       "MemoryAllocationFailed","%s","SparseColorOption");
-    return( (Image *)NULL);
+    return( (Image *) NULL);
   }
   (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
     sizeof(*sparse_arguments));
@@ -266,7 +267,7 @@ static Image *SparseColorOption(const Image *image,
       (void) ThrowMagickException(exception,GetMagickModule(),
             OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
             "Color found, instead of X-coord");
-      error = MagickTrue;
+      error=MagickTrue;
       break;
     }
     sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
@@ -277,7 +278,7 @@ static Image *SparseColorOption(const Image *image,
       (void) ThrowMagickException(exception,GetMagickModule(),
             OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
             "Color found, instead of Y-coord");
-      error = MagickTrue;
+      error=MagickTrue;
       break;
     }
     sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
@@ -348,15 +349,18 @@ static Image *SparseColorOption(const Image *image,
       }
     }
   }
-  if ( number_arguments != x && !error ) {
-    (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
-      "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
-    sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
-    return( (Image *)NULL);
-  }
-  if ( error )
-    return( (Image *)NULL);
-
+  if (error != MagickFalse)
+    {
+      sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
+      return((Image *) NULL);
+    }
+  if (number_arguments != x)
+    {
+      sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
+      (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+        "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
+      return((Image *) NULL);
+    }
   /* Call the Sparse Color Interpolation function with the parsed arguments */
   sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
     exception);
@@ -417,14 +421,14 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
 #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 ArgBoolean        IfSetOption ? MagickTrue : MagickFalse
+#define ArgBooleanNot     IfSetOption ? MagickFalse : MagickTrue
 #define ArgBooleanString  (IfSetOption?"true":"false")
 #define ArgOption(def)    (IfSetOption?arg1:(const char *)(def))
 
   assert(cli_wand != (MagickCLI *) NULL);
-  assert(cli_wand->signature == WandSignature);
-  assert(cli_wand->wand.signature == WandSignature);
+  assert(cli_wand->signature == MagickWandSignature);
+  assert(cli_wand->wand.signature == MagickWandSignature);
 
   if (IfMagickTrue(cli_wand->wand.debug))
     (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
@@ -692,7 +696,7 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
           /* DefineImageOption() equals SetImageOption() but with '=' */
           if (IfSetOption)
             (void) DefineImageOption(_image_info,arg1);
-          else if (IsMagickFalse(DeleteImageOption(_image_info,arg1)))
+          else if (DeleteImageOption(_image_info,arg1) == MagickFalse)
             CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
           break;
         }
@@ -1160,7 +1164,7 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
           */
           char
             *canonical_page,
-            page[MaxTextExtent];
+            page[MagickPathExtent];
 
           const char
             *image_option;
@@ -1184,10 +1188,10 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
           canonical_page=GetPageGeometry(arg1);
           flags=ParseAbsoluteGeometry(canonical_page,&geometry);
           canonical_page=DestroyString(canonical_page);
-          (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
+          (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu",
             (unsigned long) geometry.width,(unsigned long) geometry.height);
           if (((flags & XValue) != 0) || ((flags & YValue) != 0))
-            (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
+            (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu%+ld%+ld",
               (unsigned long) geometry.width,(unsigned long) geometry.height,
               (long) geometry.x,(long) geometry.y);
           (void) SetImageOption(_image_info,option+1,page);
@@ -1558,23 +1562,13 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
     {
       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)
-          */
-          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;
+          ssize_t
+            weight;
+
+          weight=ParseCommandOption(MagickWeightOptions,MagickFalse,arg1);
+          if (weight == -1)
+            weight=StringToUnsignedLong(arg1);
+          _draw_info->weight=(size_t) weight;
           break;
         }
       if (LocaleCompare("white-point",option+1) == 0)
@@ -1595,10 +1589,10 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
   }
 
   /* clean up percent escape interpreted strings */
-  if (arg1 != arg1n )
-    arg1=DestroyString((char *)arg1);
-  if (arg2 != arg2n )
-    arg2=DestroyString((char *)arg2);
+  if ((arg1 && arg1n) && (arg1 != arg1n ))
+    arg1=DestroyString((char *) arg1);
+  if ((arg2 && arg2n) && (arg2 != arg2n ))
+    arg2=DestroyString((char *) arg2);
 
 #undef _image_info
 #undef _exception
@@ -1694,12 +1688,12 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
 #define _option_type      ((CommandOptionFlags) cli_wand->command->flags)
 #define IfNormalOp        (*option=='-')
 #define IfPlusOp          (*option!='-')
-#define IsNormalOp        IsMagickTrue(IfNormalOp)
-#define IsPlusOp          IsMagickFalse(IfNormalOp)
+#define IsNormalOp        IfNormalOp ? MagickTrue : MagickFalse
+#define IsPlusOp          IfNormalOp ? MagickFalse : MagickTrue
 
   assert(cli_wand != (MagickCLI *) NULL);
-  assert(cli_wand->signature == WandSignature);
-  assert(cli_wand->wand.signature == WandSignature);
+  assert(cli_wand->signature == MagickWandSignature);
+  assert(cli_wand->wand.signature == MagickWandSignature);
   assert(_image != (Image *) NULL);             /* an image must be present */
   if (IfMagickTrue(cli_wand->wand.debug))
     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
@@ -1735,7 +1729,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
     "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
 #endif
 
-  new_image = (Image *)NULL; /* the replacement image, if not null at end */
+  new_image = (Image *) NULL; /* the replacement image, if not null at end */
   SetGeometryInfo(&geometry_info);
 
   switch (*(option+1))
@@ -1787,7 +1781,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
       if (LocaleCompare("annotate",option+1) == 0)
         {
           char
-            geometry[MaxTextExtent];
+            geometry[MagickPathExtent];
 
           SetGeometryInfo(&geometry_info);
           flags=ParseGeometry(arg1,&geometry_info);
@@ -1796,7 +1790,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
           if ((flags & SigmaValue) == 0)
             geometry_info.sigma=geometry_info.rho;
           (void) CloneString(&_draw_info->text,arg2);
-          (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
+          (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
             geometry_info.xi,geometry_info.psi);
           (void) CloneString(&_draw_info->geometry,geometry);
           _draw_info->affine.sx=cos(DegreesToRadians(
@@ -1945,14 +1939,14 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
         {
           if (IfPlusOp)
             {
-              SetPixelChannelMask(_image,DefaultChannels);
+              (void) SetPixelChannelMask(_image,DefaultChannels);
               break;
             }
           parse=ParseChannelOption(arg1);
           if (parse < 0)
             CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
               option,arg1);
-          SetPixelChannelMask(_image,(ChannelType) parse);
+          (void) SetPixelChannelMask(_image,(ChannelType) parse);
           break;
         }
       if (LocaleCompare("charcoal",option+1) == 0)
@@ -1986,7 +1980,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
           if (IfNormalOp)
             (void) ClipImage(_image,_exception);
           else /* "+mask" remove the write mask */
-            (void) SetImageMask(_image,(Image *) NULL,_exception);
+            (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,_exception);
           break;
         }
       if (LocaleCompare("clip-mask",option+1) == 0)
@@ -2009,7 +2003,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
 
           if (IfPlusOp) {
             /* use "+clip-mask" Remove the write mask for -clip-path */
-            (void) SetImageMask(_image,(Image *) NULL,_exception);
+            (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,_exception);
             break;
           }
           mask_image=GetImageCache(_image_info,arg1,_exception);
@@ -2041,7 +2035,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
           mask_view=DestroyCacheView(mask_view);
           mask_image->alpha_trait=BlendPixelTrait;
           (void) SetImageColorspace(_image,GRAYColorspace,_exception);
-          (void) SetImageMask(_image,mask_image,_exception);
+          (void) SetImageMask(_image,ReadPixelMask,mask_image,_exception);
           mask_image=DestroyImage(mask_image);
           break;
         }
@@ -2142,12 +2136,24 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("convolve",option+1) == 0)
         {
+          double
+            gamma;
+            
           KernelInfo
             *kernel_info;
+            
+          register ssize_t
+            j;
 
           kernel_info=AcquireKernelInfo(arg1,exception);
           if (kernel_info == (KernelInfo *) NULL)
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          gamma=0.0;
+          for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
+            gamma+=kernel_info->values[j];
+          gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+          for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
+            kernel_info->values[j]*=gamma;
           new_image=MorphologyImage(_image,CorrelateMorphology,1,kernel_info,
             _exception);
           kernel_info=DestroyKernelInfo(kernel_info);
@@ -2252,7 +2258,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
             }
           /* convert argument string into an array of doubles */
           args = StringToArrayOfDoubles(arg2,&count,_exception);
-          if (args == (double *)NULL )
+          if (args == (double *) NULL )
             CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
 
           new_image=DistortImage(_image,(DistortImageMethod) parse,(size_t)
@@ -2264,7 +2270,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
         {
           (void) CloneString(&_draw_info->primitive,arg1);
           (void) DrawImage(_image,_draw_info,_exception);
-          (void) CloneString(&_draw_info->primitive,(char *)NULL);
+          (void) CloneString(&_draw_info->primitive,(char *) NULL);
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
@@ -2413,7 +2419,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
                  option,arg1);
           /* convert argument string into an array of doubles */
           args = StringToArrayOfDoubles(arg2,&count,_exception);
-          if (args == (double *)NULL )
+          if (args == (double *) NULL )
             CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
 
           (void) FunctionImage(_image,(MagickFunction)parse,(size_t) count,args,
@@ -2443,6 +2449,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
           if (IfNormalOp)
             constant=PerceptibleReciprocal(constant);
           (void) EvaluateImage(_image,PowEvaluateOperator,constant,_exception);
+          _image->gamma*=StringToDouble(arg1,(char **) NULL);
 #endif
           /* Set gamma setting -- Old meaning of "+gamma"
            * _image->gamma=StringToDouble(arg1,(char **) NULL);
@@ -2633,7 +2640,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
       if (LocaleCompare("level-colors",option+1) == 0)
         {
           char
-            token[MaxTextExtent];
+            token[MagickPathExtent];
 
           const char
             *p;
@@ -2727,21 +2734,9 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       if (LocaleCompare("mask",option+1) == 0)
         {
-          /* Note: arguments do not have percent escapes expanded */
-          Image
-            *mask;
-
-          if (IfPlusOp)
-            { /* Remove a mask. */
-              (void) SetImageMask(_image,(Image *) NULL,_exception);
-              break;
-            }
-          /* Set the image mask. */
-          mask=GetImageCache(_image_info,arg1,_exception);
-          if (mask == (Image *) NULL)
-            break;
-          (void) SetImageMask(_image,mask,_exception);
-          mask=DestroyImage(mask);
+          CLIWandWarnReplaced("-read-mask");
+          (void) CLISimpleOperatorImage(cli_wand,"-read-mask",NULL,NULL,
+            exception);
           break;
         }
       if (LocaleCompare("matte",option+1) == 0)
@@ -2800,7 +2795,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
       if (LocaleCompare("morphology",option+1) == 0)
         {
           char
-            token[MaxTextExtent];
+            token[MagickPathExtent];
 
           const char
             *p;
@@ -3004,7 +2999,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
 
               profile_info=CloneImageInfo(_image_info);
               (void) CopyMagickString(profile_info->filename,arg1,
-                MaxTextExtent);
+                MagickPathExtent);
               profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
               if (profile != (StringInfo *) NULL)
                 {
@@ -3056,6 +3051,26 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
           (void) RandomThresholdImage(_image,arg1,_exception);
           break;
         }
+      if (LocaleCompare("read-mask",option+1) == 0)
+        {
+          /* Note: arguments do not have percent escapes expanded */
+          Image
+            *mask;
+
+          if (IfPlusOp)
+            { /* Remove a mask. */
+              (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,
+                _exception);
+              break;
+            }
+          /* Set the image mask. */
+          mask=GetImageCache(_image_info,arg1,_exception);
+          if (mask == (Image *) NULL)
+            break;
+          (void) SetImageMask(_image,ReadPixelMask,mask,_exception);
+          mask=DestroyImage(mask);
+          break;
+        }
       if (LocaleCompare("recolor",option+1) == 0)
         {
           CLIWandWarnReplaced("-color-matrix");
@@ -3305,8 +3320,8 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & RhoValue) == 0)
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
-          new_image=SpreadImage(_image,geometry_info.rho,_image->interpolate,
-               _exception);
+          new_image=SpreadImage(_image,_image->interpolate,geometry_info.rho,
+           _exception);
           break;
         }
       if (LocaleCompare("statistic",option+1) == 0)
@@ -3505,6 +3520,26 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
           (void) WhiteThresholdImage(_image,arg1,_exception);
           break;
         }
+      if (LocaleCompare("write-mask",option+1) == 0)
+        {
+          /* Note: arguments do not have percent escapes expanded */
+          Image
+            *mask;
+
+          if (IfPlusOp)
+            { /* Remove a mask. */
+              (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,
+                _exception);
+              break;
+            }
+          /* Set the image mask. */
+          mask=GetImageCache(_image_info,arg1,_exception);
+          if (mask == (Image *) NULL)
+            break;
+          (void) SetImageMask(_image,WritePixelMask,mask,_exception);
+          mask=DestroyImage(mask);
+          break;
+        }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     default:
@@ -3543,8 +3578,8 @@ WandPrivate MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,
 #endif
 
   assert(cli_wand != (MagickCLI *) NULL);
-  assert(cli_wand->signature == WandSignature);
-  assert(cli_wand->wand.signature == WandSignature);
+  assert(cli_wand->signature == MagickWandSignature);
+  assert(cli_wand->wand.signature == MagickWandSignature);
   assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
 
   if (IfMagickTrue(cli_wand->wand.debug))
@@ -3630,16 +3665,18 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
 #define _option_type    ((CommandOptionFlags) cli_wand->command->flags)
 #define IfNormalOp      (*option=='-')
 #define IfPlusOp        (*option!='-')
-#define IsNormalOp       IsMagickTrue(IfNormalOp)
+#define IsNormalOp      IfNormalOp ? MagickTrue : MagickFalse
 
   assert(cli_wand != (MagickCLI *) NULL);
-  assert(cli_wand->signature == WandSignature);
-  assert(cli_wand->wand.signature == WandSignature);
+  assert(cli_wand->signature == MagickWandSignature);
+  assert(cli_wand->wand.signature == MagickWandSignature);
   assert(_images != (Image *) NULL);             /* _images must be present */
 
   if (IfMagickTrue(cli_wand->wand.debug))
     (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
-         "- List Operator: %s \"%s\" \"%s\"", option,arg1n,arg2n);
+       "- List Operator: %s \"%s\" \"%s\"", option,
+       arg1n == (const char *) NULL ? "null" : arg1n,
+       arg2n == (const char *) NULL ? "null" : arg2n);
 
   arg1 = arg1n;
   arg2 = arg2n;
@@ -3708,7 +3745,8 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
           /* FUTURE - produce Exception, rather than silent fail */
           if (clut_image == (Image *) NULL)
             break;
-          (void) ClutImage(new_images,clut_image,new_images->interpolate,_exception);
+          (void) ClutImage(new_images,clut_image,new_images->interpolate,
+            _exception);
           clut_image=DestroyImage(clut_image);
           break;
         }
@@ -3719,10 +3757,9 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
         }
       if (LocaleCompare("combine",option+1) == 0)
         {
-          parse = (ssize_t) sRGBColorspace; /* default (backward compatible) */
+          parse=(ssize_t) _images->colorspace;
           if ( IfPlusOp )
-            parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,
-                 arg1);
+            parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
           if (parse < 0)
             CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
               arg1);
@@ -3807,7 +3844,7 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
           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));
+            clip_to_self=IsStringFalse(value);
           }
 
           new_images=RemoveFirstImageFromList(&_images);
@@ -3823,22 +3860,70 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
           GravityAdjustGeometry(new_images->columns,new_images->rows,
             new_images->gravity, &geometry);
           mask_image=RemoveFirstImageFromList(&_images);
-          if (mask_image != (Image *) NULL)
+          if (mask_image == (Image *) NULL)
+            status&=CompositeImage(new_images,source_image,compose,clip_to_self,
+              geometry.x,geometry.y,_exception);
+          else
             {
-              if ((compose != DisplaceCompositeOp) &&
-                  (compose != DistortCompositeOp))
-                status&=CompositeImage(source_image,mask_image,
-                  IntensityCompositeOp,MagickTrue,0,0,_exception);
+              if ((compose == DisplaceCompositeOp) ||
+                  (compose == DistortCompositeOp))
+                {
+                  status&=CompositeImage(source_image,mask_image,
+                    CopyGreenCompositeOp,MagickTrue,0,0,_exception);
+                  status&=CompositeImage(new_images,source_image,compose,
+                    clip_to_self,geometry.x,geometry.y,_exception);
+                }
               else
-                status&=CompositeImage(source_image,mask_image,
-                  CopyGreenCompositeOp,MagickTrue,0,0,_exception);
+                {
+                  Image
+                    *clone_image;
+
+                  clone_image=CloneImage(new_images,0,0,MagickTrue,_exception);
+                  if (clone_image == (Image *) NULL)
+                    break;
+                  status&=CompositeImage(new_images,source_image,compose,
+                    clip_to_self,geometry.x,geometry.y,_exception);
+                  status&=CompositeImage(new_images,mask_image,
+                    CopyAlphaCompositeOp,MagickTrue,0,0,_exception);
+                  status&=CompositeImage(clone_image,new_images,OverCompositeOp,
+                    clip_to_self,geometry.x,geometry.y,_exception);
+                  new_images=DestroyImage(new_images);
+                  new_images=clone_image;
+                }
               mask_image=DestroyImage(mask_image);
             }
-          status&=CompositeImage(new_images,source_image,compose,clip_to_self,
-            geometry.x,geometry.y,_exception);
           source_image=DestroyImage(source_image);
           break;
         }
+        if (LocaleCompare("copy",option+1) == 0)
+          {
+            Image
+              *source_image;
+
+            OffsetInfo
+              offset;
+
+            RectangleInfo
+              geometry;
+
+            /*
+              Copy image pixels.
+            */
+            if (IfMagickFalse(IsGeometry(arg1)))
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+            if (IfMagickFalse(IsGeometry(arg2)))
+              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+            (void) ParsePageGeometry(_images,arg2,&geometry,_exception);
+            offset.x=geometry.x;
+            offset.y=geometry.y;
+            source_image=_images;
+            if (source_image->next != (Image *) NULL)
+              source_image=source_image->next;
+            (void) ParsePageGeometry(source_image,arg1,&geometry,_exception);
+            (void) CopyImagePixels(_images,source_image,&geometry,&offset,
+              _exception);
+            break;
+          }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
     case 'd':
@@ -3882,7 +3967,7 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
           else
             new_images=DuplicateImages(_images,1,"-1",_exception);
           AppendImageToList(&_images, new_images);
-          new_images=(Image *)NULL;
+          new_images=(Image *) NULL;
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
@@ -3905,7 +3990,8 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
     {
       if (LocaleCompare("fft",option+1) == 0)
         {
-          new_images=ForwardFourierTransformImage(_images,IsNormalOp,_exception);
+          new_images=ForwardFourierTransformImage(_images,IsNormalOp,
+           _exception);
           break;
         }
       if (LocaleCompare("flatten",option+1) == 0)
@@ -3955,7 +4041,7 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
            if (phase_image == (Image *) NULL)
              break;
            new_images=InverseFourierTransformImage(magnitude_image,phase_image,
-                   IsNormalOp,_exception);
+             IsNormalOp,_exception);
            magnitude_image=DestroyImage(magnitude_image);
            phase_image=DestroyImage(phase_image);
           break;
@@ -4022,7 +4108,7 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
             case TrimBoundsLayer:
             {
               new_images=MergeImageLayers(_images,(LayerMethod) parse,
-                   _exception);
+                _exception);
               break;
             }
             case DisposeLayer:
@@ -4183,10 +4269,11 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
             count;
 
           /* convert argument string into an array of doubles */
-          args = StringToArrayOfDoubles(arg2,&count,_exception);
-          if (args == (double *)NULL )
-            CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
-          new_images=PolynomialImage(_images,(size_t) (count >> 1),args,_exception);
+          args = StringToArrayOfDoubles(arg1,&count,_exception);
+          if (args == (double *) NULL )
+            CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg1);
+          new_images=PolynomialImage(_images,(size_t) (count >> 1),args,
+           _exception);
           args=(double *) RelinquishMagickMemory(args);
           break;
         }
@@ -4229,8 +4316,8 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
               assert(arg1 != (const char *) NULL);
               length=strlen(arg1);
               token=(char *) NULL;
-              if (~length >= (MaxTextExtent-1))
-                token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
+              if (~length >= (MagickPathExtent-1))
+                token=(char *) AcquireQuantumMemory(length+MagickPathExtent,
                   sizeof(*token));
               if (token == (char *) NULL)
                 break;
@@ -4296,8 +4383,8 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
             *base_image,
             *compare_image;
 
-          const char *
-            value;
+          const char
+            *value;
 
           MetricType
             metric;
@@ -4319,32 +4406,35 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
               MagickFalse,value);
 
           new_images=SimilarityImage(base_image,compare_image,metric,0.0,
-               &offset,&similarity,_exception);
-
-          if ( new_images != (Image *)NULL ) {
-            char
-              result[MaxTextExtent];
-
-            (void) FormatLocaleString(result,MaxTextExtent,"%lf",similarity);
-            (void) SetImageProperty(new_images,"subimage:similarity",result,
-                 _exception);
-            (void) FormatLocaleString(result,MaxTextExtent,"%+ld",
-                (long) offset.x);
-            (void) SetImageProperty(new_images,"subimage:x",result,
-                 _exception);
-            (void) FormatLocaleString(result,MaxTextExtent,"%+ld",
-                (long) offset.y);
-            (void) SetImageProperty(new_images,"subimage:y",result,
-                 _exception);
-            (void) FormatLocaleString(result,MaxTextExtent,"%lux%lu%+ld%+ld",
-                (unsigned long) offset.width,(unsigned long) offset.height,
-                (long) offset.x,(long) offset.y);
-            (void) SetImageProperty(new_images,"subimage:offset",result,
-                 _exception);
-          }
+            &offset,&similarity,_exception);
+
+          if (new_images != (Image *) NULL)
+            {
+              char
+                result[MagickPathExtent];
+
+              (void) FormatLocaleString(result,MagickPathExtent,"%lf",
+                similarity);
+              (void) SetImageProperty(new_images,"subimage:similarity",result,
+                _exception);
+              (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
+                offset.x);
+              (void) SetImageProperty(new_images,"subimage:x",result,
+                _exception);
+              (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
+                offset.y);
+              (void) SetImageProperty(new_images,"subimage:y",result,
+                _exception);
+              (void) FormatLocaleString(result,MagickPathExtent,
+                "%lux%lu%+ld%+ld",(unsigned long) offset.width,(unsigned long)
+                offset.height,(long) offset.x,(long) offset.y);
+              (void) SetImageProperty(new_images,"subimage:offset",result,
+                _exception);
+            }
           break;
         }
-      if (LocaleCompare("swap",option+1) == 0) {
+      if (LocaleCompare("swap",option+1) == 0)
+        {
         Image
           *p,
           *q,
@@ -4468,12 +4558,14 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
 #define IfPlusOp        (*option!='-')
 
   assert(cli_wand != (MagickCLI *) NULL);
-  assert(cli_wand->signature == WandSignature);
-  assert(cli_wand->wand.signature == WandSignature);
+  assert(cli_wand->signature == MagickWandSignature);
+  assert(cli_wand->wand.signature == MagickWandSignature);
 
   if (IfMagickTrue(cli_wand->wand.debug))
     (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
-         "- NoImage Operator: %s \"%s\" \"%s\"", option,arg1n,arg2n);
+      "- NoImage Operator: %s \"%s\" \"%s\"", option,
+      arg1n != (char *) NULL ? arg1n : "",
+      arg2n != (char *) NULL ? arg2n : "");
 
   arg1 = arg1n;
   arg2 = arg2n;
@@ -4572,7 +4664,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
     if (LocaleCompare("write",option+1) == 0) {
       /* Note: arguments do not have percent escapes expanded */
       char
-        key[MaxTextExtent];
+        key[MagickPathExtent];
 
       Image
         *write_images;
@@ -4587,7 +4679,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
         CLIWandExceptArgBreak(OptionError,"NoImagesForWrite",option,arg1);
       }
 
-      (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
+      (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",arg1);
       (void) DeleteImageRegistry(key);
       write_images=_images;
       if (IfPlusOp)
@@ -4612,7 +4704,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
 
       size=0;
       node=cli_wand->image_list_stack;
-      for ( ; node != (Stack *)NULL; node=node->next)
+      for ( ; node != (Stack *) NULL; node=node->next)
         size++;
       if ( size >= MAX_STACK_DEPTH )
         CLIWandExceptionBreak(OptionError,"ParenthesisNestedTooDeeply",option);
@@ -4643,7 +4735,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
 
       size=0;
       node=cli_wand->image_info_stack;
-      for ( ; node != (Stack *)NULL; node=node->next)
+      for ( ; node != (Stack *) NULL; node=node->next)
         size++;
       if ( size >= MAX_STACK_DEPTH )
         CLIWandExceptionBreak(OptionError,"CurlyBracesNestedTooDeeply",option);
@@ -4657,7 +4749,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
 
       cli_wand->image_info_stack = node;
       cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
-      if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
+      if (cli_wand->wand.image_info == (ImageInfo *) NULL) {
         CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
             option);
         cli_wand->wand.image_info = (ImageInfo *)node->data;
@@ -4673,7 +4765,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
         *node;
 
       node = (Stack *)cli_wand->image_list_stack;
-      if ( node == (Stack *)NULL)
+      if ( node == (Stack *) NULL)
         CLIWandExceptionBreak(OptionError,"UnbalancedParenthesis",option);
       cli_wand->image_list_stack = node->next;
 
@@ -4683,7 +4775,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
 
       /* handle respect-parenthesis - of the previous 'pushed' settings */
       node = cli_wand->image_info_stack;
-      if ( node != (Stack *)NULL)
+      if ( node != (Stack *) NULL)
         {
           if (IfMagickTrue(IsStringTrue(GetImageOption(
                 cli_wand->wand.image_info,"respect-parenthesis"))))
@@ -4701,7 +4793,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
         *node;
 
       node = (Stack *)cli_wand->image_info_stack;
-      if ( node == (Stack *)NULL)
+      if ( node == (Stack *) NULL)
         CLIWandExceptionBreak(OptionError,"UnbalancedCurlyBraces",option);
       cli_wand->image_info_stack = node->next;
 
@@ -4756,7 +4848,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
         if (LocaleNCompare(arg1,"option:",7) == 0)
           {
             /* delete equivelent artifact from all images (if any) */
-            if (_images != (Image *)NULL)
+            if (_images != (Image *) NULL)
               {
                 MagickResetIterator(&cli_wand->wand);
                 while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
@@ -4765,7 +4857,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
               }
             /* now set/delete the global option as needed */
             /* FUTURE: make escapes in a global 'option:' delayed */
-            arg2=(char *)NULL;
+            arg2=(char *) NULL;
             if (IfNormalOp)
               {
                 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
@@ -4785,7 +4877,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
         MagickResetIterator(&cli_wand->wand);
         while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
           {
-            arg2=(char *)NULL;
+            arg2=(char *) NULL;
             if (IfNormalOp)
               {
                 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
@@ -4813,7 +4905,7 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
           arg1=AcquireString("-1");
         if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
           CLIWandExceptionBreak(OptionError,"InvalidArgument",option);
-        if ( cli_wand->image_list_stack == (Stack *)NULL)
+        if ( cli_wand->image_list_stack == (Stack *) NULL)
           CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
         new_images = (Image *)cli_wand->image_list_stack->data;
         if (new_images == (Image *) NULL)
@@ -4983,8 +5075,8 @@ WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
     option_type;
 
   assert(cli_wand != (MagickCLI *) NULL);
-  assert(cli_wand->signature == WandSignature);
-  assert(cli_wand->wand.signature == WandSignature);
+  assert(cli_wand->signature == MagickWandSignature);
+  assert(cli_wand->wand.signature == MagickWandSignature);
 
   do { /* Break Code Block for error handling */
 
@@ -5042,7 +5134,7 @@ WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
 
     /* FUTURE: this is temporary - get 'settings' to handle distribution of
       settings to images attributes,proprieties,artifacts */
-    if ( cli_wand->wand.images != (Image *)NULL )
+    if ( cli_wand->wand.images != (Image *) NULL )
       (void) SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
         cli_wand->wand.exception);
 
@@ -5052,20 +5144,20 @@ WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
     }
 
     /* Operators that do not need images - read, write, stack, clone */
-    if ( (option_type & NoImageOperatorFlag) != 0)
+    if ((option_type & NoImageOperatorFlag) != 0)
       CLINoImageOperator(cli_wand, option, arg1, arg2);
 
     /* FUTURE: The not a setting part below is a temporary hack due to
     * some options being both a Setting and a Simple operator.
     * Specifically -monitor, -depth, and  -colorspace */
-    if ( cli_wand->wand.images == (Image *)NULL )
+    if ( cli_wand->wand.images == (Image *) NULL )
       if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
           ((option_type & SettingOptionFlags) == 0 ))  /* temp hack */
         CLIWandExceptionBreak(OptionError,"NoImagesFound",option);
 
     /* Operators which loop of individual images, simply */
     if ( (option_type & SimpleOperatorFlag) != 0 &&
-         cli_wand->wand.images != (Image *)NULL) /* temp hack */
+         cli_wand->wand.images != (Image *) NULL) /* temp hack */
       {
         ExceptionInfo *exception=AcquireExceptionInfo();
         (void) CLISimpleOperatorImages(cli_wand, option, arg1, arg2,exception);