]> granicus.if.org Git - imagemagick/blobdiff - MagickWand/operation.c
(no commit message)
[imagemagick] / MagickWand / operation.c
index c9b5accfed1dd967a901b365abad261c2104988c..a88f83f49f7bd9485e6621755506ceef617f5f6b 100644 (file)
@@ -17,7 +17,7 @@
 %                               September 2011                                %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
 #include "MagickWand/studio.h"
 #include "MagickWand/MagickWand.h"
 #include "MagickWand/magick-wand-private.h"
+#include "MagickWand/mogrify.h"
 #include "MagickWand/wand.h"
 #include "MagickWand/wandcli.h"
 #include "MagickWand/wandcli-private.h"
-#include "MagickWand/operation.h"
+#include "MagickCore/image-private.h"
 #include "MagickCore/monitor-private.h"
+#include "MagickWand/operation.h"
 #include "MagickCore/thread-private.h"
 #include "MagickCore/string-private.h"
 #include "MagickCore/pixel-private.h"
 \f
+/*
+  Constant declaration.
+*/
+static const char
+  MogrifyBackgroundColor[] = "#fff",  /* white */
+  MogrifyBorderColor[] = "#dfdfdf",  /* sRGB gray */
+  MogrifyMatteColor[] = "#bdbdbd";  /* slightly darker gray */
+\f
 /*
   Define declarations.
 */
 /* FUTURE: why is this default so specific? */
 #define DEFAULT_DISSIMILARITY_THRESHOLD "0.31830988618379067154"
 
