]> granicus.if.org Git - imagemagick/commitdiff
Better syntax checks for "lists of numbers" arguments
authoranthony <anthony@git.imagemagick.org>
Sat, 14 Apr 2012 12:53:56 +0000 (12:53 +0000)
committeranthony <anthony@git.imagemagick.org>
Sat, 14 Apr 2012 12:53:56 +0000 (12:53 +0000)
Also adding some "compare" settings
And fixed "-monitor" and "-colorspace" when no images are present.

MagickCore/option.c
MagickCore/option.h
MagickCore/string.c
MagickCore/string_.h
MagickWand/magick-cli.c
MagickWand/operation.c
MagickWand/wandcli-private.h
config/english.xml
config/francais.xml

index 85623216b22d9e341fceb37c2eb2cc3e45ada894..5a66da5aeeb25dea33bd3dc455b16a818d1335e7 100644 (file)
@@ -337,6 +337,8 @@ static const OptionInfo
     { "-dispose", 1L, ImageInfoOptionFlag, MagickFalse },
     { "+dissolve", 0L, NonMagickOptionFlag, MagickFalse },
     { "-dissolve", 1L, NonMagickOptionFlag, MagickFalse },
+    { "+dissimilarity-threshold", 0L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
+    { "-dissimilarity-threshold", 1L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
     { "+distort", 2L, SimpleOperatorOptionFlag, MagickFalse },
     { "-distort", 2L, SimpleOperatorOptionFlag, MagickFalse },
     { "+dither", 0L, ImageInfoOptionFlag | QuantizeInfoOptionFlag, MagickFalse },
@@ -416,8 +418,8 @@ static const OptionInfo
     { "-green-primary", 1L, ImageInfoOptionFlag, MagickFalse },
     { "+hald-clut", 0L, DeprecateOptionFlag | FireOptionFlag, MagickTrue },
     { "-hald-clut", 0L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse },
-    { "+highlight-color", 1L, SimpleOperatorOptionFlag, MagickFalse },
-    { "-highlight-color", 1L, SimpleOperatorOptionFlag, MagickFalse },
+    { "+highlight-color", 0L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
+    { "-highlight-color", 1L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
     { "+iconGeometry", 0L, NonMagickOptionFlag, MagickFalse },
     { "-iconGeometry", 1L, NonMagickOptionFlag, MagickFalse },
     { "+iconic", 0L, NonMagickOptionFlag, MagickFalse },
@@ -468,8 +470,8 @@ static const OptionInfo
     { "-log", 1L, GlobalOptionFlag, MagickFalse },
     { "+loop", 0L, ImageInfoOptionFlag, MagickFalse },
     { "-loop", 1L, ImageInfoOptionFlag, MagickFalse },
-    { "+lowlight-color", 1L, ImageInfoOptionFlag, MagickFalse },
-    { "-lowlight-color", 1L, ImageInfoOptionFlag, MagickFalse },
+    { "+lowlight-color", 0L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
+    { "-lowlight-color", 1L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
     { "+magnify", 0L, NonMagickOptionFlag, MagickFalse },
     { "-magnify", 1L, NonMagickOptionFlag, MagickFalse },
     { "+map", 0L, ReplacedOptionFlag | ListOperatorOptionFlag | FireOptionFlag, MagickTrue },
@@ -643,7 +645,7 @@ static const OptionInfo
     { "-snaps", 1L, NonMagickOptionFlag, MagickFalse },
     { "+solarize", 1L, DeprecateOptionFlag, MagickTrue },
     { "-solarize", 1L, SimpleOperatorOptionFlag, MagickFalse },
-    { "+sparse-color", 2L, DeprecateOptionFlag, MagickTrue },
+    { "+sparse-color", 1L, DeprecateOptionFlag, MagickTrue },
     { "-sparse-color", 2L, SimpleOperatorOptionFlag, MagickFalse },
     { "+splice", 1L, DeprecateOptionFlag, MagickTrue },
     { "-splice", 1L, SimpleOperatorOptionFlag, MagickFalse },
@@ -665,8 +667,8 @@ static const OptionInfo
     { "-strokewidth", 1L, ImageInfoOptionFlag | DrawInfoOptionFlag, MagickFalse },
     { "+style", 0L, DrawInfoOptionFlag, MagickFalse },
     { "-style", 1L, DrawInfoOptionFlag, MagickFalse },
-    { "+subimage-search", 0L, NonMagickOptionFlag, MagickFalse },
-    { "-subimage-search", 0L, NonMagickOptionFlag, MagickFalse },
+    { "+subimage-search", 0L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
+    { "-subimage-search", 0L, NonMagickOptionFlag | ImageInfoOptionFlag, MagickFalse },
     { "+swap", 0L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse },
     { "-swap", 1L, ListOperatorOptionFlag | FireOptionFlag, MagickFalse },
     { "+swirl", 1L, DeprecateOptionFlag, MagickTrue },
@@ -695,7 +697,7 @@ static const OptionInfo
     { "-transform", 0L, ReplacedOptionFlag | SimpleOperatorOptionFlag, MagickTrue },
     { "+transparent", 1L, SimpleOperatorOptionFlag, MagickFalse },
     { "-transparent", 1L, SimpleOperatorOptionFlag, MagickFalse },
-    { "+transparent-color", 1L, ImageInfoOptionFlag, MagickFalse },
+    { "+transparent-color", 0L, ImageInfoOptionFlag, MagickFalse },
     { "-transparent-color", 1L, ImageInfoOptionFlag, MagickFalse },
     { "+transpose", 0L, DeprecateOptionFlag, MagickTrue },
     { "-transpose", 0L, SimpleOperatorOptionFlag, MagickFalse },
index 3679bf0c1e308a60d5bbe3273cccc20ec7a625b5..79909c7aff802dff3079d4ca69eee51437787aa6 100644 (file)
@@ -137,7 +137,7 @@ typedef enum
   ImageInfoOptionFlag       = 0x0001,  /* Setting for ImageInfo */
   DrawInfoOptionFlag        = 0x0002,  /* Setting for DrawInfo */
   QuantizeInfoOptionFlag    = 0x0004,  /* Setting for QuantizeInfo */
-  GlobalOptionFlag          = 0x0008,  /* Setting for Global Option */
+  GlobalOptionFlag          = 0x0008,  /* Setting for Global Option - depreciate */
   SettingOptionFlags        = 0x000F,  /* mask for all setting options */
 
   SimpleOperatorOptionFlag  = 0x0010,  /* Simple Image processing operator */
index a2ed535d475666189f09d4a84384a15687b2db31..573fc26c42a814e916c3cd31f97618eb8e430bd0 100644 (file)
@@ -53,6 +53,7 @@
 #include "MagickCore/resource_.h"
 #include "MagickCore/signature-private.h"
 #include "MagickCore/string_.h"
+#include "MagickCore/string-private.h"
 #include "MagickCore/utility-private.h"
 \f
 /*
@@ -101,6 +102,9 @@ static const unsigned char
 %  AcquireString() allocates memory for a string and copies the source string
 %  to that memory location (and returns it).
 %
+%  The returned string shoud be freed using DestoryString() or
+%  RelinquishMagickMemory() when finished.
+%
 %  The format of the AcquireString method is:
 %
 %      char *AcquireString(const char *source)
@@ -2038,6 +2042,82 @@ MagickExport char *StringInfoToString(const StringInfo *string_info)
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   S t r i n g I n f o T o H e x S t r i n g                                 %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  StringInfoToHexString() converts a string info string to a C string.
+%
+%  The format of the StringInfoToHexString method is:
+%
+%      char *StringInfoToHexString(const StringInfo *string_info)
+%
+%  A description of each parameter follows:
+%
+%    o string_info: the string.
+%
+*/
+MagickExport char *StringInfoToHexString(const StringInfo *string_info)
+{
+  char
+    *string;
+
+  register const unsigned char
+    *p;
+
+  register ssize_t
+    i;
+
+  register unsigned char
+    *q;
+
+  size_t
+    length;
+
+  unsigned char
+    hex_digits[16];
+
+  length=string_info->length;
+  if (~length < MaxTextExtent)
+    ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
+  string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
+  if (string == (char *) NULL)
+    ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
+  hex_digits[0]='0';
+  hex_digits[1]='1';
+  hex_digits[2]='2';
+  hex_digits[3]='3';
+  hex_digits[4]='4';
+  hex_digits[5]='5';
+  hex_digits[6]='6';
+  hex_digits[7]='7';
+  hex_digits[8]='8';
+  hex_digits[9]='9';
+  hex_digits[10]='a';
+  hex_digits[11]='b';
+  hex_digits[12]='c';
+  hex_digits[13]='d';
+  hex_digits[14]='e';
+  hex_digits[15]='f';
+  p=string_info->datum;
+  q=(unsigned char *) string;
+  for (i=0; i < (ssize_t) string_info->length; i++)
+  {
+    *q++=hex_digits[(*p >> 4) & 0x0f];
+    *q++=hex_digits[*p & 0x0f];
+    p++;
+  }
+  *q='\0';
+  return(string);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %  S t r i n g T o A r g v                                                    %
 %                                                                             %
 %                                                                             %
@@ -2152,75 +2232,85 @@ MagickExport char **StringToArgv(const char *text,int *argc)
 %                                                                             %
 %                                                                             %
 %                                                                             %
-%   S t r i n g I n f o T o H e x S t r i n g                                 %
+%   S t r i n g T o A r r a y O f D o u b l e s                               %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  StringInfoToHexString() converts a string info string to a C string.
+%  StringToArrayOfDoubles() converts a string of space or comma seperated
+%  numbers into array of floating point numbers (doubles). Any number that
+%  failes to parse properly will produce a syntax error. As will two commas
+%  without a  number between them.  However a final comma at the end will
+%  not be regarded as an error so as to simplify automatic list generation.
 %
-%  The format of the StringInfoToHexString method is:
+%  A NULL value is returned on syntax or memory errors.
 %
-%      char *StringInfoToHexString(const StringInfo *string_info)
+%  Use RelinquishMagickMemory() to free returned array when finished.
+%
+%  The format of the StringToArrayOfDoubles method is:
+%
+%     double *StringToArrayOfDoubles(const char *string,
+%          size_t *count, ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
-%    o string_info: the string.
+%    o string: the string containing the comma/space seperated values.
+%
+%    o count: returns number of arguments in returned array
+%
+%    o exception: return 'mamory failure' exceptions
 %
 */
-MagickExport char *StringInfoToHexString(const StringInfo *string_info)
+MagickExport double *StringToArrayOfDoubles(const char *string,
+     ssize_t *count, ExceptionInfo *exception)
 {
+  const char
+    *p;
+
   char
-    *string;
+    *q;
 
-  register const unsigned char
-    *p;
+  double
+    *array;
 
   register ssize_t
     i;
 
-  register unsigned char
-    *q;
-
-  size_t
-    length;
+  /* Determine count of values, and check syntax */
+  *count=0;
+  p=string;
+  i=0;
+  while( *p != '\0' )
+  {
+    (void) StringToDouble(p, &q);       /* get value - ignores leading space */
+    if (p == q) return((double *)NULL); /* no value found */
+    p=q; i++;                           /* inc value count */
+    while ( isspace((int)*p) ) p++;     /* skip spaces */
+    if ( *p == ',' )           p++;     /* skip comma */
+    while ( isspace((int)*p) ) p++;     /* and more spaces */
+  }
 
-  unsigned char
-    hex_digits[16];
+  /* Allocate floating point argument list */
+  *count=i;
+  array=(double *) AcquireQuantumMemory(i,sizeof(*array));
+  if (array == (double *) NULL) {
+    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+    (void) ThrowMagickException(exception,GetMagickModule(),
+         ResourceLimitFatalError,"MemoryAllocationFailed"," ");
+    return((double *)NULL);
+  }
 
-  length=string_info->length;
-  if (~length < MaxTextExtent)
-    ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
-  string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
-  if (string == (char *) NULL)
-    ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
-  hex_digits[0]='0';
-  hex_digits[1]='1';
-  hex_digits[2]='2';
-  hex_digits[3]='3';
-  hex_digits[4]='4';
-  hex_digits[5]='5';
-  hex_digits[6]='6';
-  hex_digits[7]='7';
-  hex_digits[8]='8';
-  hex_digits[9]='9';
-  hex_digits[10]='a';
-  hex_digits[11]='b';
-  hex_digits[12]='c';
-  hex_digits[13]='d';
-  hex_digits[14]='e';
-  hex_digits[15]='f';
-  p=string_info->datum;
-  q=(unsigned char *) string;
-  for (i=0; i < (ssize_t) string_info->length; i++)
-  {
-    *q++=hex_digits[(*p >> 4) & 0x0f];
-    *q++=hex_digits[*p & 0x0f];
-    p++;
+  /* Fill in the floating point values */
+  p=string;
+  i=0;
+  while( *p != '\0' && i < *count ) {
+    array[i++]=StringToDouble(p,&q);
+    p=q;
+    while ( isspace((int)*p) || *p == ',' ) p++;
   }
-  *q='\0';
-  return(string);
+
+  return(array);
 }
 \f
 /*
@@ -2228,13 +2318,22 @@ MagickExport char *StringInfoToHexString(const StringInfo *string_info)
 %                                                                             %
 %                                                                             %
 %                                                                             %
-%   S t r i n g T o k e n                                                     %
++   S t r i n g T o k e n                                                     %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  StringToken() extracts a token a from the string.
+%  StringToken() Looks for any one of given delimiters and splits the string
+%  into two separate strings by replacing the delimiter character found with a
+%  nul character.
+%
+%  The given string pointer is changed to point to the string following the
+%  delimiter character found, or NULL.  A pointer to the start of the
+%  string is returned, representing the token before the delimiter.
+%
+%  In may ways this is equivent to the strtok() C library function, but with
+%  multiple delimiter characters rather than a delimiter string.
 %
 %  The format of the StringToken method is:
 %
@@ -2266,7 +2365,8 @@ MagickExport char *StringToken(const char *delimiters,char **string)
   p=(*string);
   if (p == (char *) NULL)
     return((char *) NULL);
-  for (q=p; ; )
+  q=p;
+  for ( ; ; )
   {
     c=(*p++);
     r=delimiters;
index 60640cc7aba67d7f823b5d5107ee63b079010361..841c40c21661def63de3abe2581bc2e3da96581b 100644 (file)
@@ -58,19 +58,22 @@ extern MagickExport const char
   *GetStringInfoPath(const StringInfo *);
 
 extern MagickExport double
-  InterpretSiPrefixValue(const char *restrict,char **restrict);
+  InterpretSiPrefixValue(const char *restrict,char **restrict),
+  *StringToArrayOfDoubles(const char *,ssize_t *, ExceptionInfo *);
 
 extern MagickExport int
   CompareStringInfo(const StringInfo *,const StringInfo *),
   LocaleCompare(const char *,const char *),
   LocaleNCompare(const char *,const char *,const size_t);
 
+
 extern MagickExport MagickBooleanType
   ConcatenateString(char **,const char *),
   IsStringTrue(const char *),
   IsStringNotFalse(const char *),
   SubstituteString(char **,const char *,const char *);
 
+
 extern MagickExport size_t
   ConcatenateMagickString(char *,const char *,const size_t)
     magick_attribute((__nonnull__)),
index 1c2a969bb7630eb9b270f3193eb4d1c286521249..f9a97811f8a2cf5270f004bb2d24c25a2d678ae0 100644 (file)
@@ -269,37 +269,28 @@ WandExport void ProcessScriptOptions(MagickCLI *cli_wand,int argc,char **argv,
     else
       CloneString(&arg2,(char *)NULL);
 
+    /*
+      Process Options
+    */
 #if MagickCommandDebug >= 3
     (void) FormatLocaleFile(stderr,
       "Script %u,%u Option: \"%s\"  Count: %d  Flags: %04x  Args: \"%s\" \"%s\"\n",
           cli_wand->line,cli_wand->line,option,count,option_type,arg1,arg2);
 #endif
-
-    if ( (option_type & GenesisOptionFlag) != 0 ) {
-      /* Genesis Options have no place in a magick script */
-      CLIWandExceptionBreak(OptionError,"InvalidUseOfOption",option);
-      goto next_token;
-    }
+    /* Hard Depreciated Options, no code to execute - error */
     if ( (option_type & DeprecateOptionFlag) != 0 ) {
-      CLIWandException(OptionWarning,"DeprecatedOption",option);
+      CLIWandException(OptionError,"DeprecatedOptionNoCode",option);
       if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse )
         break;
-      /* fall through - do the depreciated option */
-    }
-    if (((option_type & ImageRequiredFlags) != 0 ) &&
-        ( cli_wand->wand.images == (Image *)NULL ) ) {
-      CLIWandException(OptionError,"NoImagesFound",option);
       goto next_token;
     }
 
-    /* handle special script-argument options here */
-    //either continue processing command line
-    // or making use of the command line options.
-    //CLICommandOptions(cli_wand,count+1,argv, MagickScriptArgsFlags);
+    /* MagickCommandGenesis() options have no place in a magick script */
+    if ( (option_type & GenesisOptionFlag) != 0 ) {
+      CLIWandExceptionBreak(OptionError,"InvalidUseOfOption",option);
+      goto next_token;
+    }
 
-    /*
-      Process Option from file
-    */
     if ( (option_type & SpecialOptionFlag) != 0 ) {
       if ( LocaleCompare(option,"-exit") == 0 ) {
         break; /* forced end of script */
@@ -309,6 +300,7 @@ WandExport void ProcessScriptOptions(MagickCLI *cli_wand,int argc,char **argv,
         CLIWandExceptionBreak(OptionError,"InvalidUseOfOption",option);
         goto next_token;
       }
+      /* FUTURE: handle special script-argument options here */
       /* handle any other special operators now */
       CLISpecialOperator(cli_wand,option,arg1);
     }
@@ -317,9 +309,21 @@ WandExport void ProcessScriptOptions(MagickCLI *cli_wand,int argc,char **argv,
       CLISettingOptionInfo(cli_wand, option, arg1, arg2);
       // FUTURE: Sync Specific Settings into Image Properities (not global)
     }
-    if ( cli_wand->wand.images != (Image *)NULL )
-      SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
-           cli_wand->wand.exception);
+
+    /* FUTURE: The not a setting part below is a temporary hack to stop gap
+     * measure for options that are BOTH settings and optional 'Simple/List'
+     * operators.  Specifically -monitor  and  -colorspace */
+    if ( cli_wand->wand.images == (Image *)NULL ) {
+      if (((option_type & ImageRequiredFlags) != 0 ) &&
+          ((option_type & SettingOptionFlags) == 0 ))  /* temp hack */
+        CLIWandException(OptionError,"NoImagesFound",option);
+      goto next_token;
+    }
+
+    /* FUTURE: this is temporary - get 'settings' to handle
+       distribution of settings to images attributes,proprieties,artifacts */
+    SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
+          cli_wand->wand.exception);
 
     if ( (option_type & SimpleOperatorOptionFlag) != 0)
       CLISimpleOperatorImages(cli_wand, option, arg1, arg2);
@@ -509,24 +513,23 @@ WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc,
     arg1 = ( count >= 1 ) ? argv[i+1] : (char *)NULL;
     arg2 = ( count >= 2 ) ? argv[i+2] : (char *)NULL;
 
+    /*
+      Process Known Options
+    */
 #if MagickCommandDebug >= 3
     (void) FormatLocaleFile(stderr,
       "CLI %u Option: \"%s\"  Count: %d  Flags: %04x  Args: \"%s\" \"%s\"\n",
           i,option,count,option_type,arg1,arg2);
 #endif
-
+    /* Hard Depreciated Options, no code to execute - error */
     if ( (option_type & DeprecateOptionFlag) != 0 ) {
       CLIWandException(OptionError,"DeprecatedOptionNoCode",option);
       goto next_argument;
     }
-    if ( (option_type & GenesisOptionFlag) != 0 ) {
-      goto next_argument;  /* ignore MagickCommandGenesis() Only Option */
-    }
-    if (((option_type & ImageRequiredFlags) != 0 ) &&
-        ( cli_wand->wand.images == (Image *)NULL ) ) {
-      CLIWandException(OptionError,"NoImagesFound",option);
+
+    /* Ignore MagickCommandGenesis() only option on CLI */
+    if ( (option_type & GenesisOptionFlag) != 0 )
       goto next_argument;
-    }
 
     if ( (option_type & SpecialOptionFlag) != 0 ) {
       if ( (cli_wand->process_flags & ProcessExitOption) != 0
@@ -540,8 +543,20 @@ WandExport int ProcessCommandOptions(MagickCLI *cli_wand, int argc,
       CLISettingOptionInfo(cli_wand, option, arg1, arg2);
       // FUTURE: Sync individual Settings into images (no SyncImageSettings())
     }
-    if ( cli_wand->wand.images != (Image *)NULL )
-      SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
+
+    /* FUTURE: The not a setting part below is a temporary hack to stop gap
+     * measure for options that are BOTH settings and optional 'Simple/List'
+     * operators.  Specifically -monitor  and  -colorspace */
+    if ( cli_wand->wand.images == (Image *)NULL ) {
+      if (((option_type & ImageRequiredFlags) != 0 ) &&
+          ((option_type & SettingOptionFlags) == 0 )  )  /* temp hack */
+        CLIWandException(OptionError,"NoImagesFound",option);
+      goto next_argument;
+    }
+
+    /* FUTURE: this is temporary - get 'settings' to handle
+       distribution of settings to images attributes,proprieties,artifacts */
+    SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
           cli_wand->wand.exception);
 
     if ( (option_type & SimpleOperatorOptionFlag) != 0)
index 6e12e1421ff43b62d1d5a7edf1abefc2ba50186c..f587b6cf7b219149bc847152093865afe4a7ff67 100644 (file)
@@ -65,6 +65,9 @@
 #define MAX_STACK_DEPTH  32
 #define UNDEFINED_COMPRESSION_QUALITY  0UL
 
+/* FUTURE: why is this default so specific? */
+#define DEFAULT_DISSIMILARITY_THRESHOLD "0.31830988618379067154"
+
 /*
   Constant declaration. (temporary exports)
 */
@@ -148,29 +151,6 @@ static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
   return(image);
 }
 
-#if 0
-/*
-  FloatListOption() converts a string option of space or comma seperated
-  numbers into a list of floating point numbers, required by some operations.
-*/
-static MagickBooleanType FloatListOption(const char *option,
-     size_t *number_arguments, double **arguments, ExceptionInfo *exception)
-{
-  char
-    token[MaxTextExtent];
-
-  const char
-    *p;
-
-  MagickBooleanType
-    error;
-
-  register size_t
-    x;
-
-}
-#endif
-
 /*
   SparseColorOption() parse the complex -sparse-color argument into an
   an array of floating point values than call SparseColorImage().
@@ -217,7 +197,8 @@ static Image *SparseColorOption(const Image *image,
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
   /*
-    Limit channels according to image - and add up number of color channel.
+    Limit channels according to image
+    add up number of values needed per color.
   */
   number_colors=0;
   if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
@@ -767,6 +748,16 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
           (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
           break;
         }
+      if (LocaleCompare("dissimilarity-threshold",option+1) == 0)
+        {
+          /* FUTURE: this is only used by CompareImages() which is used
+             only by the "compare" CLI program at this time.  */
+          arg1=ArgOption(DEFAULT_DISSIMILARITY_THRESHOLD);
+          if (IfMagickFalse(IsGeometry(arg1)))
+            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+          (void) SetImageOption(_image_info,option+1,arg1);
+          break;
+        }
       if (LocaleCompare("dither",option+1) == 0)
         {
           /* _image_info attr (on/off), _quantize_info attr (on/off)
@@ -928,6 +919,17 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
+    case 'h':
+    {
+      if (LocaleCompare("highlight-color",option+1) == 0)
+        {
+          /* FUTURE: this is only used by CompareImages() which is used
+             only by the "compare" CLI program at this time.  */
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
+          break;
+        }
+      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
+    }
     case 'i':
     {
       if (LocaleCompare("intent",option+1) == 0)
@@ -1034,6 +1036,8 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
         }
       if (LocaleCompare("lowlight-color",option+1) == 0)
         {
+          /* FUTURE: this is only used by CompareImages() which is used
+             only by the "compare" CLI program at this time.  */
           (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
           break;
         }
@@ -1057,6 +1061,16 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
           (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
              &_image_info->matte_color,_exception);
           break;
+        } 
+      if (LocaleCompare("metric",option+1) == 0)
+        {
+          /* FUTURE: this is only used by CompareImages() which is used
+             only by the "compare" CLI program at this time.  */
+          parse=ParseCommandOption(MagickMetricOptions,MagickFalse,arg1);
+          if ( parse < 0 )
+            CLIWandExceptArgBreak(OptionError,"UnrecognizedMetricType",
+                option,arg1);
+          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
         }
       if (LocaleCompare("monitor",option+1) == 0)
         {
@@ -1350,6 +1364,13 @@ WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
           _draw_info->style=(StyleType) parse;
           break;
         }
+      if (LocaleCompare("subimage-search",option+1) == 0)
+        {
+        /* FUTURE: this is only used by CompareImages() which is used
+            only by the "compare" CLI program at this time.  */
+          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
+          break;
+        }
       if (LocaleCompare("synchronize",option+1) == 0)
         {
           /* FUTURE: syncronize to storage - but what does that mean? */
@@ -2152,20 +2173,13 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
       if (LocaleCompare("distort",option+1) == 0)
         {
           char
-            *args,
-            token[MaxTextExtent];
-
-          const char
-            *p;
+            *arg;
 
           double
-            *arguments;
-
-          register ssize_t
-            x;
+            *args;
 
-          size_t
-            number_arguments;
+          ssize_t
+            count;
 
           parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
           if ( parse < 0 )
@@ -2189,42 +2203,19 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
                     (size_t)2,resize_args,MagickTrue,_exception);
                break;
             }
-          /* handle percent arguments */
-          args=InterpretImageProperties(_image_info,_image,arg2,_exception);
-          if (args == (char *) NULL)
+          /* allow percent escapes in argument string */
+          arg=InterpretImageProperties(_image_info,_image,arg2,_exception);
+          if (arg == (char *) NULL)
             break;
-          /* convert arguments into an array of doubles
-             FUTURE: make this a separate function.
-             Also make use of new 'sentinal' feature to avoid need for
-             tokenization.
-          */
-          p=(char *) args;
-          for (x=0; *p != '\0'; x++)
-          {
-            GetMagickToken(p,&p,token);
-            if (*token == ',')
-              GetMagickToken(p,&p,token);
-          }
-          number_arguments=(size_t) x;
-          arguments=(double *) AcquireQuantumMemory(number_arguments,
-            sizeof(*arguments));
-          if (arguments == (double *) NULL)
-            CLIWandExceptionBreak(ResourceLimitFatalError,
-                                "MemoryAllocationFailed",option);
-          (void) ResetMagickMemory(arguments,0,number_arguments*
-                        sizeof(*arguments));
-          p=(char *) args;
-          for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
-          {
-            GetMagickToken(p,&p,token);
-            if (*token == ',')
-              GetMagickToken(p,&p,token);
-            arguments[x]=StringToDouble(token,(char **) NULL);
-          }
-          args=DestroyString(args);
-          new_image=DistortImage(_image,(DistortImageMethod) parse,
-               number_arguments,arguments,plus_alt_op,_exception);
-          arguments=(double *) RelinquishMagickMemory(arguments);
+          /* convert argument string into an array of doubles */
+          args = StringToArrayOfDoubles(arg,&count,_exception);
+          arg=DestroyString(arg);
+          if (args == (double *)NULL )
+            CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
+
+          new_image=DistortImage(_image,(DistortImageMethod) parse,count,args,
+               plus_alt_op,_exception);
+          args=(double *) RelinquishMagickMemory(args);
           break;
         }
       if (LocaleCompare("draw",option+1) == 0)
@@ -2386,59 +2377,31 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
       if (LocaleCompare("function",option+1) == 0)
         {
           char
-            *arguments,
-            token[MaxTextExtent];
-
-          const char
-            *p;
+            *arg;
 
           double
-            *parameters;
+            *args;
 
-          register ssize_t
-            x;
-
-          size_t
-            number_parameters;
+          ssize_t
+            count;
 
-          /*
-            Function Modify Image Values
-            FUTURE: code should be almost a duplicate of that is "distort"
-          */
           parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
           if ( parse < 0 )
             CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
                  option,arg1);
-          arguments=InterpretImageProperties(_image_info,_image,arg2,
-            _exception);
-          if (arguments == (char *) NULL)
-            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
-          p=(char *) arguments;
-          for (x=0; *p != '\0'; x++)
-          {
-            GetMagickToken(p,&p,token);
-            if (*token == ',')
-              GetMagickToken(p,&p,token);
-          }
-          number_parameters=(size_t) x;
-          parameters=(double *) AcquireQuantumMemory(number_parameters,
-            sizeof(*parameters));
-          if (parameters == (double *) NULL)
-            ThrowWandFatalException(ResourceLimitFatalError,
-              "MemoryAllocationFailed",_image->filename);
-          (void) ResetMagickMemory(parameters,0,number_parameters*
-            sizeof(*parameters));
-          p=(char *) arguments;
-          for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++) {
-            GetMagickToken(p,&p,token);
-            if (*token == ',')
-              GetMagickToken(p,&p,token);
-            parameters[x]=StringToDouble(token,(char **) NULL);
-          }
-          arguments=DestroyString(arguments);
-          (void) FunctionImage(_image,(MagickFunction)parse,number_parameters,
-                  parameters,_exception);
-          parameters=(double *) RelinquishMagickMemory(parameters);
+          /* allow percent escapes in argument string */
+          arg=InterpretImageProperties(_image_info,_image,arg2,_exception);
+          if (arg == (char *) NULL)
+            break;
+          /* convert argument string into an array of doubles */
+          args = StringToArrayOfDoubles(arg,&count,_exception);
+          arg=DestroyString(arg);
+          if (args == (double *)NULL )
+            CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
+
+          (void) FunctionImage(_image,(MagickFunction)parse,count,args,
+               _exception);
+          args=(double *) RelinquishMagickMemory(args);
           break;
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
@@ -2498,15 +2461,6 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
         }
       CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
     }
-    case 'h':
-    {
-      if (LocaleCompare("highlight-color",option+1) == 0)
-        {
-          (void) SetImageArtifact(_image,option+1,arg1);
-          break;
-        }
-      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
-    }
     case 'i':
     {
       if (LocaleCompare("identify",option+1) == 0)
@@ -3237,8 +3191,7 @@ static void CLISimpleOperatorImage(MagickCLI *cli_wand,
             geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
               100.0;
           (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
-               geometry_info.sigma,
-            _exception);
+               geometry_info.sigma,_exception);
           break;
         }
       if (LocaleCompare("sketch",option+1) == 0)
@@ -4102,6 +4055,7 @@ WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
         }
       if (LocaleCompare("process",option+1) == 0)
         {
+          /* FUTURE: better parsing using ScriptToken() from string ??? */
           char
             **arguments;
 
index 4b9618bb4b80e78417c157d9e62568763a959e31..b0d350b44ab68ee2e86a0cf865af239b00130afd 100644 (file)
@@ -33,7 +33,7 @@ extern "C" {
 #define CLIWandWarnDepreciated(message) \
   if ( (cli_wand->process_flags & ProcessWarnDepreciated) != 0 ) \
     (void) CLIThrowException(cli_wand,GetMagickModule(),OptionWarning, \
-       "DeprecatedOption", "'%s' use \"%s\" instead",option,message)
+       "DeprecatedOption", "'%s', use \"%s\"",option,message)
 
 #define CLIWandExceptionFile(severity,tag,context) \
 { char *message=GetExceptionMessage(errno); \
index 7e075fba39342a2db5dfd94fcd08e1f6da825acc..4ff958b16f250aa1cf9a01b6459c7cba80ac1c7f 100644 (file)
         <message name="InvalidImageIndex">
           invalid image index
         </message>
+        <message name="InvalidNumberList">
+          invalid list of numbers
+        </message>
         <message name="ImagesAreNotTheSameSize">
           images are not the same size
         </message>
index b2861214381f6202e774f5b9d59cad289de5d550..241798f4c982088de3572967ebee0def30fc4496 100644 (file)
         <message name="InvalidImageIndex">
           index de l'image non valide
         </message>
+        <message name="InvalidNumberList">
+          liste des numéros non valide
+        </message>
         <message name="ImagesAreNotTheSameSize">
           images diffèrent par la taille
         </message>