(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Thu, 4 Apr 2013 19:00:52 +0000 (19:00 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Thu, 4 Apr 2013 19:00:52 +0000 (19:00 +0000)
MagickCore/colorspace.c
MagickCore/enhance.c
MagickCore/gem-private.h
MagickCore/gem.c

index 6e336f87a0fcae59676b971f4875aa3bb9971a25..75d5a5ec9635631e9e6ec226fd6a6d33c55d5155 100644 (file)
@@ -749,32 +749,20 @@ static MagickBooleanType sRGBTransformImage(Image *image,
         for (x=0; x < (ssize_t) image->columns; x++)
         {
           double
-            a,
-            b,
             blue,
-            C,
+            chroma,
             green,
-            H,
-            L,
-            red,
-            X,
-            Y,
-            Z;
+            hue,
+            luma,
+            red;
 
           red=DecodePixelGamma((MagickRealType) GetPixelRed(image,q));
           green=DecodePixelGamma((MagickRealType) GetPixelGreen(image,q));
           blue=DecodePixelGamma((MagickRealType) GetPixelBlue(image,q));
-          ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
-          ConvertXYZToLab(X,Y,Z,&L,&a,&b);
-          C=hypot(a-0.5,b-0.5);
-          H=180.0*atan2(b-0.5,a-0.5)/MagickPI;
-          if (H < 360.0)
-            H+=360.0;
-          if (H > 360.0)
-            H-=360.0;
-          SetPixelRed(image,ClampToQuantum(QuantumRange*L),q);
-          SetPixelGreen(image,ClampToQuantum(QuantumRange*C),q);
-          SetPixelBlue(image,ClampToQuantum(QuantumRange*H/360.0),q);
+          ConvertRGBToLCH(red,green,blue,&luma,&chroma,&hue);
+          SetPixelRed(image,ClampToQuantum(QuantumRange*luma),q);
+          SetPixelGreen(image,ClampToQuantum(QuantumRange*chroma),q);
+          SetPixelBlue(image,ClampToQuantum(QuantumRange*hue),q);
           q+=GetPixelChannels(image);
         }
         sync=SyncCacheViewAuthenticPixels(image_view,exception);
@@ -2604,25 +2592,17 @@ static MagickBooleanType TransformsRGBImage(Image *image,
         for (x=0; x < (ssize_t) image->columns; x++)
         {
           double
-            a,
-            b,
             blue,
-            C,
+            chroma,
             green,
-            H,
-            L,
-            red,
-            X,
-            Y,
-            Z;
+            hue,
+            luma,
+            red;
 
-          L=QuantumScale*GetPixelRed(image,q);
-          C=QuantumScale*GetPixelGreen(image,q);
-          H=QuantumScale*GetPixelBlue(image,q);
-          a=C*cos(360.0*H*MagickPI/180.0)+0.5;
-          b=C*sin(360.0*H*MagickPI/180.0)+0.5;
-          ConvertLabToXYZ(L,a,b,&X,&Y,&Z);
-          ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
+          luma=(double) (QuantumScale*GetPixelRed(image,q));
+          chroma=(double) (QuantumScale*GetPixelGreen(image,q));
+          hue=(double) (QuantumScale*GetPixelBlue(image,q));
+          ConvertLCHToRGB(luma,chroma,hue,&red,&green,&blue);
           SetPixelRed(image,ClampToQuantum(EncodePixelGamma(red)),q);
           SetPixelGreen(image,ClampToQuantum(EncodePixelGamma(green)),q);
           SetPixelBlue(image,ClampToQuantum(EncodePixelGamma(blue)),q);
index 78029e076f84dcd6936fc309d2068d53b36c3565..2f28e4cc6af18e7f6b7a8c2db34bc49bc5116d94 100644 (file)
@@ -2954,6 +2954,29 @@ static inline void ModulateHWB(const double percent_hue,
   ConvertHWBToRGB(hue,whiteness,blackness,red,green,blue);
 }
 
+static inline void ModulateLCH(const double percent_luma,
+  const double percent_chroma,const double percent_hue,double *red,
+  double *green,double *blue)
+{
+  double
+    hue,
+    luma,
+    chroma;
+
+  /*
+    Increase or decrease color luma, chroma, or hue.
+  */
+  ConvertRGBToLCH(*red,*green,*blue,&luma,&chroma,&hue);
+  luma*=0.01*percent_luma;
+  chroma*=0.01*percent_chroma;
+  hue+=0.5*(0.01*percent_hue-1.0);
+  while (hue < 0.0)
+    hue+=1.0;
+  while (hue > 1.0)
+    hue-=1.0;
+  ConvertHCLToRGB(luma,chroma,hue,red,green,blue);
+}
+
 MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
   ExceptionInfo *exception)
 {
@@ -3062,6 +3085,12 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
             &red,&green,&blue);
           break;
         }
+        case LCHColorspace:
+        {
+          ModulateLCH(percent_brightness,percent_saturation,percent_hue,
+            &red,&green,&blue);
+          break;
+        }
       }
       if (IssRGBColorspace(image->colorspace) != MagickFalse)
         {
@@ -3142,6 +3171,12 @@ MagickExport MagickBooleanType ModulateImage(Image *image,const char *modulate,
             &red,&green,&blue);
           break;
         }
+        case LCHColorspace:
+        {
+          ModulateLCH(percent_brightness,percent_saturation,percent_hue,
+            &red,&green,&blue);
+          break;
+        }
       }
       if (IssRGBColorspace(image->colorspace) != MagickFalse)
         {
index 12d95e088899cebb75669bc4ca856a41ab7c79bb..d51e7c9ba388f146de30a8788d23fef32bdfccd3 100644 (file)
@@ -44,11 +44,15 @@ extern MagickPrivate void
     double *),
   ConvertHWBToRGB(const double,const double,const double,double *,double *,
     double *),
+  ConvertLCHToRGB(const double,const double,const double,double *,double *,
+    double *),
   ConvertRGBToHCL(const double,const double,const double,double *,double *,
     double *),
   ConvertRGBToHSB(const double,const double,const double,double *,double *,
     double *),
   ConvertRGBToHWB(const double,const double,const double,double *,double *,
+    double *),
+  ConvertRGBToLCH(const double,const double,const double,double *,double *,
     double *);
 
 static inline void ConvertLabToXYZ(const double L,const double a,const double b,
index 913a92c9d127b1d231251b7a1b76dd2cf54d7235..c74ca1aedafe0cd8fff125c7288ecf9bb9d8d1a9 100644 (file)
@@ -89,14 +89,13 @@ MagickPrivate void ConvertHCLToRGB(const double hue,const double chroma,
   const double luma,double *red,double *green,double *blue)
 {
   double
-    a,
     b,
-    C,
-    H,
-    L,
-    X,
-    Y,
-    Z;
+    c,
+    g,
+    h,
+    m,
+    r,
+    x;
 
   /*
     Convert HCL to RGB colorspace.
@@ -104,13 +103,51 @@ MagickPrivate void ConvertHCLToRGB(const double hue,const double chroma,
   assert(red != (double *) NULL);
   assert(green != (double *) NULL);
   assert(blue != (double *) NULL);
-  L=luma;
-  C=chroma;
-  H=hue;
-  a=C*cos(360.0*H*MagickPI/180.0)+0.5;
-  b=C*sin(360.0*H*MagickPI/180.0)+0.5;
-  ConvertLabToXYZ(L,a,b,&X,&Y,&Z);
-  ConvertXYZToRGB(X,Y,Z,red,green,blue);
+  h=6.0*hue;
+  c=chroma;
+  x=c*(1.0-fabs(fmod(h,2.0)-1.0));
+  r=0.0;
+  g=0.0;
+  b=0.0;
+  if ((0.0 <= h) && (h < 1.0))
+    {
+      r=c;
+      g=x;
+    }
+  else
+    if ((1.0 <= h) && (h < 2.0))
+      {
+        r=x;
+        g=c;
+      }
+    else
+      if ((2.0 <= h) && (h < 3.0))
+        {
+          g=c;
+          b=x;
+        }
+      else
+        if ((3.0 <= h) && (h < 4.0))
+          {
+            g=x;
+            b=c;
+          }
+        else
+          if ((4.0 <= h) && (h < 5.0))
+            {
+              r=x;
+              b=c;
+            }
+          else
+            if ((5.0 <= h) && (h < 6.0))
+              {
+                r=c;
+                b=x;
+              }
+  m=luma-(0.298839f*r+0.586811f*g+0.114350f*b);
+  *red=QuantumRange*(r+m);
+  *green=QuantumRange*(g+m);
+  *blue=QuantumRange*(b+m);
 }
 \f
 /*
@@ -376,6 +413,61 @@ MagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   C o n v e r t L C H T o R G B                                             %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  ConvertLCHToRGB() transforms a (luma, chroma, hue) to a (red, green,
+%  blue) triple.
+%
+%  The format of the ConvertLCHToRGBImage method is:
+%
+%      void ConvertLCHToRGB(const double luma,const double chroma,
+%        const double hue,double *red,double *green,double *blue)
+%
+%  A description of each parameter follows:
+%
+%    o luma, chroma, hue: A double value representing a
+%      component of the LCH color space.
+%
+%    o red, green, blue: A pointer to a pixel component of type Quantum.
+%
+*/
+MagickPrivate void ConvertLCHToRGB(const double luma,const double chroma,
+  const double hue,double *red,double *green,double *blue)
+{
+  double
+    a,
+    b,
+    C,
+    H,
+    L,
+    X,
+    Y,
+    Z;
+
+  /*
+    Convert LCH to RGB colorspace.
+  */
+  assert(red != (double *) NULL);
+  assert(green != (double *) NULL);
+  assert(blue != (double *) NULL);
+  L=luma;
+  C=chroma;
+  H=hue;
+  a=C*cos(360.0*H*MagickPI/180.0)+0.5;
+  b=C*sin(360.0*H*MagickPI/180.0)+0.5;
+  ConvertLabToXYZ(L,a,b,&X,&Y,&Z);
+  ConvertXYZToRGB(X,Y,Z,red,green,blue);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   C o n v e r t R G B T o H C L                                             %
 %                                                                             %
 %                                                                             %
@@ -399,18 +491,31 @@ MagickPrivate void ConvertHWBToRGB(const double hue,const double whiteness,
 %      component of the HCL color space.
 %
 */
+
+static inline double MagickMax(const double x,const double y)
+{
+  if (x > y)
+    return(x);
+  return(y);
+}
+
+static inline double MagickMin(const double x,const double y)
+{
+  if (x < y)
+    return(x);
+  return(y);
+}
+
 MagickPrivate void ConvertRGBToHCL(const double red,const double green,
   const double blue,double *hue,double *chroma,double *luma)
 {
   double
-    a,
     b,
-    C,
-    H,
-    L,
-    X,
-    Y,
-    Z;
+    c,
+    g,
+    h,
+    max,
+    r;
 
   /*
     Convert RGB to HCL colorspace.
@@ -418,17 +523,26 @@ MagickPrivate void ConvertRGBToHCL(const double red,const double green,
   assert(hue != (double *) NULL);
   assert(chroma != (double *) NULL);
   assert(luma != (double *) NULL);
-  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
-  ConvertXYZToLab(X,Y,Z,&L,&a,&b);
-  C=hypot(a-0.5,b-0.5);
-  H=180.0*atan2(b-0.5,a-0.5)/MagickPI;
-  if (H < 360.0)
-    H+=360.0;
-  if (H > 360.0)
-    H-=360.0;
-  *hue=H/360.0;
-  *chroma=C;
-  *luma=L;
+  r=red;
+  g=green;
+  b=blue;
+  max=MagickMax(r,MagickMax(g,b));
+  c=max-(double) MagickMin(r,MagickMin(g,b));
+  h=0.0;
+  if (c == 0.0)
+    h=0.0;
+  else
+    if (red == max)
+      h=fmod((g-b)/c+6.0,6.0);
+    else
+      if (green == max)
+        h=((b-r)/c)+2.0;
+      else
+        if (blue == max)
+          h=((r-g)/c)+4.0;
+  *hue=(h/6.0);
+  *chroma=QuantumScale*c;
+  *luma=QuantumScale*(0.298839f*r+0.586811f*g+0.114350f*b);
 }
 \f
 /*
@@ -535,21 +649,6 @@ MagickPrivate void ConvertRGBToHSB(const double red,const double green,
 %      component of the HSL color space.
 %
 */
-
-static inline double MagickMax(const double x,const double y)
-{
-  if (x > y)
-    return(x);
-  return(y);
-}
-
-static inline double MagickMin(const double x,const double y)
-{
-  if (x < y)
-    return(x);
-  return(y);
-}
-
 MagickExport void ConvertRGBToHSL(const double red,const double green,
   const double blue,double *hue,double *saturation,double *lightness)
 {
@@ -668,6 +767,66 @@ MagickPrivate void ConvertRGBToHWB(const double red,const double green,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   C o n v e r t R G B T o L C H                                             %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  ConvertRGBToLCH() transforms a (red, green, blue) to a (luma, chroma,
+%  hue) triple.
+%
+%  The format of the ConvertRGBToLCH method is:
+%
+%      void ConvertRGBToLCH(const double red,const double green,
+%        const double blue,double *luma,double *chroma,double *hue)
+%
+%  A description of each parameter follows:
+%
+%    o red, green, blue: A Quantum value representing the red, green, and
+%      blue component of a pixel.
+%
+%    o luma, chroma, hue: A pointer to a double value representing a
+%      component of the LCH color space.
+%
+*/
+MagickPrivate void ConvertRGBToLCH(const double red,const double green,
+  const double blue,double *luma,double *chroma,double *hue)
+{
+  double
+    a,
+    b,
+    C,
+    H,
+    L,
+    X,
+    Y,
+    Z;
+
+  /*
+    Convert RGB to LCH colorspace.
+  */
+  assert(luma != (double *) NULL);
+  assert(chroma != (double *) NULL);
+  assert(hue != (double *) NULL);
+  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
+  ConvertXYZToLab(X,Y,Z,&L,&a,&b);
+  C=hypot(a-0.5,b-0.5);
+  H=180.0*atan2(b-0.5,a-0.5)/MagickPI;
+  if (H < 360.0)
+    H+=360.0;
+  if (H > 360.0)
+    H-=360.0;
+  *luma=L;
+  *chroma=C;
+  *hue=H/360.0;
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   E x p a n d A f f i n e                                                   %
 %                                                                             %
 %                                                                             %