]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/enhance.c
(no commit message)
[imagemagick] / MagickCore / enhance.c
index 8aa3b4cf78e894c813018b15a443dc69c2b58f86..19108a48ce2445d8b3b16367b8630c2c930a4cf6 100644 (file)
 %                    MagickCore Image Enhancement Methods                     %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  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  %
@@ -45,6 +45,7 @@
 #include "MagickCore/attribute.h"
 #include "MagickCore/cache.h"
 #include "MagickCore/cache-view.h"
+#include "MagickCore/channel.h"
 #include "MagickCore/color.h"
 #include "MagickCore/color-private.h"
 #include "MagickCore/colorspace.h"
@@ -151,7 +152,7 @@ MagickExport MagickBooleanType AutoGammaImage(Image *image,
     if( IfMagickFalse(status) )
       break;
   }
-  return(status);
+  return(status != 0 ? MagickTrue : MagickFalse);
 }
 \f
 /*
@@ -887,10 +888,13 @@ MagickExport MagickBooleanType ContrastImage(Image *image,
           green,
           red;
 
+        red=0.0;
+        green=0.0;
+        blue=0.0;
         Contrast(sign,&red,&green,&blue);
         image->colormap[i].red=(MagickRealType) red;
-        image->colormap[i].red=(MagickRealType) red;
-        image->colormap[i].red=(MagickRealType) red;
+        image->colormap[i].green=(MagickRealType) green;
+        image->colormap[i].blue=(MagickRealType) blue;
       }
     }
   /*
@@ -1376,6 +1380,7 @@ MagickExport Image *EnhanceImage(const Image *image,ExceptionInfo *exception)
 
       if (GetPixelReadMask(image,p) == 0)
         {
+          SetPixelBackgoundColor(enhance_image,q);
           p+=GetPixelChannels(image);
           q+=GetPixelChannels(enhance_image);
           continue;
@@ -1488,11 +1493,11 @@ MagickExport MagickBooleanType EqualizeImage(Image *image,
     progress;
 
   double
-    black[CompositePixelChannel],
+    black[CompositePixelChannel+1],
     *equalize_map,
     *histogram,
     *map,
-    white[CompositePixelChannel];
+    white[CompositePixelChannel+1];
 
   register ssize_t
     i;
@@ -1512,10 +1517,10 @@ MagickExport MagickBooleanType EqualizeImage(Image *image,
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   equalize_map=(double *) AcquireQuantumMemory(MaxMap+1UL,
     GetPixelChannels(image)*sizeof(*equalize_map));
-  histogram=(double *) AcquireQuantumMemory(MaxMap+1UL,
-    GetPixelChannels(image)*sizeof(*histogram));
-  map=(double *) AcquireQuantumMemory(MaxMap+1UL,
-    GetPixelChannels(image)*sizeof(*map));
+  histogram=(double *) AcquireQuantumMemory(MaxMap+1UL,GetPixelChannels(image)*
+    sizeof(*histogram));
+  map=(double *) AcquireQuantumMemory(MaxMap+1UL,GetPixelChannels(image)*
+    sizeof(*map));
   if ((equalize_map == (double *) NULL) || (histogram == (double *) NULL) ||
       (map == (double *) NULL))
     {
@@ -1583,6 +1588,8 @@ MagickExport MagickBooleanType EqualizeImage(Image *image,
   }
   (void) ResetMagickMemory(equalize_map,0,(MaxMap+1)*GetPixelChannels(image)*
     sizeof(*equalize_map));
+  (void) ResetMagickMemory(black,0,sizeof(*black));
+  (void) ResetMagickMemory(white,0,sizeof(*white));
   number_channels=GetPixelChannels(image);
   for (i=0; i < (ssize_t) number_channels; i++)
   {
@@ -1748,7 +1755,7 @@ MagickExport MagickBooleanType EqualizeImage(Image *image,
 
 static inline double gamma_pow(const double value,const double gamma)
 {
-  return(value < 0.0 ? value : pow(value,1.0/gamma));
+  return(value < 0.0 ? value : pow(value,gamma));
 }
 
 MagickExport MagickBooleanType GammaImage(Image *image,const double gamma,
@@ -1813,13 +1820,17 @@ MagickExport MagickBooleanType GammaImage(Image *image,const double gamma,
           ClampToQuantum(image->colormap[i].alpha))];
 #else
       if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
-        image->colormap[i].red=gamma_pow(image->colormap[i].red,1.0/gamma);
+        image->colormap[i].red=QuantumRange*gamma_pow(QuantumScale*
+          image->colormap[i].red,1.0/gamma);
       if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
-        image->colormap[i].green=gamma_pow(image->colormap[i].green,1.0/gamma);
+        image->colormap[i].green=QuantumRange*gamma_pow(QuantumScale*
+          image->colormap[i].green,1.0/gamma);
       if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
-        image->colormap[i].blue=gamma_pow(image->colormap[i].blue,1.0/gamma);
+        image->colormap[i].blue=QuantumRange*gamma_pow(QuantumScale*
+          image->colormap[i].blue,1.0/gamma);
       if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
-        image->colormap[i].alpha=gamma_pow(image->colormap[i].alpha,1.0/gamma);
+        image->colormap[i].alpha=QuantumRange*gamma_pow(QuantumScale*
+          image->colormap[i].alpha,1.0/gamma);
 #endif
     }
   /*
@@ -1867,7 +1878,7 @@ MagickExport MagickBooleanType GammaImage(Image *image,const double gamma,
 #if !defined(MAGICKCORE_HDRI_SUPPORT)
         q[i]=gamma_map[ScaleQuantumToMap(q[i])];
 #else
-        q[i]=gamma_pow((double) q[i],1.0/gamma);
+        q[i]=QuantumRange*gamma_pow(QuantumScale*q[i],1.0/gamma);
 #endif
       }
       q+=GetPixelChannels(image);
@@ -1967,24 +1978,6 @@ MagickExport MagickBooleanType GrayscaleImage(Image *image,
       if( IfMagickFalse(SetImageStorageClass(image,DirectClass,exception)) )
         return(MagickFalse);
     }
-  switch (image->intensity)
-  {
-    case Rec601LuminancePixelIntensityMethod:
-    case Rec709LuminancePixelIntensityMethod:
-    {
-      (void) SetImageColorspace(image,RGBColorspace,exception);
-      break;
-    }
-    case Rec601LumaPixelIntensityMethod:
-    case Rec709LumaPixelIntensityMethod:
-    case UndefinedPixelIntensityMethod:
-    {
-      (void) SetImageColorspace(image,sRGBColorspace,exception);
-      break;
-    }
-    default:
-      break;
-  }
   /*
     Grayscale image.
   */
