[gegl] operations: fix convolution-matrix pretty much completely



commit 3db82e23a44de2da30df52507a4ee6ff8be900e9
Author: Michael Natterer <mitch gimp org>
Date:   Thu May 29 00:32:21 2014 +0200

    operations: fix convolution-matrix pretty much completely
    
    - use GeglAbyssPolicy instead of selfmade abyss handling; simply pass
      the policy propery to gegl_buffer_get()
    - remove all sorts of junk needed for reimplementins abyss
    - properly center the matrix on the source pixel

 operations/workshop/convolution-matrix.c |  142 ++++++++----------------------
 1 files changed, 37 insertions(+), 105 deletions(-)
---
diff --git a/operations/workshop/convolution-matrix.c b/operations/workshop/convolution-matrix.c
index 0637d87..306b5a8 100644
--- a/operations/workshop/convolution-matrix.c
+++ b/operations/workshop/convolution-matrix.c
@@ -22,12 +22,6 @@
 
 #ifdef GEGL_PROPERTIES
 
-enum_start (gegl_convolution_matrix_border)
-  enum_value (GEGL_CONVOLUTION_MATRIX_EXTEND, "extend", N_("Extend"))
-  enum_value (GEGL_CONVOLUTION_MATRIX_WRAP,   "wrap",   N_("Wrap"))
-  enum_value (GEGL_CONVOLUTION_MATRIX_CROP,   "crop",   N_("Crop"))
-enum_end (GeglConvolutionMatrixBorder)
-
 property_double (a1, _("(1,1)"), 0.0)
 property_double (a2, _("(1,2)"), 0.0)
 property_double (a3, _("(1,3)"), 0.0)
@@ -69,8 +63,8 @@ property_boolean (norm,   _("Normalize"),       TRUE)
 property_boolean (weight, _("Alpha-weighting"), TRUE)
 
 property_enum (border, _("Border"),
-               GeglConvolutionMatrixBorder, gegl_convolution_matrix_border,
-               GEGL_CONVOLUTION_MATRIX_EXTEND)
+               GeglAbyssPolicy, gegl_abyss_policy,
+               GEGL_ABYSS_CLAMP)
 
 #else
 
@@ -131,7 +125,7 @@ make_matrix (GeglProperties  *o,
   matrix[4][4] = o->e5;
 }
 
-static void
+static gboolean
 normalize_o (GeglProperties  *o,
              gdouble        **matrix)
 {
@@ -162,34 +156,28 @@ normalize_o (GeglProperties  *o,
       o->off = 0.5;
       o->div = 1;
     }
+
+  return valid;
 }
 
 static void
