[gimp/pippin/linear-is-the-new-black] app: improve structure of gimp_composite_blend conversions



commit 9e9a3cec8a57baa9fd7a8b2ff618503aeff114cc
Author: Øyvind Kolås <pippin gimp org>
Date:   Wed Jan 18 03:13:44 2017 +0100

    app: improve structure of gimp_composite_blend conversions

 .../layer-modes/gimpoperationpointlayermode.h      |  127 ++++++++++----------
 app/paint/gimppaintcore-loops.c                    |    4 +-
 2 files changed, 64 insertions(+), 67 deletions(-)
---
diff --git a/app/operations/layer-modes/gimpoperationpointlayermode.h 
b/app/operations/layer-modes/gimpoperationpointlayermode.h
index 27d086a..5caab5d 100644
--- a/app/operations/layer-modes/gimpoperationpointlayermode.h
+++ b/app/operations/layer-modes/gimpoperationpointlayermode.h
@@ -118,24 +118,32 @@ gimp_composite_blend (gfloat                *in,
                                               float *out,
                                               int samples))
 {
-  int samples_backup = samples;
+  int samples_backup  = samples;
   gfloat *blend_in    = in;
   gfloat *blend_layer = layer;
   gfloat *blend_out   = out;
+
   const Babl *fish_to_blend = NULL;
   const Babl *fish_to_composite = NULL;
   const Babl *fish_from_composite = NULL;
  
   switch (blend_trc)
   {
+    default:
     case GIMP_LAYER_BLEND_RGB_LINEAR:
+      fish_to_blend   =  NULL;
       switch (composite_trc)
       {
+        case GIMP_LAYER_BLEND_LAB:
+          fish_to_composite   = _gimp_fish_rgba_to_laba;
+          fish_from_composite = _gimp_fish_laba_to_rgba;
         default:
         case GIMP_LAYER_BLEND_RGB_LINEAR:
+          fish_to_composite   = NULL;
+          fish_from_composite = NULL;
           break;
         case GIMP_LAYER_BLEND_RGB_PERCEPTUAL:
-          fish_to_composite = _gimp_fish_rgba_to_perceptual;
+          fish_to_composite   = _gimp_fish_rgba_to_perceptual;
           fish_from_composite = _gimp_fish_perceptual_to_rgba;
           break;
       }
@@ -144,9 +152,13 @@ gimp_composite_blend (gfloat                *in,
       fish_to_blend   = _gimp_fish_rgba_to_laba;
       switch (composite_trc)
       {
+        case GIMP_LAYER_BLEND_LAB:
         default:
+          fish_to_composite = NULL;
+          fish_from_composite = _gimp_fish_laba_to_rgba;
         case GIMP_LAYER_BLEND_RGB_LINEAR:
           fish_to_composite = _gimp_fish_laba_to_rgba;
+          fish_from_composite = NULL;
           break;
         case GIMP_LAYER_BLEND_RGB_PERCEPTUAL:
           fish_to_composite = _gimp_fish_laba_to_perceptual;
@@ -155,58 +167,44 @@ gimp_composite_blend (gfloat                *in,
       }
       break;
     case GIMP_LAYER_BLEND_RGB_PERCEPTUAL:
-      fish_to_blend   = _gimp_fish_rgba_to_perceptual;
+      fish_to_blend = _gimp_fish_rgba_to_perceptual;
       switch (composite_trc)
       {
+        case GIMP_LAYER_BLEND_LAB:
         default:
+          fish_to_composite = _gimp_fish_perceptual_to_laba;
+          fish_from_composite = NULL;
         case GIMP_LAYER_BLEND_RGB_LINEAR:
           fish_to_composite = _gimp_fish_perceptual_to_rgba;
+          fish_from_composite = NULL;
           break;
         case GIMP_LAYER_BLEND_RGB_PERCEPTUAL:
+          fish_to_composite = NULL;
           fish_from_composite = _gimp_fish_perceptual_to_rgba;
           break;
       }
       break;
   }
 
-  if (blendfun == NULL)
-  {
-     if (fish_to_blend == NULL)
-       {
-         blend_out = layer;
-       }
-     else
-       {
-         blend_out = alloca (sizeof (gfloat) * 4 * samples);
-         babl_process (fish_to_blend, layer, blend_out, samples);
-       }
-  }
-  else if (fish_to_blend == NULL)
-  {
-    if (in == out)
-      blend_out = alloca (sizeof (gfloat) * 4 * samples);
+  if (in == out) /* in-place detected, avoid clobbering since we need to
+                    read it for the compositing stage  */
+    blend_out = alloca (sizeof (gfloat) * 4 * samples);
 
-    blendfun (blend_in, blend_layer, blend_out, samples);
-    if (fish_to_composite)
-    {
-      babl_process (fish_to_composite, blend_out, blend_out, samples);
-    }
-  }
-  else {
+  if (fish_to_blend)
+  {
     blend_in    = alloca (sizeof (gfloat) * 4 * samples);
     blend_layer = alloca (sizeof (gfloat) * 4 * samples);
+    babl_process (fish_to_blend, in,    blend_in,  samples);
+    babl_process (fish_to_blend, layer, blend_layer,  samples);
+  }
 
-    if (in == out)
-      blend_out   = alloca (sizeof (gfloat) * 4 * samples);
-    babl_process (fish_to_blend, in, blend_in, samples);
-    babl_process (fish_to_blend, layer, blend_layer, samples);
-    blendfun (blend_in, blend_layer, blend_out, samples);
+  blendfun (blend_in, blend_layer, blend_out, samples);
 
-    if (fish_to_composite)
+  if (fish_to_composite)
     {
+      babl_process (fish_to_composite, blend_in, blend_in,   samples);
       babl_process (fish_to_composite, blend_out, blend_out, samples);
     }
-  }
  
   switch (composite_mode)
   {
@@ -220,18 +218,17 @@ gimp_composite_blend (gfloat                *in,
  
           if (comp_alpha == 0.0f)
             {
-              out[RED]   = in[RED];
-              out[GREEN] = in[GREEN];
-              out[BLUE]  = in[BLUE];
+              out[RED]   = blend_in[RED];
+              out[GREEN] = blend_in[GREEN];
+              out[BLUE]  = blend_in[BLUE];
             }
             else
             {
               gint   b;
               for (b = RED; b < ALPHA; b++)
-                out[b] = blend_out[b] * comp_alpha + in[b] * (1.0f - comp_alpha);
+                out[b] = blend_out[b] * comp_alpha + blend_in[b] * (1.0f - comp_alpha);
             }
- 
-          out[ALPHA] = in[ALPHA];
+          out[ALPHA] = blend_in[ALPHA];
  
           in          += 4;
           out         += 4;
@@ -249,38 +246,39 @@ gimp_composite_blend (gfloat                *in,
           if (mask)
             comp_alpha *= *mask;
  
-          new_alpha = comp_alpha + (1.0f - comp_alpha) * in[ALPHA];
+          new_alpha = comp_alpha + (1.0f - comp_alpha) * blend_in[ALPHA];
  
           if (comp_alpha == 0.0f || new_alpha == 0.0f)
             {
-              out[RED]   = in[RED];
-              out[GREEN] = in[GREEN];
-              out[BLUE]  = in[BLUE];
+              out[RED]   = blend_in[RED];
+              out[GREEN] = blend_in[GREEN];
+              out[BLUE]  = blend_in[BLUE];
             }
             else
             {
               gint   b;
-              gfloat ratio = comp_alpha / new_alpha;
- 
               for (b = RED; b < ALPHA; b++)
-                out[b] = ratio * (in[ALPHA] * (blend_out[b] - layer[b]) + layer[b] - in[b]) + in[b];
+                out[b] = blend_out[b] * comp_alpha + blend_in[b] * (1.0f - comp_alpha);
             }
  
           out[ALPHA] = new_alpha;
  
-          in          += 4;
-          layer       += 4;
-          out         += 4;
+          blend_in    += 4;
           blend_out   += 4;
+          out         += 4;
  
           if (mask)
             mask++;
         }
       break;
     case GIMP_LAYER_COMPOSITE_DST_ATOP:
+
+      if (fish_to_composite)
+        babl_process (fish_to_composite, blend_layer, blend_layer,  samples);
+
       while (samples--)
         {
-          gfloat comp_alpha = in[ALPHA];
+          gfloat comp_alpha = blend_in[ALPHA];
  
           out[ALPHA] = blend_out[ALPHA] * opacity;
           if (mask)
@@ -288,19 +286,18 @@ gimp_composite_blend (gfloat                *in,
  
           if (comp_alpha == 0.0f)
             {
-              out[RED]   = layer[RED];
-              out[GREEN] = layer[GREEN];
-              out[BLUE]  = layer[BLUE];
+              out[RED]   = blend_layer[RED];
+              out[GREEN] = blend_layer[GREEN];
+              out[BLUE]  = blend_layer[BLUE];
             }
             else
             {
               gint   b;
               for (b = RED; b < ALPHA; b++)
-                out[b] = layer[b] * (1.0f -comp_alpha) + blend_out[b] * (comp_alpha);
+                out[b] = blend_layer[b] * (1.0f -comp_alpha) + blend_out[b] * (comp_alpha);
             }
- 
-          in          += 4;
-          layer       += 4;
+          blend_in    += 4;
+          blend_layer += 4;
           out         += 4;
           blend_out   += 4;
  
@@ -311,15 +308,15 @@ gimp_composite_blend (gfloat                *in,
     case GIMP_LAYER_COMPOSITE_SRC_IN:
       while (samples--)
         {
-          gfloat new_alpha = in[ALPHA] * blend_out[ALPHA] * opacity;
+          gfloat new_alpha = blend_in[ALPHA] * blend_out[ALPHA] * opacity;
           if (mask)
             new_alpha *= *mask;
  
           if (new_alpha == 0.0f)
             {
-              out[RED]   = in[RED];
-              out[GREEN] = in[GREEN];
-              out[BLUE]  = in[BLUE];
+              out[RED]   = blend_in[RED];
+              out[GREEN] = blend_in[GREEN];
+              out[BLUE]  = blend_in[BLUE];
             }
           else
             {
@@ -328,8 +325,7 @@ gimp_composite_blend (gfloat                *in,
               out[BLUE]  = blend_out[BLUE];
             }
           out[ALPHA] = new_alpha;
-          in          += 4;
-          out         += 4;
+          blend_in    += 4;
           blend_out   += 4;
  
           if (mask)
@@ -340,9 +336,8 @@ gimp_composite_blend (gfloat                *in,
 
   if (fish_from_composite)
   {
-    samples = samples_backup;
-    out -= 4 * samples;
-    babl_process (fish_from_composite, out, out, samples);
+    out -= 4 * samples_backup;
+    babl_process (fish_from_composite, out, out, samples_backup);
   }
 }
  
diff --git a/app/paint/gimppaintcore-loops.c b/app/paint/gimppaintcore-loops.c
index f13d497..132b6c5 100644
--- a/app/paint/gimppaintcore-loops.c
+++ b/app/paint/gimppaintcore-loops.c
@@ -299,6 +299,7 @@ do_layer_blend (GeglBuffer    *src_buffer,
 {
   GimpLayerBlendTRC   blend_trc = GIMP_LAYER_BLEND_RGB_PERCEPTUAL;//XXX
   GimpLayerBlendTRC   composite_trc = GIMP_LAYER_BLEND_RGB_LINEAR;//placeholders
+  GimpLayerCompositeMode composite_mode = GIMP_LAYER_COMPOSITE_SRC_OVER;//placeholders
   GeglRectangle       roi;
   GeglRectangle       mask_roi;
   GeglRectangle       process_roi;
@@ -366,7 +367,8 @@ do_layer_blend (GeglBuffer    *src_buffer,
                          &process_roi,
                          0,
                          blend_trc,
-                         composite_trc);
+                         composite_trc,
+                         composite_mode);
 
           in_pixel    += iter->roi[0].width * 4;
           out_pixel   += iter->roi[0].width * 4;


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