-/*
-  Constant declaration. (temporary exports)
-*/
-static const char
-  BackgroundColor[] = "#fff",  /* white */
-  BorderColor[] = "#dfdfdf",  /* sRGB gray */
-  MatteColor[] = "#bdbdbd";  /* slightly darker gray */
-
 /* For Debugging Geometry Input */
 #define ReportGeometry(flags,info) \
   (void) FormatLocaleFile(stderr, "Geometry = 0x%04X : %lg x %lg %+lg %+lg\n", \
@@ -149,7 +151,8 @@ static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
   if (image != (Image *) NULL)
     return(image);
   read_info=CloneImageInfo(image_info);
-  (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
+  if (path != (const char *) NULL)
+    (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
   image=ReadImage(read_info,exception);
   read_info=DestroyImageInfo(read_info);
   if (image != (Image *) NULL)
@@ -162,7 +165,7 @@ static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
   an array of floating point values than call SparseColorImage().
   Argument is a complex mix of floating-point pixel coodinates, and color
   specifications (or direct floating point numbers).  The number of floats
-  needed to represent a color varies depending on teh current channel
+  needed to represent a color varies depending on the current channel
   setting.
 
   This really should be in MagickCore, so that other API's can make use of it.
@@ -513,7 +516,7 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
              Better error handling of QueryColorCompliance() needed.
           */
           (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
-          (void) QueryColorCompliance(ArgOption(BackgroundColor),AllCompliance,
+          (void) QueryColorCompliance(ArgOption(MogrifyBackgroundColor),AllCompliance,
              &_image_info->background_color,_exception);
           break;
         }
@@ -566,9 +569,9 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
               break;
             }
           (void) DeleteImageOption(_image_info,option+1);
-          (void) QueryColorCompliance(BorderColor,AllCompliance,
+          (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
             &_image_info->border_color,_exception);
-          (void) QueryColorCompliance(BorderColor,AllCompliance,
+          (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
             &_draw_info->border_color,_exception);
           break;
         }
@@ -603,8 +606,7 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
         }
       if (LocaleCompare("channel",option+1) == 0)
         {
-          arg1=ArgOption("default");
-          parse=ParseChannelOption(arg1);
+          parse=ParseChannelOption(ArgOption("Default"));
           if (parse < 0)
             CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",
                  option,arg1);
@@ -833,7 +835,7 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
       if (LocaleCompare("features",option+1) == 0)
         {
           (void) SetImageOption(_image_info,"identify:features",
-                    ArgBooleanString);
+            ArgBooleanString);
           if (IfSetOption)
             (void) SetImageArtifact(_image,"verbose","true");
           break;
@@ -1098,7 +1100,7 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
         {
           /* SyncImageSettings() used to set per-image attribute. */
           (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
-          (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
+          (void) QueryColorCompliance(ArgOption(MogrifyMatteColor),AllCompliance,
              &_image_info->matte_color,_exception);
           break;
         }
@@ -1113,6 +1115,14 @@ WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
           (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
+      if (LocaleCompare("moments",option+1) == 0)
+        {
+          (void) SetImageOption(_image_info,"identify:moments",
+            ArgBooleanString);
+          if (IfSetOption)
+            (void) SetImageArtifact(_image,"verbose","true");
+          break;
+        }
       if (LocaleCompare("monitor",option+1) == 0)
         {
           (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
@@ -1904,6 +1914,26 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
     }
     case 'c':
     {
+      if (LocaleCompare("canny",option+1) == 0)
+        {
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          if ((flags & SigmaValue) == 0)
+            geometry_info.sigma=1.0;
+          if ((flags & XiValue) == 0)
+            geometry_info.xi=10;
+          if ((flags & PsiValue) == 0)
+            geometry_info.psi=30;
+          if ((flags & PercentValue) != 0)
+            {
+              geometry_info.xi/=100.0;
+              geometry_info.psi/=100.0;
+            }
+          new_image=CannyEdgeImage(_image,geometry_info.rho,geometry_info.sigma,
+            geometry_info.xi,geometry_info.psi,_exception);
+          break;
+        }
       if (LocaleCompare("cdl",option+1) == 0)
         {
           /* Note: arguments do not have percent escapes expanded */
@@ -1913,7 +1943,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
           /*
             Color correct with a color decision list.
           */
-          color_correction_collection=FileToString(arg1,~0,_exception);
+          color_correction_collection=FileToString(arg1,~0UL,_exception);
           if (color_correction_collection == (char *) NULL)
             break;
           (void) ColorDecisionListImage(_image,color_correction_collection,
@@ -2136,7 +2166,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
           StringInfo
             *passkey;
 
-          passkey=FileToStringInfo(arg1,~0,_exception);
+          passkey=FileToStringInfo(arg1,~0UL,_exception);
           if (passkey == (StringInfo *) NULL)
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
 
@@ -2253,7 +2283,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
           StringInfo
             *passkey;
 
-          passkey=FileToStringInfo(arg1,~0,_exception);
+          passkey=FileToStringInfo(arg1,~0UL,_exception);
           if (passkey != (StringInfo *) NULL)
             {
               (void) PasskeyEncipherImage(_image,passkey,_exception);
@@ -2458,6 +2488,23 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
+    case 'h':
+    {
+      if (LocaleCompare("hough-lines",option+1) == 0)
+        {
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          if ((flags & SigmaValue) == 0)
+            geometry_info.sigma=geometry_info.rho;
+          if ((flags & XiValue) == 0)
+            geometry_info.xi=40;
+          new_image=HoughLineImage(_image,(size_t) geometry_info.rho,
+            (size_t) geometry_info.sigma,(size_t) geometry_info.xi,_exception);
+          break;
+        }
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
+    }
     case 'i':
     {
       if (LocaleCompare("identify",option+1) == 0)
@@ -2467,16 +2514,17 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
             *text;
 
           format=GetImageOption(_image_info,"format");
-          if (format == (char *) NULL) {
-            (void) IdentifyImage(_image,stdout,_image_info->verbose,_exception);
-            break;
-          }
+          if (format == (char *) NULL)
+            {
+              (void) IdentifyImage(_image,stdout,_image_info->verbose,
+                _exception);
+              break;
+            }
           text=InterpretImageProperties(_image_info,_image,format,_exception);
           if (text == (char *) NULL)
             CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
-                 option);
+              option);
           (void) fputs(text,stdout);
-          (void) fputc('\n',stdout);
           text=DestroyString((char *)text);
           break;
         }
@@ -2669,7 +2717,22 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
         {
           CLIWandWarnReplaced(IfNormalOp?"-alpha Set":"-alpha Off");
           (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
-                         DeactivateAlphaChannel, _exception);
+            DeactivateAlphaChannel, _exception);
+          break;
+        }
+      if (LocaleCompare("mean-shift",option+1) == 0)
+        {
+          flags=ParseGeometry(arg1,&geometry_info);
+          if ((flags & (RhoValue|SigmaValue)) == 0)
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          if ((flags & SigmaValue) == 0)
+            geometry_info.sigma=1.0;
+          if ((flags & XiValue) == 0)
+            geometry_info.xi=0.10*QuantumRange;
+          if ((flags & PercentValue) != 0)
+            geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
+          new_image=MeanShiftImage(_image,(size_t) geometry_info.rho,
+            (size_t) geometry_info.sigma,geometry_info.xi,_exception);
           break;
         }
       if (LocaleCompare("median",option+1) == 0)
@@ -2940,12 +3003,12 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
     }
     case 'r':
     {
-      if (LocaleCompare("radial-blur",option+1) == 0)
+      if (LocaleCompare("rotational-blur",option+1) == 0)
         {
           flags=ParseGeometry(arg1,&geometry_info);
           if ((flags & RhoValue) == 0)
             CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
-          new_image=RadialBlurImage(_image,geometry_info.rho,_exception);
+          new_image=RotationalBlurImage(_image,geometry_info.rho,_exception);
           break;
         }
       if (LocaleCompare("raise",option+1) == 0)
@@ -3380,6 +3443,11 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
             geometry_info.xi=0.1*_image->columns;
           if ((flags & PsiValue) == 0)
             geometry_info.psi=0.1*_image->rows;
+          if ((flags & PercentValue) != 0)
+            {
+              geometry_info.xi*=(double) _image->columns/100.0;
+              geometry_info.psi*=(double) _image->rows/100.0;
+            }
           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);
@@ -3631,6 +3699,48 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
           new_images=CombineImages(_images,(ColorspaceType) parse,_exception);
           break;
         }
+      if (LocaleCompare("compare",option+1) == 0)
+        {
+          double
+            distortion;
+
+          Image
+            *image,
+            *reconstruct_image;
+
+          MetricType
+            metric;
+
+          /*
+            Mathematically and visually annotate the difference between an
+            image and its reconstruction.
+          */
+          image=RemoveFirstImageFromList(&_images);
+          reconstruct_image=RemoveFirstImageFromList(&_images);
+          /* FUTURE - produce Exception, rather than silent fail */
+          if (reconstruct_image == (Image *) NULL)
+            break;
+          metric=UndefinedErrorMetric;
+          option=GetImageOption(_image_info,"metric");
+          if (option != (const char *) NULL)
+            metric=(MetricType) ParseCommandOption(MagickMetricOptions,
+              MagickFalse,option);
+          new_images=CompareImages(image,reconstruct_image,metric,&distortion,
+            _exception);
+          (void) distortion;
+          reconstruct_image=DestroyImage(reconstruct_image);
+          image=DestroyImage(image);
+          break;
+        }
+      if (LocaleCompare("complex",option+1) == 0)
+        {
+          parse=ParseCommandOption(MagickComplexOptions,MagickFalse,arg1);
+          if (parse < 0)
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
+              option,arg1);
+          new_images=ComplexImages(_images,(ComplexOperator) parse,_exception);
+          break;
+        }
       if (LocaleCompare("composite",option+1) == 0)
         {
           CompositeOperator
@@ -3771,12 +3881,12 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
     {
       if (LocaleCompare("evaluate-sequence",option+1) == 0)
         {
-          parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
-          if ( parse < 0 )
+          parse=ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
+          if (parse < 0)
             CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
-                 option,arg1);
+              option,arg1);
           new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
-               _exception);
+            _exception);
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
@@ -4027,6 +4137,8 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
           (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
           break;
         }
+      if (LocaleCompare("metric",option+1) == 0)
+        break;
       if (LocaleCompare("morph",option+1) == 0)
         {
           Image
@@ -4104,6 +4216,7 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
               /*
                 Support old style syntax, filter="-option arg1".
               */
+              assert(arg1 != (const char *) NULL);
               length=strlen(arg1);
               token=(char *) NULL;
               if (~length >= (MaxTextExtent-1))
@@ -4189,7 +4302,7 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
           compare_image=GetImageFromList(_images,1);
 
           /* Comparision Metric */
-          metric=UndefinedMetric;
+          metric=UndefinedErrorMetric;
           value=GetImageOption(_image_info,"metric");
           if (value != (const char *) NULL)
             metric=(MetricType) ParseCommandOption(MagickMetricOptions,
@@ -4278,10 +4391,10 @@ WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
 
   /* if new image list generated, replace existing image list */
   if (new_images == (Image *) NULL)
-    return(status);
+    return(status == 0 ? MagickFalse : MagickTrue);
   _images=DestroyImageList(_images);
   _images=GetFirstImageInList(new_images);
-  return(status);
+  return(status == 0 ? MagickFalse : MagickTrue);
 
 #undef _image_info
 #undef _images
@@ -4788,7 +4901,9 @@ WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
 
     CLIWandException(OptionError,"UnrecognizedOption",option);
 
+DisableMSCWarning(4127)
   } while (0);  /* break to exit code. */
+RestoreMSCWarning
 
   /* clean up percent escape interpreted strings */
   if (arg1 != arg1n )
@@ -4947,7 +5062,9 @@ WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
     if ( (option_type & ListOperatorFlag) != 0 )
       CLIListOperatorImages(cli_wand, option, arg1, arg2);
 
+DisableMSCWarning(4127)
   } while (0);  /* end Break code block */
+RestoreMSCWarning
 
   cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */
 }