-convolve_pixel (gfloat               *src_buf,
+convolve_pixel (GeglProperties       *o,
+                gfloat               *src_buf,
                 gfloat               *dst_buf,
                 const GeglRectangle  *result,
                 const GeglRectangle  *extended,
-                const GeglRectangle  *boundary,
                 gdouble             **matrix,
-                GeglProperties       *o,
-                GeglBuffer           *input,
                 gint                  xx,
                 gint                  yy,
                 gdouble               matrixsum)
 {
-  gint    i, temp, s_x, s_y;
   gfloat  color[4];
-  gint    d_offset, s_offset;
-  gint    half;
-
-  s_x = 0;
-  s_y = 0;
+  gint    d_offset;
+  gint    s_offset;
+  gint    i;
 
-  half = (MATRIX_SIZE / 2) + (MATRIX_SIZE % 2);
-
-  d_offset = ((yy - result->y) * result->width * 4) + (xx - result->x) * 4;
-  s_offset = (yy - result->y + HALF_WINDOW) * extended->width * 4 +
-             (xx - result->x + HALF_WINDOW) * 4;
+  d_offset = (yy - result->y) * result->width * 4 +
+             (xx - result->x) * 4;
 
   for (i = 0; i < 4; i++)
     {
@@ -206,62 +194,19 @@ convolve_pixel (gfloat               *src_buf,
           for (x = 0; x < MATRIX_SIZE; x++)
             for (y = 0; y < MATRIX_SIZE; y++)
               {
-                switch (o->border)
-                  {
-                  case GEGL_CONVOLUTION_MATRIX_WRAP:
-                    s_x = fmod (x + xx, boundary->width);
-                    while (s_x < 0)
-                      s_x += boundary->width;
-
-                    s_y = fmod (y + yy, boundary->height);
-                    while (s_y < 0)
-                      s_y += boundary->width;
-                    break;
-
-                  case GEGL_CONVOLUTION_MATRIX_EXTEND:
-                    s_x = CLAMP (x + xx, 0, boundary->width);
-                    s_y = CLAMP (y + yy, 0, boundary->height);
-                    break;
-
-                  default:
-                    s_x = x + xx;
-                    s_y = y + yy;
-                    break;
-                  }
-
-                temp = (s_y - extended->y) * extended->width * 4 +
-                  (s_x - extended->x) * 4;
-
-                if ((s_x >= extended->x &&
-                     (s_x < extended->x + extended->width)) &&
-                    (s_y >=extended->y &&
-                     (s_y < extended->y + extended->height)))
-                  {
-                    if (i != 3 && o->weight)
-                      sum += matrix[x][y] * src_buf[temp + i] * src_buf[temp + 3];
-                    else
-                      sum += matrix[x][y] * src_buf[temp + i];
-
-                    if (i == 3)
-                      alphasum += fabs (matrix[x][y] * src_buf[temp + i]);
-                  }
+                gint s_x = x + xx - HALF_WINDOW;
+                gint s_y = y + yy - HALF_WINDOW;
+
+                s_offset = (s_y - extended->y) * extended->width * 4 +
+                           (s_x - extended->x) * 4;
+
+                if (i != 3 && o->weight)
+                  sum += matrix[x][y] * src_buf[s_offset + i] * src_buf[s_offset + 3];
                 else
-                  {
-                    gfloat temp_color[4];
-
-                    gegl_buffer_sample (input, s_x, s_y, NULL, temp_color,
-                                        babl_format ("RGBA float"),
-                                        GEGL_SAMPLER_NEAREST,
-                                        GEGL_ABYSS_NONE);
-
-                    if (i != 3 && o->weight)
-                      sum += matrix[x][y] * temp_color[i] * temp_color[3];
-                    else
-                      sum += matrix[x][y] * temp_color[i];
-
-                    if (i == 3)
-                      alphasum += fabs (matrix[x][y] * temp_color[i]);
-                  }
+                  sum += matrix[x][y] * src_buf[s_offset + i];
+
+                if (i == 3)
+                  alphasum += fabs (matrix[x][y] * src_buf[s_offset + i]);
               }
 
           sum = sum / o->div;
@@ -280,6 +225,9 @@ convolve_pixel (gfloat               *src_buf,
         }
       else
         {
+          s_offset = (yy - result->y + HALF_WINDOW) * extended->width * 4 +
+                     (xx - result->x + HALF_WINDOW) * 4;
+
           color[i] = src_buf[s_offset + i];
         }
     }
@@ -288,17 +236,6 @@ convolve_pixel (gfloat               *src_buf,
     dst_buf[d_offset + i] = color[i];
 }
 
-static GeglRectangle
-get_effective_area (GeglOperation *operation)
-{
-  GeglRectangle  result  = { 0, };
-  GeglRectangle *in_rect = gegl_operation_source_get_bounding_box (operation, "input");
-
-  gegl_rectangle_copy (&result, in_rect);
-
-  return result;
-}
-
 static gboolean
 process (GeglOperation       *operation,
          GeglBuffer          *input,
@@ -308,16 +245,13 @@ process (GeglOperation       *operation,
 {
   GeglProperties          *o       = GEGL_PROPERTIES (operation);
   GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
-
-  GeglRectangle   rect;
-  GeglRectangle   boundary = get_effective_area (operation);
-  gfloat         *src_buf;
-  gfloat         *dst_buf;
-  gdouble       **matrix;
-
-  const Babl    *format = babl_format ("RGBA float");
-  gint           x, y;
-  gdouble        matrixsum = 0.0;
+  const Babl              *format  = babl_format ("RGBA float");
+  GeglRectangle            rect;
+  gfloat                  *src_buf;
+  gfloat                  *dst_buf;
+  gdouble                **matrix;
+  gdouble                  matrixsum = 0.0;
+  gint                     x, y;
 
   matrix = g_new0 (gdouble *, MATRIX_SIZE);
 
@@ -342,16 +276,14 @@ process (GeglOperation       *operation,
   dst_buf = g_new0 (gfloat, result->width * result->height * 4);
 
   gegl_buffer_get (input, &rect, 1.0, format, src_buf,
-                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
-
-  /*fill src_buf with wrap pixels if it is the case*/
+                   GEGL_AUTO_ROWSTRIDE, o->border);
 
   if (o->div != 0)
     {
       for (y = result->y; y < result->height + result->y; y++)
         for (x = result->x; x < result->width + result->x; x++)
-          convolve_pixel (src_buf, dst_buf, result, &rect, &boundary,
-                          matrix, o, input, x, y, matrixsum);
+          convolve_pixel (o, src_buf, dst_buf, result, &rect,
+                          matrix, x, y, matrixsum);
 
       gegl_buffer_set (output, result, 0, format,
                        dst_buf, GEGL_AUTO_ROWSTRIDE);


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