@@ -2042,7 +2035,8 @@ MagickExport MagickBooleanType GrayscaleImage(Image *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:
@@ -2053,23 +2047,47 @@ MagickExport MagickBooleanType GrayscaleImage(Image *image,
         }
         case Rec601LumaPixelIntensityMethod:
         {
-          intensity=0.298839f*red+0.586811f*green+0.114350f*blue;
+          if (image->colorspace == RGBColorspace)
+            {
+              red=EncodePixelGamma(red);
+              green=EncodePixelGamma(green);
+              blue=EncodePixelGamma(blue);
+            }
+          intensity=0.298839*red+0.586811*green+0.114350*blue;
           break;
         }
         case Rec601LuminancePixelIntensityMethod:
         {
-          intensity=0.298839f*red+0.586811f*green+0.114350f*blue;
+          if (image->colorspace == sRGBColorspace)
+            {
+              red=DecodePixelGamma(red);
+              green=DecodePixelGamma(green);
+              blue=DecodePixelGamma(blue);
+            }
+          intensity=0.298839*red+0.586811*green+0.114350*blue;
           break;
         }
         case Rec709LumaPixelIntensityMethod:
-        case UndefinedPixelIntensityMethod:
+        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:
         {
-          intensity=0.21260f*red+0.71520f*green+0.07220f*blue;
+          if (image->colorspace == sRGBColorspace)
+            {
+              red=DecodePixelGamma(red);
+              green=DecodePixelGamma(green);
+              blue=DecodePixelGamma(blue);
+            }
+          intensity=0.212656*red+0.715158*green+0.072186*blue;
           break;
         }
         case RMSPixelIntensityMethod:
@@ -2078,13 +2096,11 @@ MagickExport MagickBooleanType GrayscaleImage(Image *image,
             blue*blue)/sqrt(3.0));
           break;
         }
-        default:
-          break;
       }
       SetPixelGray(image,ClampToQuantum(intensity),q);
       q+=GetPixelChannels(image);
     }
-    if( IfMagickFalse(SyncCacheViewAuthenticPixels(image_view,exception)) )
+    if (IfMagickFalse(SyncCacheViewAuthenticPixels(image_view,exception)))
       status=MagickFalse;
     if (image->progress_monitor != (MagickProgressMonitor) NULL)
       {
@@ -2346,7 +2362,8 @@ static inline double LevelPixel(const double black_point,
     scale;
 
   scale=(white_point != black_point) ? 1.0/(white_point-black_point) : 1.0;
-  level_pixel=QuantumRange*gamma_pow(scale*((double) pixel-black_point),gamma);
+  level_pixel=QuantumRange*gamma_pow(scale*((double) pixel-black_point),
+    1.0/gamma);
   return(level_pixel);
 }
 
@@ -2459,6 +2476,7 @@ MagickExport MagickBooleanType LevelImage(Image *image,const double black_point,
       }
   }
   image_view=DestroyCacheView(image_view);
