]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authoranthony <anthony@git.imagemagick.org>
Thu, 13 Dec 2012 23:54:34 +0000 (23:54 +0000)
committeranthony <anthony@git.imagemagick.org>
Thu, 13 Dec 2012 23:54:34 +0000 (23:54 +0000)
MagickCore/distort.c

index ec1b9a8a631e72430ec9212e00b3df6b359b4b1a..e3162d75cde9cd5b229a8042c39315fbdb193f15 100644 (file)
@@ -471,7 +471,7 @@ static double *GenerateCoefficients(const Image *image,
 #endif
       break;
     case ShepardsDistortion:
-      number_coeff=1;  /* not used, but provide some type of return */
+      number_coeff=1;  /* The power factor to use */
       break;
     case ArcDistortion:
       number_coeff=5;
@@ -1408,11 +1408,25 @@ static double *GenerateCoefficients(const Image *image,
       if ( number_arguments%cp_size != 0 ||
            number_arguments < cp_size ) {
         (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
-              "InvalidArgument", "%s : 'require at least %.20g CPs'",
-              CommandOptionToMnemonic(MagickDistortOptions, *method), 1.0);
+              "InvalidArgument", "%s : 'requires CP's (4 numbers each)'",
+              CommandOptionToMnemonic(MagickDistortOptions, *method));
         coeff=(double *) RelinquishMagickMemory(coeff);
         return((double *) NULL);
       }
+      /* User defined weighting power for Shepard's Method */
+      { const char *artifact=GetImageArtifact(image,"shepards:power");
+        if ( artifact != (const char *) NULL ) {
+          coeff[0]=StringToDouble(artifact,(char **) NULL) / 2.0;
+          if ( coeff[0] < MagickEpsilon ) {
+            (void) ThrowMagickException(exception,GetMagickModule(),
+                OptionError,"InvalidArgument","%s", "-define shepards:power" );
+            coeff=(double *) RelinquishMagickMemory(coeff);
+            return((double *) NULL);
+          }
+        }
+        else
+          coeff[0]=1.0;  /* Default power of 2 (Inverse Squared) */
+      }
       return(coeff);
     }
     default:
@@ -1463,9 +1477,6 @@ MagickExport Image *DistortResizeImage(const Image *image,
 {
 #define DistortResizeImageTag  "Distort/Image"
 
-  double
-    distort_args[12];
-
   Image
     *resize_image,
     *tmp_image;
@@ -1473,6 +1484,9 @@ MagickExport Image *DistortResizeImage(const Image *image,
   RectangleInfo
     crop_area;
 
+  double
+    distort_args[12];
+
   VirtualPixelMethod
     vp_save;
 
@@ -2665,10 +2679,13 @@ if ( d.x == 0.5 && d.y == 0.5 ) {
           }
           case ShepardsDistortion:
           { /* Shepards Method, or Inverse Weighted Distance for
-              displacement around the destination image control points
-              The input arguments are the coefficents to the function.
-              This is more of a 'displacement' function rather than an
-              absolute distortion function.
+               displacement around the destination image control points
+               The input arguments are the coefficents to the function.
+               This is more of a 'displacement' function rather than an
+               absolute distortion function.
+
+               Note: We can not determine derivatives using shepards method
+               so only a point sample interpolatation can be used.
             */
             size_t
               i;
@@ -2680,10 +2697,8 @@ if ( d.x == 0.5 && d.y == 0.5 ) {
               double weight =
                   ((double)d.x-arguments[i+2])*((double)d.x-arguments[i+2])
                 + ((double)d.y-arguments[i+3])*((double)d.y-arguments[i+3]);
-              if ( weight != 0 )
-                weight = 1/weight;
-              else
-                weight = 1;
+              weight = pow(weight,coeff[0]); /* shepards power factor */
+              weight = ( weight < 1.0 ) ? 1.0 : 1.0/weight;
 
               s.x += (arguments[ i ]-arguments[i+2])*weight;
               s.y += (arguments[i+1]-arguments[i+3])*weight;
@@ -2691,11 +2706,8 @@ if ( d.x == 0.5 && d.y == 0.5 ) {
             }
             s.x /= denominator;
             s.y /= denominator;
-            s.x += d.x;
+            s.x += d.x;   /* make it as relative displacement */
             s.y += d.y;
-
-            /* We can not determine derivatives using shepards method
-               only color interpolatation, not area-resampling */
             break;
           }
           default:
@@ -2944,7 +2956,9 @@ MagickExport Image *SparseColorImage(const Image *image,
     */
     sparse_method = (SparseColorMethod) distort_method;
     if ( distort_method == ShepardsDistortion )
-      sparse_method = method;   /* return non-distiort methods to normal */
+      sparse_method = method;   /* return non-distort methods to normal */
+    if ( sparse_method == InverseColorInterpolate )
+      coeff[0]=0.5;            /* sqrt() the squared distance for inverse */
   }
 
   /* Verbose output */
@@ -3139,8 +3153,7 @@ MagickExport Image *SparseColorImage(const Image *image,
               double weight =
                   ((double)i-arguments[ k ])*((double)i-arguments[ k ])
                 + ((double)j-arguments[k+1])*((double)j-arguments[k+1]);
-              if ( method == InverseColorInterpolate )
-                weight = sqrt(weight);  /* inverse, not inverse squared */
+              weight = pow(weight,coeff[0]); /* inverse of power factor */
               weight = ( weight < 1.0 ) ? 1.0 : 1.0/weight;
               if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
                 pixel.red     += arguments[x++]*weight;