[gimp/metadata-browser] Bug 541859 - Colour Balance Range to Adjust has no Effect



commit d008d90274601fbb349ca5d6f81543da80ef00a9
Author: Alexis Wilhelm <alexiswilhelm gmail com>
Date:   Wed Feb 15 21:00:27 2012 +0100

    Bug 541859 - Colour Balance Range to Adjust has no Effect
    
    This makes the different ranges have a clearly different effect,
    plus speeds up the gegl op quite a lot.
    
    NOTE: this might affect the result of scripts using color-balance

 app/base/color-balance.c             |  105 +++++++---------------------------
 app/gegl/gimpoperationcolorbalance.c |   62 ++++++++++----------
 2 files changed, 52 insertions(+), 115 deletions(-)
---
diff --git a/app/base/color-balance.c b/app/base/color-balance.c
index 62a47ac..4a9fbcb 100644
--- a/app/base/color-balance.c
+++ b/app/base/color-balance.c
@@ -38,15 +38,9 @@ static void   color_balance_transfer_init (void);
 
 static gboolean transfer_initialized = FALSE;
 
-/*  for lightening  */
-static gdouble  highlights_add[256] = { 0 };
-static gdouble  midtones_add[256]   = { 0 };
-static gdouble  shadows_add[256]    = { 0 };
-
-/*  for darkening  */
-static gdouble  highlights_sub[256] = { 0 };
-static gdouble  midtones_sub[256]   = { 0 };
-static gdouble  shadows_sub[256]    = { 0 };
+static gdouble  highlights[256] = { 0 };
+static gdouble  midtones[256]   = { 0 };
+static gdouble  shadows[256]    = { 0 };
 
 
 /*  public functions  */
@@ -71,9 +65,6 @@ color_balance_init (ColorBalance *cb)
 void
 color_balance_create_lookup_tables (ColorBalance *cb)
 {
-  gdouble *cyan_red_transfer[3];
-  gdouble *magenta_green_transfer[3];
-  gdouble *yellow_blue_transfer[3];
   gint     i;
   gint32   r_n, g_n, b_n;
 
@@ -85,78 +76,25 @@ color_balance_create_lookup_tables (ColorBalance *cb)
       transfer_initialized = TRUE;
     }
 
