[gegl] operations: npd: add alpha blending



commit 97d3926bac332cc8d41b13dad43b8631d7d056e8
Author: Marek Dvoroznak <dvoromar gmail com>
Date:   Mon Jan 13 19:40:28 2014 +0100

    operations: npd: add alpha blending

 libs/npd/graphics.c       |   13 ++++++++-----
 libs/npd/graphics.h       |    5 -----
 operations/external/npd.c |   31 ++++++++++++++++++++++++++-----
 3 files changed, 34 insertions(+), 15 deletions(-)
---
diff --git a/libs/npd/graphics.c b/libs/npd/graphics.c
index 1cb8897..353b9a4 100644
--- a/libs/npd/graphics.c
+++ b/libs/npd/graphics.c
@@ -54,7 +54,7 @@ npd_bilinear_color_interpolation (NPDColor *I0,
   out->a = npd_bilinear_interpolation (I0->a, I1->a, I2->a, I3->a, dx, dy);
 }
 
-gfloat
+static gfloat
 npd_blend_band (gfloat src,
                 gfloat dst,
                 gfloat src_alpha,
@@ -73,11 +73,14 @@ npd_blend_colors (NPDColor *src,
   gfloat src_A = src->a / 255.0,
          dst_A = dst->a / 255.0;
   gfloat out_alpha = src_A + dst_A * (1 - src_A);
-  gfloat out_alpha_recip = 1 / out_alpha;
+  if (out_alpha > 0)
+    {
+      gfloat out_alpha_recip = 1 / out_alpha;
 
-  out_color->r = npd_blend_band (src->r, dst->r, src_A, dst_A, out_alpha_recip);
-  out_color->g = npd_blend_band (src->g, dst->g, src_A, dst_A, out_alpha_recip);
-  out_color->b = npd_blend_band (src->b, dst->b, src_A, dst_A, out_alpha_recip);
+      out_color->r = npd_blend_band (src->r, dst->r, src_A, dst_A, out_alpha_recip);
+      out_color->g = npd_blend_band (src->g, dst->g, src_A, dst_A, out_alpha_recip);
+      out_color->b = npd_blend_band (src->b, dst->b, src_A, dst_A, out_alpha_recip);
+    }
   out_color->a = out_alpha * 255;
 }
 
diff --git a/libs/npd/graphics.h b/libs/npd/graphics.h
index 89c1ab4..902026b 100644
--- a/libs/npd/graphics.h
+++ b/libs/npd/graphics.h
@@ -55,11 +55,6 @@ void            npd_draw_model_into_image         (NPDModel   *model,
 void            npd_draw_mesh                     (NPDModel   *model,
                                                    NPDDisplay *display);
 gboolean        npd_is_color_transparent          (NPDColor   *color);
-gfloat          npd_blend_band                    (gfloat      src,
-                                                   gfloat      dst,
-                                                   gfloat      src_alpha,
-                                                   gfloat      dst_alpha,
-                                                   gfloat      out_alpha_recip);
 extern void   (*npd_draw_line)                    (NPDDisplay *display,
                                                    gfloat      x0,
                                                    gfloat      y0,
diff --git a/operations/external/npd.c b/operations/external/npd.c
index dda01d6..c4b39ea 100644
--- a/operations/external/npd.c
+++ b/operations/external/npd.c
@@ -89,6 +89,9 @@ prepare (GeglOperation *operation)
   gegl_operation_set_format (operation, "output", babl_format ("RGBA float"));
 }
 
+#define NPD_BLEND_BAND(src,dst,src_alpha,dst_alpha,out_alpha_recip) \
+(src * src_alpha + dst * dst_alpha * (1 - src_alpha)) * out_alpha_recip;
+
 static void
 npd_gegl_process_pixel (NPDImage *input_image,
                         gfloat    ix,
@@ -101,18 +104,36 @@ npd_gegl_process_pixel (NPDImage *input_image,
   if (ox > -1 && ox < output_image->width &&
       oy > -1 && oy < output_image->height)
     {
-      gint position = 4 * (((gint) oy) * output_image->width + ((gint) ox));
+      gint    position = 4 * (((gint) oy) * output_image->width + ((gint) ox));
+      gfloat  sample_color[4];
+      gfloat *dst_color = &output_image->buffer_f[position];
+      gfloat  src_A, dst_A, out_alpha, out_alpha_recip;
       gegl_buffer_sample (input_image->gegl_buffer, ix, iy, NULL,
-                          &output_image->buffer_f[position], output_image->format,
+                          sample_color, output_image->format,
                           output_image->sampler_type, GEGL_ABYSS_NONE);
+
+      /* suppose that output_image has RGBA float pixel format - and what about endianness? */
+      src_A = sample_color[3];
+      dst_A = dst_color[3];
+      out_alpha = src_A + dst_A * (1 - src_A);
+      if (out_alpha > 0)
+        {
+          out_alpha_recip = 1 / out_alpha;
+          dst_color[0] = NPD_BLEND_BAND (sample_color[0], dst_color[0], src_A, dst_A, out_alpha_recip);
+          dst_color[1] = NPD_BLEND_BAND (sample_color[1], dst_color[1], src_A, dst_A, out_alpha_recip);
+          dst_color[2] = NPD_BLEND_BAND (sample_color[2], dst_color[2], src_A, dst_A, out_alpha_recip);
+        }
+      dst_color[3] = out_alpha;
     }
 }
 
+#undef NPD_BLEND_BAND
+
 static void
 npd_gegl_get_pixel_color_f (NPDImage *image,
-                          gint      x,
-                          gint      y,
-                          NPDColor *color)
+                            gint      x,
+                            gint      y,
+                            NPDColor *color)
 {
   gegl_buffer_sample (image->gegl_buffer, x, y, NULL,
                       &color->color, babl_format ("RGBA u8"),


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