]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/pixel.c
(no commit message)
[imagemagick] / MagickCore / pixel.c
index 4a12bec6efcdad74d583c78389ad3a6ca9a10f85..fbf27e31d28cb584945c093aeff0390ccc994a7a 100644 (file)
 %                  MagickCore Methods to Import/Export Pixels                 %
 %                                                                             %
 %                             Software Design                                 %
-%                               John Cristy                                   %
+%                                  Cristy                                     %
 %                               October 1998                                  %
 %                                                                             %
 %                                                                             %
-%  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  %
@@ -1466,7 +1466,8 @@ static void ExportLongLongPixel(Image *image,const RectangleInfo *roi,
           }
           case IndexQuantum:
           {
-            *q=ScaleQuantumToLongLong(ClampToQuantum(GetPixelIntensity(image,p)));
+            *q=ScaleQuantumToLongLong(ClampToQuantum(
+              GetPixelIntensity(image,p)));
             break;
           }
           default:
@@ -1894,9 +1895,9 @@ static void ExportShortPixel(Image *image,const RectangleInfo *roi,
   }
 }
 
-MagickExport MagickBooleanType ExportImagePixels(Image *image,
-  const ssize_t x,const ssize_t y,const size_t width,const size_t height,
-  const char *map,const StorageType type,void *pixels,ExceptionInfo *exception)
+MagickExport MagickBooleanType ExportImagePixels(Image *image,const ssize_t x,
+  const ssize_t y,const size_t width,const size_t height,const char *map,
+  const StorageType type,void *pixels,ExceptionInfo *exception)
 {
   QuantumType
     *quantum_map;
@@ -2136,12 +2137,14 @@ MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
 %
 %    Rec601Luma       0.298839R' + 0.586811G' + 0.114350B'
 %    Rec601Luminance  0.298839R + 0.586811G + 0.114350B
-%    Rec709Luma       0.21260R' + 0.71520G' + 0.07220B'
-%    Rec709Luminance  0.21260R + 0.71520G + 0.07220B
-%    Brightness       max(R, G, B)
-%    Lightness        (min(R, G, B) + max(R, G, B)) / 2.0
-%    RMS              (R'^2 + G'^2 + B'^2) / 3.0
-%    Average          (R' + G' + B') / 3.0
+%    Rec709Luma       0.212656R' + 0.715158G' + 0.072186B'
+%    Rec709Luminance  0.212656R + 0.715158G + 0.072186B
+%    Brightness       max(R', G', B')
+%    Lightness        (min(R', G', B') + max(R', G', B')) / 2.0
+% 
+%    MS               (R^2 + G^2 + B^2) / 3.0
+%    RMS              sqrt((R^2 + G^2 + B^2) / 3.0
+%    Average          (R + G + B') / 3.0
 %
 %  The format of the GetPixelIntensity method is:
 %
@@ -2200,7 +2203,8 @@ MagickExport MagickRealType GetPixelIntensity(const Image *restrict image,
     }
     case LightnessPixelIntensityMethod:
     {
-      intensity=MagickMin(MagickMin(red,green),blue);
+      intensity=(MagickMin(MagickMin(red,green),blue)+
+        MagickMax(MagickMax(red,green),blue))/2.0;
       break;
     }
     case MSPixelIntensityMethod:
@@ -2211,6 +2215,12 @@ MagickExport MagickRealType GetPixelIntensity(const Image *restrict image,
     }
     case Rec601LumaPixelIntensityMethod:
     {
+      if (image->colorspace == RGBColorspace)
+        {
+          red=EncodePixelGamma(red);
+          green=EncodePixelGamma(green);
+          blue=EncodePixelGamma(blue);
+        }
       intensity=0.298839*red+0.586811*green+0.114350*blue;
       break;
     }
@@ -2228,7 +2238,13 @@ MagickExport MagickRealType GetPixelIntensity(const Image *restrict image,
     case Rec709LumaPixelIntensityMethod:
     default:
     {
-      intensity=0.21260f*red+0.71520f*green+0.07220f*blue;
+      if (image->colorspace == RGBColorspace)
+        {
+          red=EncodePixelGamma(red);
+          green=EncodePixelGamma(green);
+          blue=EncodePixelGamma(blue);
+        }
+      intensity=0.212656*red+0.715158*green+0.072186*blue;
       break;
     }
     case Rec709LuminancePixelIntensityMethod:
@@ -2239,7 +2255,7 @@ MagickExport MagickRealType GetPixelIntensity(const Image *restrict image,
           green=DecodePixelGamma(green);
           blue=DecodePixelGamma(blue);
         }
-      intensity=0.21260f*red+0.71520f*green+0.07220f*blue;
+      intensity=0.212656*red+0.715158*green+0.072186*blue;
       break;
     }
     case RMSPixelIntensityMethod:
@@ -4092,7 +4108,7 @@ MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
     {
       quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
       (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
-        "UnrecognizedPixelMap","`%s'",map);
+        "UnrecognizedStorageType","`%d'",type);
       break;
     }
   }
@@ -4344,11 +4360,10 @@ static inline void SplineWeights(const double x,double (*weights)[4])
     beta;
 
   /*
-    Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the
-    computation of the standard four 1D cubic B-spline smoothing
-    weights. The sampling location is assumed between the second and
-    third input pixel locations, and x is the position relative to the
-    second input pixel location.
+    Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the computation
+    of the standard four 1D cubic B-spline smoothing weights. The sampling
+    location is assumed between the second and third input pixel locations,
+    and x is the position relative to the second input pixel location.
   */
   alpha=(double) 1.0-x;
   (*weights)[3]=(double) (1.0/6.0)*x*x*x;
@@ -4378,14 +4393,17 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
   const PixelInterpolateMethod method,const double x,const double y,
   double *pixel,ExceptionInfo *exception)
 {
-  MagickBooleanType
-    status;
-
   double
     alpha[16],
     gamma,
     pixels[16];
 
+  MagickBooleanType
+    status;
+
+  PixelInterpolateMethod
+    interpolate;
+
   PixelTrait
     traits;
 
@@ -4399,9 +4417,6 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
     x_offset,
     y_offset;
 
-  PixelInterpolateMethod
-    interpolate;
-
   assert(image != (Image *) NULL);
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
@@ -4416,9 +4431,9 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
     interpolate = image->interpolate;
   switch (interpolate)
   {
-    case AverageInterpolatePixel:        /* nearest 4 neighbours */
-    case Average9InterpolatePixel:       /* nearest 9 neighbours */
-    case Average16InterpolatePixel:      /* nearest 16 neighbours */
+    case AverageInterpolatePixel:  /* nearest 4 neighbours */
+    case Average9InterpolatePixel:  /* nearest 9 neighbours */
+    case Average16InterpolatePixel:  /* nearest 16 neighbours */
     {
       ssize_t
         count;
@@ -4444,7 +4459,7 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
           status=MagickFalse;
           break;
         }
-      count*=count;   /* Number of pixels to Average */
+      count*=count;  /* Number of pixels to average */
       if ((traits & BlendPixelTrait) == 0)
         for (i=0; i < (ssize_t) count; i++)
         {
@@ -4523,7 +4538,7 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
             GetPixelChannels(image));
           pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
         }
-      gamma=1.0;    /* number of pixels blended together (its variable) */
+      gamma=1.0;  /* number of pixels blended together (its variable) */
       for (i=0; i <= 1L; i++) {
         if ((y-y_offset) >= 0.75)
           {
@@ -4551,9 +4566,9 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
             pixels[0]+=pixels[1];
           }
       if (channel != AlphaPixelChannel)
-        gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
+        gamma=PerceptibleReciprocal(alpha[0]);  /* (color) 1/alpha_weights */
       else
-        gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
+        gamma=PerceptibleReciprocal(gamma);  /* (alpha) 1/number_of_pixels */
       *pixel=gamma*pixels[0];
       break;
     }
@@ -4649,10 +4664,10 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
         }
       delta.x=x-x_offset;
       delta.y=y-y_offset;
-      luminance.x=GetPixelLuminance(image,p)-(double)
-        GetPixelLuminance(image,p+3*GetPixelChannels(image));
-      luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
-        GetPixelLuminance(image,p+2*GetPixelChannels(image));
+      luminance.x=GetPixelLuma(image,p)-(double)
+        GetPixelLuma(image,p+3*GetPixelChannels(image));
+      luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double)
+        GetPixelLuma(image,p+2*GetPixelChannels(image));
       if (fabs(luminance.x) < fabs(luminance.y))
         {
           /*
@@ -4836,9 +4851,9 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
     interpolate = source->interpolate;
   switch (interpolate)
   {
-    case AverageInterpolatePixel:        /* nearest 4 neighbours */
-    case Average9InterpolatePixel:       /* nearest 9 neighbours */
-    case Average16InterpolatePixel:      /* nearest 16 neighbours */
+    case AverageInterpolatePixel:  /* nearest 4 neighbours */
+    case Average9InterpolatePixel:  /* nearest 9 neighbours */
+    case Average16InterpolatePixel:  /* nearest 16 neighbours */
     {
       ssize_t
         count;
@@ -4864,7 +4879,7 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
           status=MagickFalse;
           break;
         }
-      count*=count;  /* Number of pixels to Average */
+      count*=count;  /* Number of pixels to average */
       for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
       {
         double
@@ -5006,7 +5021,7 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
           else
             if ((y-y_offset) > 0.25)
               {
-                gamma=2.0;              /* blend both pixels in row */
+                gamma=2.0;  /* blend both pixels in row */
                 alpha[j]+=alpha[j+2];  /* add up alpha weights */
                 pixels[j]+=pixels[j+2];
               }
@@ -5024,9 +5039,9 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
                pixels[0]+=pixels[1];
              }
         if ((traits & BlendPixelTrait) == 0)
-          gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
+          gamma=PerceptibleReciprocal(alpha[0]);  /* (color) 1/alpha_weights */
         else
-          gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
+          gamma=PerceptibleReciprocal(gamma);  /* (alpha) 1/number_of_pixels */
         SetPixelChannel(destination,channel,ClampToQuantum(gamma*pixels[0]),
           pixel);
       }
@@ -5175,10 +5190,10 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
           }
         delta.x=x-x_offset;
         delta.y=y-y_offset;
-        luminance.x=fabs((double) (GetPixelLuminance(source,p)-
-          GetPixelLuminance(source,p+3*GetPixelChannels(source))));
-        luminance.y=fabs((double) (GetPixelLuminance(source,p+
-          GetPixelChannels(source))-GetPixelLuminance(source,p+2*
+        luminance.x=fabs((double) (GetPixelLuma(source,p)-
+          GetPixelLuma(source,p+3*GetPixelChannels(source))));
+        luminance.y=fabs((double) (GetPixelLuma(source,p+
+          GetPixelChannels(source))-GetPixelLuma(source,p+2*
           GetPixelChannels(source))));
         if (luminance.x < luminance.y)
           {
@@ -5401,9 +5416,9 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
     interpolate = image->interpolate;
   switch (interpolate)
   {
-    case AverageInterpolatePixel:        /* nearest 4 neighbours */
-    case Average9InterpolatePixel:       /* nearest 9 neighbours */
-    case Average16InterpolatePixel:      /* nearest 16 neighbours */
+    case AverageInterpolatePixel:  /* nearest 4 neighbours */
+    case Average9InterpolatePixel:  /* nearest 9 neighbours */
+    case Average16InterpolatePixel:  /* nearest 16 neighbours */
     {
       ssize_t
         count;
@@ -5433,7 +5448,7 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
       pixel->blue=0.0;
       pixel->black=0.0;
       pixel->alpha=0.0;
-      count*=count;         /* number of pixels - square of size */
+      count*=count;  /* number of pixels - square of size */
       for (i=0; i < (ssize_t) count; i++)
       {
         AlphaBlendPixelInfo(image,p,pixels,alpha);
@@ -5538,7 +5553,7 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
         if ((x-x_offset) > 0.25)
           {
             gamma*=2.0;  /* blend both rows */
-            alpha[0]+= alpha[1];      /* add up alpha weights */
+            alpha[0]+= alpha[1];  /* add up alpha weights */
             pixels[0].red+=pixels[1].red;
             pixels[0].green+=pixels[1].green;
             pixels[0].blue+=pixels[1].blue;
@@ -5631,10 +5646,10 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
         }
       delta.x=x-x_offset;
       delta.y=y-y_offset;
-      luminance.x=GetPixelLuminance(image,p)-(double)
-        GetPixelLuminance(image,p+3*GetPixelChannels(image));
-      luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
-        GetPixelLuminance(image,p+2*GetPixelChannels(image));
+      luminance.x=GetPixelLuma(image,p)-(double)
+        GetPixelLuma(image,p+3*GetPixelChannels(image));
+      luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double)
+        GetPixelLuma(image,p+2*GetPixelChannels(image));
       AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
       AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
       AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
@@ -5847,8 +5862,8 @@ MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
     distance,
     scale;
 
-  fuzz=MagickMax(source->fuzz,(double) MagickSQ1_2)*MagickMax(
-    destination->fuzz,(double) MagickSQ1_2);
+  fuzz=(double) MagickMax(source->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(
+    destination->fuzz,(MagickRealType) MagickSQ1_2);
   scale=1.0;
   distance=0.0;
   if (source->alpha_trait == BlendPixelTrait)
@@ -5959,11 +5974,14 @@ MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
   if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
     return(IsPixelInfoEquivalent(p,q));
   if (p->fuzz == 0.0)
-    fuzz=MagickMax(q->fuzz,(double) MagickSQ1_2)*MagickMax(q->fuzz,MagickSQ1_2);
+    fuzz=MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2)*
+      MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2);
   else if (q->fuzz == 0.0)
-    fuzz=MagickMax(p->fuzz,(double) MagickSQ1_2)*MagickMax(p->fuzz,MagickSQ1_2);
+    fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*
+      MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2);
   else
-    fuzz=MagickMax(p->fuzz,(double) MagickSQ1_2)*MagickMax(q->fuzz,MagickSQ1_2);
+    fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*
+      MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2);
   scale=1.0;
   distance=0.0;
   if ((p->alpha_trait == BlendPixelTrait) ||
@@ -6010,9 +6028,9 @@ MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
       (p->colorspace == HWBColorspace))
     {
       /*
-        This calculates a arc distance for hue-- it should be a vector angle
-        of 'S'/'W' length with 'L'/'B' forming appropriate cones.  In other
-        words this is a hack - Anthony.
+        This calculates a arc distance for hue-- it should be a vector
+        angle of 'S'/'W' length with 'L'/'B' forming appropriate cones.
+        In other words this is a hack - Anthony.
       */
       if (fabs((double) pixel) > (QuantumRange/2))
         pixel-=QuantumRange;