]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/enhance.c
(no commit message)
[imagemagick] / MagickCore / enhance.c
index 44477517b2ba2477b79d1419fb0cf05b5009221a..4437c79eff11296b257ddd67d613d69bb96c7dab 100644 (file)
@@ -885,8 +885,17 @@ MagickExport MagickBooleanType ContrastImage(Image *image,
         Contrast enhance colormap.
       */
       for (i=0; i < (ssize_t) image->colors; i++)
-        Contrast(sign,&image->colormap[i].red,&image->colormap[i].green,
-          &image->colormap[i].blue);
+      {
+        double
+          blue,
+          green,
+          red;
+
+        Contrast(sign,&red,&green,&blue);
+        image->colormap[i].red=(MagickRealType) red;
+        image->colormap[i].red=(MagickRealType) red;
+        image->colormap[i].red=(MagickRealType) red;
+      }
     }
   /*
     Contrast enhance image.
@@ -1289,12 +1298,10 @@ MagickExport Image *EnhanceImage(const Image *image,ExceptionInfo *exception)
 {
 #define EnhancePixel(weight) \
   mean=((double) r[i]+GetPixelChannel(enhance_image,channel,q))/2.0; \
-  distance=(double) r[i]-(double) GetPixelChannel( \
-    enhance_image,channel,q); \
-  distance_squared=QuantumScale*(2.0*((double) QuantumRange+1.0)+ \
-    mean)*distance*distance; \
-  if (distance_squared < ((double) QuantumRange*(double) \
-      QuantumRange/25.0f)) \
+  distance=(double) r[i]-(double) GetPixelChannel(enhance_image,channel,q); \
+  distance_squared=QuantumScale*(2.0*((double) QuantumRange+1.0)+mean)* \
+    distance*distance; \
+  if (distance_squared < ((double) QuantumRange*(double) QuantumRange/25.0f)) \
     { \
       aggregate+=(weight)*r[i]; \
       total_weight+=(weight); \
@@ -3150,7 +3157,7 @@ MagickExport MagickBooleanType NegateImage(Image *image,
     Negate image.
   */
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
-  #pragma omp parallel for schedule(static) shared(progress,status) \
+  #pragma omp parallel for schedule(static,4) shared(progress,status) \
     dynamic_number_threads(image,image->columns,image->rows,1)
 #endif
   for (y=0; y < (ssize_t) image->rows; y++)
@@ -3294,21 +3301,27 @@ MagickExport MagickBooleanType NormalizeImage(Image *image,
 */
 
 /*
-  Sigmoidal function with inflexion point moved to b and "slope constant" set
-  to a.
+  ImageMagick 6 has a version of this function which uses LUTs.
+*/
+
+/*
+  Sigmoidal function Sigmoidal with inflexion point moved to b and "slope
+  constant" set to a.
+
   The first version, based on the hyperbolic tangent tanh, when combined with
   the scaling step, is an exact arithmetic clone of the the sigmoid function
   based on the logistic curve. The equivalence is based on the identity
 
-  1/(1+exp(-t)) = (1+tanh(t/2))/2
+    1/(1+exp(-t)) = (1+tanh(t/2))/2
+
+  (http://de.wikipedia.org/wiki/Sigmoidfunktion) and the fact that the
+  scaled sigmoidal derivation is invariant under affine transformations of
+  the ordinate.
 
-  (http://de.wikipedia.org/wiki/Sigmoidfunktion) and the fact that the scaled
-  sigmoidal derivation is invariant under affine transformations of the
-  ordinate.
-  The tanh version is almost certainly more accurate and cheaper.
-  The 0.5 factor in its argument is to clone the legacy ImageMagick behavior.
-  The reason for making the define depend on atanh even though it only uses
-  tanh has to do with the construction of the inverse of the scaled sigmoidal.
+  The tanh version is almost certainly more accurate and cheaper.  The 0.5
+  factor in the argument is to clone the legacy ImageMagick behavior. The
+  reason for making the define depend on atanh even though it only uses tanh
+  has to do with the construction of the inverse of the scaled sigmoidal.
 */
 #if defined(MAGICKCORE_HAVE_ATANH)
 #define Sigmoidal(a,b,x) ( tanh((0.5*(a))*((x)-(b))) )
@@ -3324,7 +3337,7 @@ MagickExport MagickBooleanType NormalizeImage(Image *image,
   See http://osdir.com/ml/video.image-magick.devel/2005-04/msg00006.html and
   http://www.cs.dartmouth.edu/farid/downloads/tutorials/fip.pdf.  The limit
   of ScaledSigmoidal as a->0 is the identity, but a=0 gives a division by
-  zero. This is fixed above by exiting immediately when contrast is small,
+  zero. This is fixed below by exiting immediately when contrast is small,
   leaving the image (or colormap) unmodified. This appears to be safe because
   the series expansion of the logistic sigmoidal function around x=b is
 
@@ -3341,14 +3354,15 @@ MagickExport MagickBooleanType NormalizeImage(Image *image,
   sigmoidal) may be outside of the interval (-1,1) (resp. (0,1)), even
   when creating a LUT from in gamut values, hence the branching.  In
   addition, HDRI may have out of gamut values.
-  InverseScaledSigmoidal is not a two-side inverse of ScaledSigmoidal:
+  InverseScaledSigmoidal is not a two-sided inverse of ScaledSigmoidal:
   It is only a right inverse. This is unavoidable.
 */
 static inline double InverseScaledSigmoidal(const double a,const double b,
   const double x)
 {
   const double sig0=Sigmoidal(a,b,0.0);
-  const double argument=(Sigmoidal(a,b,1.0)-sig0)*x+sig0;
+  const double sig1=Sigmoidal(a,b,1.0);
+  const double argument=(sig1-sig0)*x+sig0;
   const double clamped=
     (
 #if defined(MAGICKCORE_HAVE_ATANH)
@@ -3366,7 +3380,7 @@ static inline double InverseScaledSigmoidal(const double a,const double b,
       :
       ( argument > 1-MagickEpsilon ? 1-MagickEpsilon : argument )
     );
-  return(b+(-1.0/a)*log(1.0/clamped+-1.0));
+  return(b-log(1.0/clamped-1.0)/a);
 #endif
 }