+  (void) ClampImage(image,exception);
   return(status);
 }
 \f
@@ -2684,21 +2702,21 @@ MagickExport MagickBooleanType LevelImageColors(Image *image,
       if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
         {
           channel_mask=SetImageChannelMask(image,RedChannel);
-          status|=LevelImage(image,black_color->red,white_color->red,1.0,
+          status&=LevelImage(image,black_color->red,white_color->red,1.0,
             exception);
           (void) SetImageChannelMask(image,channel_mask);
         }
       if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
         {
           channel_mask=SetImageChannelMask(image,GreenChannel);
-          status|=LevelImage(image,black_color->green,white_color->green,1.0,
+          status&=LevelImage(image,black_color->green,white_color->green,1.0,
             exception);
           (void) SetImageChannelMask(image,channel_mask);
         }
       if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
         {
           channel_mask=SetImageChannelMask(image,BlueChannel);
-          status|=LevelImage(image,black_color->blue,white_color->blue,1.0,
+          status&=LevelImage(image,black_color->blue,white_color->blue,1.0,
             exception);
           (void) SetImageChannelMask(image,channel_mask);
         }
@@ -2706,7 +2724,7 @@ MagickExport MagickBooleanType LevelImageColors(Image *image,
           (image->colorspace == CMYKColorspace))
         {
           channel_mask=SetImageChannelMask(image,BlackChannel);
-          status|=LevelImage(image,black_color->black,white_color->black,1.0,
+          status&=LevelImage(image,black_color->black,white_color->black,1.0,
             exception);
           (void) SetImageChannelMask(image,channel_mask);
         }
@@ -2714,7 +2732,7 @@ MagickExport MagickBooleanType LevelImageColors(Image *image,
           (image->alpha_trait == BlendPixelTrait))
         {
           channel_mask=SetImageChannelMask(image,AlphaChannel);
-          status|=LevelImage(image,black_color->alpha,white_color->alpha,1.0,
+          status&=LevelImage(image,black_color->alpha,white_color->alpha,1.0,
             exception);
           (void) SetImageChannelMask(image,channel_mask);
         }
@@ -2724,21 +2742,21 @@ MagickExport MagickBooleanType LevelImageColors(Image *image,
       if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
         {
           channel_mask=SetImageChannelMask(image,RedChannel);
-          status|=LevelizeImage(image,black_color->red,white_color->red,1.0,
+          status&=LevelizeImage(image,black_color->red,white_color->red,1.0,
             exception);
           (void) SetImageChannelMask(image,channel_mask);
         }
       if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
         {
           channel_mask=SetImageChannelMask(image,GreenChannel);
-          status|=LevelizeImage(image,black_color->green,white_color->green,1.0,
+          status&=LevelizeImage(image,black_color->green,white_color->green,1.0,
             exception);
           (void) SetImageChannelMask(image,channel_mask);
         }
       if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
         {
           channel_mask=SetImageChannelMask(image,BlueChannel);
-          status|=LevelizeImage(image,black_color->blue,white_color->blue,1.0,
+          status&=LevelizeImage(image,black_color->blue,white_color->blue,1.0,
             exception);
           (void) SetImageChannelMask(image,channel_mask);
         }
@@ -2746,7 +2764,7 @@ MagickExport MagickBooleanType LevelImageColors(Image *image,
           (image->colorspace == CMYKColorspace))
         {
           channel_mask=SetImageChannelMask(image,BlackChannel);
-          status|=LevelizeImage(image,black_color->black,white_color->black,1.0,
+          status&=LevelizeImage(image,black_color->black,white_color->black,1.0,
             exception);
           (void) SetImageChannelMask(image,channel_mask);
         }
@@ -2754,12 +2772,12 @@ MagickExport MagickBooleanType LevelImageColors(Image *image,
           (image->alpha_trait == BlendPixelTrait))
         {
           channel_mask=SetImageChannelMask(image,AlphaChannel);
-          status|=LevelizeImage(image,black_color->alpha,white_color->alpha,1.0,
+          status&=LevelizeImage(image,black_color->alpha,white_color->alpha,1.0,
             exception);
           (void) SetImageChannelMask(image,channel_mask);
         }
     }
-  return(status);
+  return(status != 0 ? MagickTrue : MagickFalse);
 }
 \f
 /*
@@ -2926,6 +2944,29 @@ static inline void ModulateHCL(const double percent_hue,
   ConvertHCLToRGB(hue,chroma,luma,red,green,blue);
 }
 
+static inline void ModulateHCLp(const double percent_hue,
+  const double percent_chroma,const double percent_luma,double *red,
+  double *green,double *blue)
+{
+  double
+    hue,
+    luma,
+    chroma;
+
+  /*
+    Increase or decrease color luma, chroma, or hue.
+  */
+  ConvertRGBToHCLp(*red,*green,*blue,&hue,&chroma,&luma);
+  hue+=0.5*(0.01*percent_hue-1.0);
+  while (hue < 0.0)
+    hue+=1.0;
+  while (hue > 1.0)
+    hue-=1.0;
+  chroma*=0.01*percent_chroma;
+  luma*=0.01*percent_luma;
+  ConvertHCLpToRGB(hue,chroma,luma,red,green,blue);
+}
+
 static inline void ModulateHSB(const double percent_hue,
   const double percent_saturation,const double percent_brightness,double *red,
   double *green,double *blue)
@@ -3162,12 +3203,6 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
       red=(double) image->colormap[i].red;
       green=(double) image->colormap[i].green;
       blue=(double) image->colormap[i].blue;
-      if( IfMagickTrue(IssRGBColorspace(image->colorspace)) )
-        {
-          red=DecodePixelGamma((MagickRealType) red);
-          green=DecodePixelGamma((MagickRealType) green);
-          blue=DecodePixelGamma((MagickRealType) blue);
-        }
       switch (colorspace)
       {
         case HCLColorspace:
@@ -3176,6 +3211,12 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
             &red,&green,&blue);
           break;
         }
+        case HCLpColorspace:
+        {
+          ModulateHCLp(percent_hue,percent_saturation,percent_brightness,
+            &red,&green,&blue);
+          break;
+        }
         case HSBColorspace:
         {
           ModulateHSB(percent_hue,percent_saturation,percent_brightness,
@@ -3207,13 +3248,13 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
             &red,&green,&blue);
           break;
         }
+        case LCHColorspace:
         case LCHabColorspace:
         {
           ModulateLCHab(percent_brightness,percent_saturation,percent_hue,
             &red,&green,&blue);
           break;
         }
-        case LCHColorspace:
         case LCHuvColorspace:
         {
           ModulateLCHuv(percent_brightness,percent_saturation,percent_hue,
@@ -3221,12 +3262,6 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
           break;
         }
       }
-      if( IfMagickTrue(IssRGBColorspace(image->colorspace)) )
-        {
-          red=EncodePixelGamma(red);
-          green=EncodePixelGamma(green);
-          blue=EncodePixelGamma(blue);
-        }
       image->colormap[i].red=red;
       image->colormap[i].green=green;
       image->colormap[i].blue=blue;
@@ -3267,12 +3302,6 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
       red=(double) GetPixelRed(image,q);
       green=(double) GetPixelGreen(image,q);
       blue=(double) GetPixelBlue(image,q);
-      if( IfMagickTrue(IssRGBColorspace(image->colorspace)) )
-        {
-          red=DecodePixelGamma((MagickRealType) red);
-          green=DecodePixelGamma((MagickRealType) green);
-          blue=DecodePixelGamma((MagickRealType) blue);
-        }
       switch (colorspace)
       {
         case HCLColorspace:
@@ -3281,6 +3310,12 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
             &red,&green,&blue);
           break;
         }
+        case HCLpColorspace:
+        {
+          ModulateHCLp(percent_hue,percent_saturation,percent_brightness,
+            &red,&green,&blue);
+          break;
+        }
         case HSBColorspace:
         {
           ModulateHSB(percent_hue,percent_saturation,percent_brightness,
@@ -3294,6 +3329,12 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
             &red,&green,&blue);
           break;
         }
+        case HSVColorspace:
+        {
+          ModulateHSV(percent_hue,percent_saturation,percent_brightness,
+            &red,&green,&blue);
+          break;
+        }
         case HWBColorspace:
         {
           ModulateHWB(percent_hue,percent_saturation,percent_brightness,
@@ -3314,12 +3355,6 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
           break;
         }
       }
-      if( IfMagickTrue(IssRGBColorspace(image->colorspace)) )
-        {
-          red=EncodePixelGamma(red);
-          green=EncodePixelGamma(green);
-          blue=EncodePixelGamma(blue);
-        }
       SetPixelRed(image,ClampToQuantum(red),q);
       SetPixelGreen(image,ClampToQuantum(green),q);
       SetPixelBlue(image,ClampToQuantum(blue),q);