]> granicus.if.org Git - imagemagick/blobdiff - magick/gem.c
(no commit message)
[imagemagick] / magick / gem.c
index a53427c57b54350e1ae2cc4804881038faefd70b..f2cd994e7cbd40f99a0368fdca26f487a80ff3e0 100644 (file)
@@ -17,7 +17,7 @@
 %                                 August 1996                                 %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2011 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  %
@@ -100,7 +100,7 @@ MagickExport void ConvertHSBToRGB(const double hue,const double saturation,
   assert(blue != (Quantum *) NULL);
   if (saturation == 0.0)
     {
-      *red=RoundToQuantum((MagickRealType) QuantumRange*brightness);
+      *red=ClampToQuantum((MagickRealType) QuantumRange*brightness);
       *green=(*red);
       *blue=(*red);
       return;
@@ -115,44 +115,44 @@ MagickExport void ConvertHSBToRGB(const double hue,const double saturation,
     case 0:
     default:
     {
-      *red=RoundToQuantum((MagickRealType) QuantumRange*brightness);
-      *green=RoundToQuantum((MagickRealType) QuantumRange*t);
-      *blue=RoundToQuantum((MagickRealType) QuantumRange*p);
+      *red=ClampToQuantum((MagickRealType) QuantumRange*brightness);
+      *green=ClampToQuantum((MagickRealType) QuantumRange*t);
+      *blue=ClampToQuantum((MagickRealType) QuantumRange*p);
       break;
     }
     case 1:
     {
-      *red=RoundToQuantum((MagickRealType) QuantumRange*q);
-      *green=RoundToQuantum((MagickRealType) QuantumRange*brightness);
-      *blue=RoundToQuantum((MagickRealType) QuantumRange*p);
+      *red=ClampToQuantum((MagickRealType) QuantumRange*q);
+      *green=ClampToQuantum((MagickRealType) QuantumRange*brightness);
+      *blue=ClampToQuantum((MagickRealType) QuantumRange*p);
       break;
     }
     case 2:
     {
-      *red=RoundToQuantum((MagickRealType) QuantumRange*p);
-      *green=RoundToQuantum((MagickRealType) QuantumRange*brightness);
-      *blue=RoundToQuantum((MagickRealType) QuantumRange*t);
+      *red=ClampToQuantum((MagickRealType) QuantumRange*p);
+      *green=ClampToQuantum((MagickRealType) QuantumRange*brightness);
+      *blue=ClampToQuantum((MagickRealType) QuantumRange*t);
       break;
     }
     case 3:
     {
-      *red=RoundToQuantum((MagickRealType) QuantumRange*p);
-      *green=RoundToQuantum((MagickRealType) QuantumRange*q);
-      *blue=RoundToQuantum((MagickRealType) QuantumRange*brightness);
+      *red=ClampToQuantum((MagickRealType) QuantumRange*p);
+      *green=ClampToQuantum((MagickRealType) QuantumRange*q);
+      *blue=ClampToQuantum((MagickRealType) QuantumRange*brightness);
       break;
     }
     case 4:
     {
-      *red=RoundToQuantum((MagickRealType) QuantumRange*t);
-      *green=RoundToQuantum((MagickRealType) QuantumRange*p);
-      *blue=RoundToQuantum((MagickRealType) QuantumRange*brightness);
+      *red=ClampToQuantum((MagickRealType) QuantumRange*t);
+      *green=ClampToQuantum((MagickRealType) QuantumRange*p);
+      *blue=ClampToQuantum((MagickRealType) QuantumRange*brightness);
       break;
     }
     case 5:
     {
-      *red=RoundToQuantum((MagickRealType) QuantumRange*brightness);
-      *green=RoundToQuantum((MagickRealType) QuantumRange*p);
-      *blue=RoundToQuantum((MagickRealType) QuantumRange*q);
+      *red=ClampToQuantum((MagickRealType) QuantumRange*brightness);
+      *green=ClampToQuantum((MagickRealType) QuantumRange*p);
+      *blue=ClampToQuantum((MagickRealType) QuantumRange*q);
       break;
     }
   }
@@ -220,12 +220,12 @@ MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
   assert(blue != (Quantum *) NULL);
   if (saturation == 0)
     {
-      *red=RoundToQuantum((MagickRealType) QuantumRange*lightness);
+      *red=ClampToQuantum((MagickRealType) QuantumRange*lightness);
       *green=(*red);
       *blue=(*red);
       return;
     }
-  if (lightness <= 0.5)
+  if (lightness < 0.5)
     m2=lightness*(saturation+1.0);
   else
     m2=(lightness+saturation)-(lightness*saturation);
@@ -233,9 +233,9 @@ MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
   r=ConvertHueToRGB(m1,m2,hue+1.0/3.0);
   g=ConvertHueToRGB(m1,m2,hue);
   b=ConvertHueToRGB(m1,m2,hue-1.0/3.0);
-  *red=RoundToQuantum((MagickRealType) QuantumRange*r);
-  *green=RoundToQuantum((MagickRealType) QuantumRange*g);
-  *blue=RoundToQuantum((MagickRealType) QuantumRange*b);
+  *red=ClampToQuantum((MagickRealType) QuantumRange*r);
+  *green=ClampToQuantum((MagickRealType) QuantumRange*g);
+  *blue=ClampToQuantum((MagickRealType) QuantumRange*b);
 }
 \f
 /*
@@ -276,7 +276,7 @@ MagickExport void ConvertHWBToRGB(const double hue,const double whiteness,
     r,
     v;
 
-  register long
+  register ssize_t
     i;
 
   /*
@@ -288,12 +288,12 @@ MagickExport void ConvertHWBToRGB(const double hue,const double whiteness,
   v=1.0-blackness;
   if (hue == 0.0)
     {
-      *red=RoundToQuantum((MagickRealType) QuantumRange*v);
-      *green=RoundToQuantum((MagickRealType) QuantumRange*v);
-      *blue=RoundToQuantum((MagickRealType) QuantumRange*v);
+      *red=ClampToQuantum((MagickRealType) QuantumRange*v);
+      *green=ClampToQuantum((MagickRealType) QuantumRange*v);
+      *blue=ClampToQuantum((MagickRealType) QuantumRange*v);
       return;
     }
-  i=(long) floor(6.0*hue);
+  i=(ssize_t) floor(6.0*hue);
   f=6.0*hue-i;
   if ((i & 0x01) != 0)
     f=1.0-f;
@@ -309,9 +309,9 @@ MagickExport void ConvertHWBToRGB(const double hue,const double whiteness,
     case 4: r=n; g=whiteness; b=v; break;
     case 5: r=v; g=whiteness; b=n; break;
   }
-  *red=RoundToQuantum((MagickRealType) QuantumRange*r);
-  *green=RoundToQuantum((MagickRealType) QuantumRange*g);
-  *blue=RoundToQuantum((MagickRealType) QuantumRange*b);
+  *red=ClampToQuantum((MagickRealType) QuantumRange*r);
+  *green=ClampToQuantum((MagickRealType) QuantumRange*g);
+  *blue=ClampToQuantum((MagickRealType) QuantumRange*b);
 }
 \f
 /*
@@ -372,20 +372,16 @@ MagickExport void ConvertRGBToHSB(const Quantum red,const Quantum green,
   *brightness=(double) (QuantumScale*max);
   if (delta == 0.0)
     return;
-  if (red == max)
-    *hue=((((max-blue)/6.0)+(delta/2.0))-(((max-green)/6.0)+(delta/2.0)))/delta;
+  if ((MagickRealType) red == max)
+    *hue=(double) ((green-(MagickRealType) blue)/delta);
   else
-    if (green == max)
-      *hue=(1.0/3.0)+((((max-red)/6.0)+(delta/2.0))-(((max-blue)/6.0)+
-        (delta/2.0)))/delta;
+    if ((MagickRealType) green == max)
+      *hue=(double) (2.0+(blue-(MagickRealType) red)/delta);
     else
-      if (blue == max)
-        *hue=(2.0/3.0)+((((max-green)/6.0)+(delta/2.0))-(((max-red)/6.0)+
-          (delta/2.0)))/delta;
+      *hue=(double) (4.0+(red-(MagickRealType) green)/delta);
+  *hue/=6.0;
   if (*hue < 0.0)
     *hue+=1.0;
-  if (*hue > 1.0)
-    *hue-=1.0;
 }
 \f
 /*
@@ -512,14 +508,14 @@ MagickExport void ConvertRGBToHSL(const Quantum red,const Quantum green,
 MagickExport void ConvertRGBToHWB(const Quantum red,const Quantum green,
   const Quantum blue,double *hue,double *whiteness,double *blackness)
 {
+  long
+    i;
+
   MagickRealType
     f,
     v,
     w;
 
-  register long
-    i;
-
   /*
     Convert RGB to HWB colorspace.
   */
@@ -638,13 +634,15 @@ MagickExport double GenerateDifferentialNoise(RandomInfo *random_info,
     case GaussianNoise:
     {
       double
+        gamma,
         tau;
 
       if (alpha == 0.0)
         alpha=1.0;
       beta=GetPseudoRandomValue(random_info);
-      sigma=sqrt(-2.0*log(alpha))*cos(2.0*MagickPI*beta);
-      tau=sqrt(-2.0*log(alpha))*sin(2.0*MagickPI*beta);
+      gamma=sqrt(-2.0*log(alpha));
+      sigma=gamma*cos((double) (2.0*MagickPI*beta));
+      tau=gamma*sin((double) (2.0*MagickPI*beta));
       noise=(double) pixel+sqrt((double) pixel)*SigmaGaussian*sigma+
         TauGaussian*tau;
       break;
@@ -657,7 +655,7 @@ MagickExport double GenerateDifferentialNoise(RandomInfo *random_info,
         sigma=sqrt(-2.0*log(alpha));
       beta=GetPseudoRandomValue(random_info);
       noise=(double) pixel+pixel*SigmaMultiplicativeGaussian*sigma/2.0*
-        cos((2.0*MagickPI*beta));
+        cos((double) (2.0*MagickPI*beta));
       break;
     }
     case ImpulseNoise:
@@ -695,7 +693,7 @@ MagickExport double GenerateDifferentialNoise(RandomInfo *random_info,
       double
         poisson;
 
-      register long
+      register ssize_t
         i;
 
       poisson=exp(-SigmaPoisson*ScaleQuantumToChar(pixel));
@@ -709,7 +707,7 @@ MagickExport double GenerateDifferentialNoise(RandomInfo *random_info,
     }
     case RandomNoise:
     {
-      noise=(double) QuantumRange*GetPseudoRandomValue(random_info);
+      noise=(double) QuantumRange*alpha;
       break;
     }
   }
@@ -733,7 +731,7 @@ MagickExport double GenerateDifferentialNoise(RandomInfo *random_info,
 %
 %  The format of the GetOptimalKernelWidth method is:
 %
-%      unsigned long GetOptimalKernelWidth(const double radius,
+%      size_t GetOptimalKernelWidth(const double radius,
 %        const double sigma)
 %
 %  A description of each parameter follows:
@@ -747,80 +745,89 @@ MagickExport double GenerateDifferentialNoise(RandomInfo *random_info,
 %    o sigma: the standard deviation of the Gaussian, in pixels.
 %
 */
-MagickExport unsigned long GetOptimalKernelWidth1D(const double radius,
+MagickExport size_t GetOptimalKernelWidth1D(const double radius,
   const double sigma)
 {
-  long
-    width;
-
-  MagickRealType
+  double
+    alpha,
+    beta,
+    gamma,
     normalize,
     value;
 
-  register long
-    u;
+  register ssize_t
+    i;
+
+  size_t
+    width;
+
+  ssize_t
+    j;
 
   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
-  if (radius > 0.0)
-    return((unsigned long) (2.0*ceil(radius)+1.0));
-  if (fabs(sigma) <= MagickEpsilon)
-    return(1);
+  if (radius > MagickEpsilon)
+    return((size_t) (2.0*ceil(radius)+1.0));
+  gamma=fabs(sigma);
+  if (gamma <= MagickEpsilon)
+    return(3UL);
+  alpha=1.0/(2.0*gamma*gamma);
+  beta=(double) (1.0/(MagickSQ2PI*gamma));
   for (width=5; ; )
   {
     normalize=0.0;
-    for (u=(-width/2); u <= (width/2); u++)
-      normalize+=exp(-((double) u*u)/(2.0*sigma*sigma))/(MagickSQ2PI*sigma);
-    u=width/2;
-    value=exp(-((double) u*u)/(2.0*sigma*sigma))/(MagickSQ2PI*sigma)/normalize;
-    if ((long) (QuantumRange*value) <= 0L)
+    j=(ssize_t) width/2;
+    for (i=(-j); i <= j; i++)
+      normalize+=exp(-((double) (i*i))*alpha)*beta;
+    value=exp(-((double) (j*j))*alpha)*beta/normalize;
+    if ((value < QuantumScale) || (value < MagickEpsilon))
       break;
     width+=2;
   }
-  return((unsigned long) (width-2));
+  return((size_t) (width-2));
 }
 
-MagickExport unsigned long GetOptimalKernelWidth2D(const double radius,
+MagickExport size_t GetOptimalKernelWidth2D(const double radius,
   const double sigma)
 {
-
-  long
-    width;
-
-  MagickRealType
+  double
     alpha,
+    beta,
+    gamma,
     normalize,
     value;
 
-  register long
+  size_t
+    width;
+
+  ssize_t
+    j,
     u,
     v;
 
   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
-  if (radius > 0.0)
-    return((unsigned long) (2.0*ceil(radius)+1.0));
-  if (fabs(sigma) <= MagickEpsilon)
-    return(1);
+  if (radius > MagickEpsilon)
+    return((size_t) (2.0*ceil(radius)+1.0));
+  gamma=fabs(sigma);
+  if (gamma <= MagickEpsilon)
+    return(3UL);
+  alpha=1.0/(2.0*gamma*gamma);
+  beta=(double) (1.0/(Magick2PI*gamma*gamma));
   for (width=5; ; )
   {
     normalize=0.0;
-    for (v=(-width/2); v <= (width/2); v++)
-    {
-      for (u=(-width/2); u <= (width/2); u++)
-      {
-        alpha=exp(-((double) u*u+v*v)/(2.0*sigma*sigma));
-        normalize+=alpha/(2.0*MagickPI*sigma*sigma);
-      }
-    }
-    v=width/2;
-    value=exp(-((double) v*v)/(2.0*sigma*sigma))/normalize;
-    if ((long) (QuantumRange*value) <= 0L)
+    j=(ssize_t) width/2;
+    for (v=(-j); v <= j; v++)
+      for (u=(-j); u <= j; u++)
+        normalize+=exp(-((double) (u*u+v*v))*alpha)*beta;
+    value=exp(-((double) (j*j))*alpha)*beta/normalize;
+    if ((value < QuantumScale) || (value < MagickEpsilon))
       break;
     width+=2;
   }
-  return((unsigned long) (width-2));
+  return((size_t) (width-2));
 }
 
-MagickExport unsigned long  GetOptimalKernelWidth(const double radius,
+MagickExport size_t  GetOptimalKernelWidth(const double radius,
   const double sigma)
 {
   return(GetOptimalKernelWidth1D(radius,sigma));