-  /*  Prepare the transfer arrays  (for speed)  */
-
-  cyan_red_transfer[GIMP_SHADOWS] =
-    (cb->cyan_red[GIMP_SHADOWS] > 0) ? shadows_add : shadows_sub;
-
-  cyan_red_transfer[GIMP_MIDTONES] =
-    (cb->cyan_red[GIMP_MIDTONES] > 0) ? midtones_add : midtones_sub;
-
-  cyan_red_transfer[GIMP_HIGHLIGHTS] =
-    (cb->cyan_red[GIMP_HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
-
-
-  magenta_green_transfer[GIMP_SHADOWS] =
-    (cb->magenta_green[GIMP_SHADOWS] > 0) ? shadows_add : shadows_sub;
-
-  magenta_green_transfer[GIMP_MIDTONES] =
-    (cb->magenta_green[GIMP_MIDTONES] > 0) ? midtones_add : midtones_sub;
-
-  magenta_green_transfer[GIMP_HIGHLIGHTS] =
-    (cb->magenta_green[GIMP_HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
-
-
-  yellow_blue_transfer[GIMP_SHADOWS] =
-    (cb->yellow_blue[GIMP_SHADOWS] > 0) ? shadows_add : shadows_sub;
-
-  yellow_blue_transfer[GIMP_MIDTONES] =
-    (cb->yellow_blue[GIMP_MIDTONES] > 0) ? midtones_add : midtones_sub;
-
-  yellow_blue_transfer[GIMP_HIGHLIGHTS] =
-    (cb->yellow_blue[GIMP_HIGHLIGHTS] > 0) ? highlights_add : highlights_sub;
-
-
   for (i = 0; i < 256; i++)
     {
       r_n = i;
       g_n = i;
       b_n = i;
 
-      r_n += (cb->cyan_red[GIMP_SHADOWS] *
-              cyan_red_transfer[GIMP_SHADOWS][r_n]);
+      r_n += cb->cyan_red[GIMP_SHADOWS] * shadows[i];
+      r_n += cb->cyan_red[GIMP_MIDTONES] * midtones[i];
+      r_n += cb->cyan_red[GIMP_HIGHLIGHTS] * highlights[i];
       r_n = CLAMP0255 (r_n);
 
-      r_n += (cb->cyan_red[GIMP_MIDTONES] *
-              cyan_red_transfer[GIMP_MIDTONES][r_n]);
-      r_n = CLAMP0255 (r_n);
-
-      r_n += (cb->cyan_red[GIMP_HIGHLIGHTS] *
-              cyan_red_transfer[GIMP_HIGHLIGHTS][r_n]);
-      r_n = CLAMP0255 (r_n);
-
-      g_n += (cb->magenta_green[GIMP_SHADOWS] *
-              magenta_green_transfer[GIMP_SHADOWS][g_n]);
-      g_n = CLAMP0255 (g_n);
-
-      g_n += (cb->magenta_green[GIMP_MIDTONES] *
-              magenta_green_transfer[GIMP_MIDTONES][g_n]);
-      g_n = CLAMP0255 (g_n);
-
-      g_n += (cb->magenta_green[GIMP_HIGHLIGHTS] *
-              magenta_green_transfer[GIMP_HIGHLIGHTS][g_n]);
+      g_n += cb->magenta_green[GIMP_SHADOWS] * shadows[i];
+      g_n += cb->magenta_green[GIMP_MIDTONES] * midtones[i];
+      g_n += cb->magenta_green[GIMP_HIGHLIGHTS] * highlights[i];
       g_n = CLAMP0255 (g_n);
 
-      b_n += (cb->yellow_blue[GIMP_SHADOWS] *
-              yellow_blue_transfer[GIMP_SHADOWS][b_n]);
-      b_n = CLAMP0255 (b_n);
-
-      b_n += (cb->yellow_blue[GIMP_MIDTONES] *
-              yellow_blue_transfer[GIMP_MIDTONES][b_n]);
-      b_n = CLAMP0255 (b_n);
-
-      b_n += (cb->yellow_blue[GIMP_HIGHLIGHTS] *
-              yellow_blue_transfer[GIMP_HIGHLIGHTS][b_n]);
+      b_n += cb->yellow_blue[GIMP_SHADOWS] * shadows[i];
+      b_n += cb->yellow_blue[GIMP_MIDTONES] * midtones[i];
+      b_n += cb->yellow_blue[GIMP_HIGHLIGHTS] * highlights[i];
       b_n = CLAMP0255 (b_n);
 
       cb->r_lookup[i] = r_n;
@@ -231,16 +169,13 @@ color_balance_transfer_init (void)
 
   for (i = 0; i < 256; i++)
     {
-      gdouble low = (1.075 - 1 / ((gdouble) i / 16.0 + 1));
-      gdouble mid = 0.667 * (1 - SQR (((gdouble) i - 127.0) / 127.0));
-
-      shadows_add[i]          = low;
-      shadows_sub[255 - i]    = low;
-
-      midtones_add[i]         = mid;
-      midtones_sub[i]         = mid;
-
-      highlights_add[255 - i] = low;
-      highlights_sub[i]       = low;
+      static const gdouble a = 64, b = 85, scale = 1.785;
+      gdouble low = CLAMP ((i - b) / -a + .5, 0, 1) * scale;
+      gdouble mid = CLAMP ((i - b) /  a + .5, 0, 1) *
+                    CLAMP ((i + b - 255) / -a + .5, 0, 1) * scale;
+
+      shadows[i]          = low;
+      midtones[i]         = mid;
+      highlights[255 - i] = low;
     }
 }
diff --git a/app/gegl/gimpoperationcolorbalance.c b/app/gegl/gimpoperationcolorbalance.c
index 3762f61..bf88035 100644
--- a/app/gegl/gimpoperationcolorbalance.c
+++ b/app/gegl/gimpoperationcolorbalance.c
@@ -78,35 +78,34 @@ gimp_operation_color_balance_init (GimpOperationColorBalance *self)
 
 static inline gfloat
 gimp_operation_color_balance_map (gfloat  value,
+                                  gdouble lightness,
                                   gdouble shadows,
                                   gdouble midtones,
                                   gdouble highlights)
 {
-  gdouble low = 1.075 - 1.0 / (value / 16.0 + 1.0);
-  gdouble mid = 0.667 * (1.0 - SQR (value - 0.5));
-  gdouble shadows_add;
-  gdouble shadows_sub;
-  gdouble midtones_add;
-  gdouble midtones_sub;
-  gdouble highlights_add;
-  gdouble highlights_sub;
-
-  shadows_add    = low + 1.0;
-  shadows_sub    = 1.0 - low;
-
-  midtones_add   = mid;
-  midtones_sub   = mid;
-
-  highlights_add = 1.0 - low;
-  highlights_sub = low + 1.0;
-
-  value += shadows * (shadows > 0 ? shadows_add : shadows_sub);
-  value = CLAMP (value, 0.0, 1.0);
-
-  value += midtones * (midtones > 0 ? midtones_add : midtones_sub);
-  value = CLAMP (value, 0.0, 1.0);
-
-  value += highlights * (highlights > 0 ? highlights_add : highlights_sub);
+  /* Apply masks to the corrections for shadows, midtones and
+   * highlights so that each correction affects only one range.
+   * Those masks look like this:
+   *     â\___
+   *     _/â\_
+   *     ___/â
+   * whith ramps of width a at x = b and x = 1 - b.
+   *
+   * The sum of these masks equals 1 for x in 0..1, so applying the
+   * same correction in the shadows and in the midtones is equivalent
+   * to applying this correction on a virtual shadows_and_midtones
+   * range.
+   */
+  static const gdouble a = 0.25, b = 0.333, scale = 0.7;
+
+  shadows    *= CLAMP ((lightness - b) / -a + 0.5, 0, 1) * scale;
+  midtones   *= CLAMP ((lightness - b) /  a + 0.5, 0, 1) *
+                CLAMP ((lightness + b - 1) / -a + 0.5, 0, 1) * scale;
+  highlights *= CLAMP ((lightness + b - 1) /  a + 0.5, 0, 1) * scale;
+
+  value += shadows;
+  value += midtones;
+  value += highlights;
   value = CLAMP (value, 0.0, 1.0);
 
   return value;
@@ -136,25 +135,28 @@ gimp_operation_color_balance_process (GeglOperation       *operation,
       gfloat g_n;
       gfloat b_n;
 
-      r_n = gimp_operation_color_balance_map (r,
+      GimpRGB rgb = { r, g, b};
+      GimpHSL hsl;
+
+      gimp_rgb_to_hsl (&rgb, &hsl);
+
+      r_n = gimp_operation_color_balance_map (r, hsl.l,
                                               config->cyan_red[GIMP_SHADOWS],
                                               config->cyan_red[GIMP_MIDTONES],
                                               config->cyan_red[GIMP_HIGHLIGHTS]);
 
-      g_n = gimp_operation_color_balance_map (g,
+      g_n = gimp_operation_color_balance_map (g, hsl.l,
                                               config->magenta_green[GIMP_SHADOWS],
                                               config->magenta_green[GIMP_MIDTONES],
                                               config->magenta_green[GIMP_HIGHLIGHTS]);
 
-      b_n = gimp_operation_color_balance_map (b,
+      b_n = gimp_operation_color_balance_map (b, hsl.l,
                                               config->yellow_blue[GIMP_SHADOWS],
                                               config->yellow_blue[GIMP_MIDTONES],
                                               config->yellow_blue[GIMP_HIGHLIGHTS]);
 
       if (config->preserve_luminosity)
         {
-          GimpRGB rgb;
-          GimpHSL hsl;
           GimpHSL hsl2;
 
           rgb.r = r_n;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]