]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Mon, 13 Aug 2012 12:49:50 +0000 (12:49 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Mon, 13 Aug 2012 12:49:50 +0000 (12:49 +0000)
MagickCore/composite.c

index cb18635e8d8f68f687339f1981202eb09085c4cf..6942322a078d1e26cf00e9ff99f3531c94974c03 100644 (file)
        performed as 'pure' mathematical operations, rather than as image
        operations.
 */
-static void CompositeHSB(const double red,const double green,
-  const double blue,double *hue,double *saturation,double *brightness)
+
+static inline double MagickMin(const double x,const double y)
 {
-  double
-    delta,
-    max,
-    min;
+  if (x < y)
+    return(x);
+  return(y);
+}
 
-  /*
-    Convert RGB to HSB colorspace.
-  */
-  assert(hue != (double *) NULL);
-  assert(saturation != (double *) NULL);
-  assert(brightness != (double *) NULL);
-  max=(red > green ? red : green);
-  if (blue > max)
-    max=blue;
-  min=(red < green ? red : green);
-  if (blue < min)
-    min=blue;
-  *hue=0.0;
-  *saturation=0.0;
-  *brightness=(double) (QuantumScale*max);
-  if (fabs((double) max) < MagickEpsilon)
-    return;
-  *saturation=(double) (1.0-min/max);
-  delta=(double) max-min;
-  if (fabs(delta) < MagickEpsilon)
-    return;
-  if (fabs((double) red-max) < MagickEpsilon)
-    *hue=(double) ((green-blue)/delta);
-  else
-    if (fabs((double) green-max) < MagickEpsilon)
-      *hue=(double) (2.0+(blue-red)/delta);
-    else
-      if (fabs((double) blue-max) < MagickEpsilon)
-        *hue=(double) (4.0+(red-green)/delta);
-  *hue/=6.0;
-  if (*hue < 0.0)
-    *hue+=1.0;
+static inline double MagickMax(const double x,const double y)
+{
+  if (x > y)
+    return(x);
+  return(y);
 }
 
-static void HSBComposite(const double hue,const double saturation,
-  const double brightness,double *red,double *green,double *blue)
+static inline double ConvertHueToRGB(double m1,
+  double m2,double hue)
+{
+  if (hue < 0.0)
+    hue+=1.0;
+  if (hue > 1.0)
+    hue-=1.0;
+  if ((6.0*hue) < 1.0)
+    return(m1+6.0*(m2-m1)*hue);
+  if ((2.0*hue) < 1.0)
+    return(m2);
+  if ((3.0*hue) < 2.0)
+    return(m1+6.0*(m2-m1)*(2.0/3.0-hue));
+  return(m1);
+}
+
+static void HSLComposite(const double hue,const double saturation,
+  const double lightness,double *red,double *green,double *blue)
 {
   double
-    f,
-    h,
-    p,
-    q,
-    t;
+    b,
+    g,
+    r,
+    m1,
+    m2;
 
   /*
-    Convert HSB to RGB colorspace.
+    Convert HSL to RGB colorspace.
   */
   assert(red != (double *) NULL);
   assert(green != (double *) NULL);
   assert(blue != (double *) NULL);
-  if (saturation == 0.0)
+  if (saturation == 0)
     {
-      *red=(double) QuantumRange*brightness;
+      *red=(double) QuantumRange*lightness;
       *green=(*red);
       *blue=(*red);
       return;
     }
-  h=6.0*(hue-floor(hue));
-  f=h-floor((double) h);
-  p=brightness*(1.0-saturation);
-  q=brightness*(1.0-saturation*f);
-  t=brightness*(1.0-saturation*(1.0-f));
-  switch ((int) h)
-  {
-    case 0:
-    default:
-    {
-      *red=(double) QuantumRange*brightness;
-      *green=(double) QuantumRange*t;
-      *blue=(double) QuantumRange*p;
-      break;
-    }
-    case 1:
-    {
-      *red=(double) QuantumRange*q;
-      *green=(double) QuantumRange*brightness;
-      *blue=(double) QuantumRange*p;
-      break;
-    }
-    case 2:
-    {
-      *red=(double) QuantumRange*p;
-      *green=(double) QuantumRange*brightness;
-      *blue=(double) QuantumRange*t;
-      break;
-    }
-    case 3:
-    {
-      *red=(double) QuantumRange*p;
-      *green=(double) QuantumRange*q;
-      *blue=(double) QuantumRange*brightness;
-      break;
-    }
-    case 4:
-    {
-      *red=(double) QuantumRange*t;
-      *green=(double) QuantumRange*p;
-      *blue=(double) QuantumRange*brightness;
-      break;
-    }
-    case 5:
-    {
-      *red=(double) QuantumRange*brightness;
-      *green=(double) QuantumRange*p;
-      *blue=(double) QuantumRange*q;
-      break;
-    }
-  }
+  if (lightness < 0.5)
+    m2=lightness*(saturation+1.0);
+  else
+    m2=(lightness+saturation)-(lightness*saturation);
+  m1=2.0*lightness-m2;
+  r=ConvertHueToRGB(m1,m2,hue+1.0/3.0);
+  g=ConvertHueToRGB(m1,m2,hue);
+  b=ConvertHueToRGB(m1,m2,hue-1.0/3.0);
+  *red=(double) QuantumRange*r;
+  *green=(double) QuantumRange*g;
+  *blue=(double) QuantumRange*b;
 }
 
-static inline double MagickMin(const double x,const double y)
+static void CompositeHSL(const double red,const double green,const double blue,
+  double *hue,double *saturation,double *lightness)
 {
-  if (x < y)
-    return(x);
-  return(y);
-}
+  double
+    b,
+    delta,
+    g,
+    max,
+    min,
+    r;
 
-static inline double MagickMax(const double x,const double y)
-{
-  if (x > y)
-    return(x);
-  return(y);
+  /*
+    Convert RGB to HSL colorspace.
+  */
+  assert(hue != (double *) NULL);
+  assert(saturation != (double *) NULL);
+  assert(lightness != (double *) NULL);
+  r=QuantumScale*red;
+  g=QuantumScale*green;
+  b=QuantumScale*blue;
+  max=MagickMax(r,MagickMax(g,b));
+  min=MagickMin(r,MagickMin(g,b));
+  *lightness=(double) ((min+max)/2.0);
+  delta=max-min;
+  if (delta == 0.0)
+    {
+      *hue=0.0;
+      *saturation=0.0;
+      return;
+    }
+  if (*lightness < 0.5)
+    *saturation=(double) (delta/(min+max));
+  else
+    *saturation=(double) (delta/(2.0-max-min));
+  if (r == max)
+    *hue=((((max-b)/6.0)+(delta/2.0))-(((max-g)/6.0)+(delta/2.0)))/delta;
+  else
+    if (g == max)
+      *hue=(1.0/3.0)+((((max-r)/6.0)+(delta/2.0))-(((max-b)/6.0)+(delta/2.0)))/
+        delta;
+    else
+      if (b == max)
+        *hue=(2.0/3.0)+((((max-g)/6.0)+(delta/2.0))-(((max-r)/6.0)+
+          (delta/2.0)))/delta;
+  if (*hue < 0.0)
+    *hue+=1.0;
+  if (*hue > 1.0)
+    *hue-=1.0;
 }
 
 static MagickBooleanType CompositeOverImage(Image *image,
@@ -1760,11 +1745,11 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
                 pixel=Sc;
                 break;
               }
-            CompositeHSB(destination_pixel.red,destination_pixel.green,
+            CompositeHSL(destination_pixel.red,destination_pixel.green,
               destination_pixel.blue,&sans,&sans,&brightness);
-            CompositeHSB(source_pixel.red,source_pixel.green,source_pixel.blue,
+            CompositeHSL(source_pixel.red,source_pixel.green,source_pixel.blue,
               &hue,&saturation,&sans);
-            HSBComposite(hue,saturation,brightness,&red,&green,&blue);
+            HSLComposite(hue,saturation,brightness,&red,&green,&blue);
             switch (channel)
             {
               case RedPixelChannel: pixel=red; break;
@@ -1925,11 +1910,11 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
                 pixel=Sc;
                 break;
               }
-            CompositeHSB(destination_pixel.red,destination_pixel.green,
+            CompositeHSL(destination_pixel.red,destination_pixel.green,
               destination_pixel.blue,&hue,&saturation,&brightness);
-            CompositeHSB(source_pixel.red,source_pixel.green,source_pixel.blue,
+            CompositeHSL(source_pixel.red,source_pixel.green,source_pixel.blue,
               &hue,&sans,&sans);
-            HSBComposite(hue,saturation,brightness,&red,&green,&blue);
+            HSLComposite(hue,saturation,brightness,&red,&green,&blue);
             switch (channel)
             {
               case RedPixelChannel: pixel=red; break;
@@ -2005,11 +1990,11 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
                 pixel=Sc;
                 break;
               }
-            CompositeHSB(destination_pixel.red,destination_pixel.green,
+            CompositeHSL(destination_pixel.red,destination_pixel.green,
               destination_pixel.blue,&hue,&saturation,&brightness);
-            CompositeHSB(source_pixel.red,source_pixel.green,source_pixel.blue,
+            CompositeHSL(source_pixel.red,source_pixel.green,source_pixel.blue,
               &sans,&sans,&brightness);
-            HSBComposite(hue,saturation,brightness,&red,&green,&blue);
+            HSLComposite(hue,saturation,brightness,&red,&green,&blue);
             switch (channel)
             {
               case RedPixelChannel: pixel=red; break;
@@ -2076,11 +2061,11 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
                 pixel=Dc;
                 break;
               }
-            CompositeHSB(destination_pixel.red,destination_pixel.green,
+            CompositeHSL(destination_pixel.red,destination_pixel.green,
               destination_pixel.blue,&hue,&saturation,&brightness);
             brightness+=(0.01*percent_brightness*offset)/midpoint;
             saturation*=0.01*percent_saturation;
-            HSBComposite(hue,saturation,brightness,&red,&green,&blue);
+            HSLComposite(hue,saturation,brightness,&red,&green,&blue);
             switch (channel)
             {
               case RedPixelChannel: pixel=red; break;
@@ -2192,11 +2177,11 @@ MagickExport MagickBooleanType CompositeImage(Image *image,
                 pixel=Sc;
                 break;
               }
-            CompositeHSB(destination_pixel.red,destination_pixel.green,
+            CompositeHSL(destination_pixel.red,destination_pixel.green,
               destination_pixel.blue,&hue,&saturation,&brightness);
-            CompositeHSB(source_pixel.red,source_pixel.green,source_pixel.blue,
+            CompositeHSL(source_pixel.red,source_pixel.green,source_pixel.blue,
               &sans,&saturation,&sans);
-            HSBComposite(hue,saturation,brightness,&red,&green,&blue);
+            HSLComposite(hue,saturation,brightness,&red,&green,&blue);
             switch (channel)
             {
               case RedPixelChannel: pixel=red; break;