[gegl] Bug 727005: "C" and "cl" gegl:pixelize produce different results



commit 2cb55d4363d346132b6b29f96dd94f223c9d7cc9
Author: Massimo Valentini <mvalentini src gnome org>
Date:   Wed Mar 26 18:31:49 2014 +0100

    Bug 727005: "C" and "cl" gegl:pixelize produce different results
    
    * Use input bounding box, not only its width/height, to compute
      block color for partial blocks.
    * Always round down integer divisions

 opencl/pixelize.cl           |   39 ++++++++++++++++++++++++---------------
 opencl/pixelize.cl.h         |   39 ++++++++++++++++++++++++---------------
 operations/common/pixelize.c |   29 +++++++++++++++++++----------
 3 files changed, 67 insertions(+), 40 deletions(-)
---
diff --git a/opencl/pixelize.cl b/opencl/pixelize.cl
index bb75963..b87cfd5 100644
--- a/opencl/pixelize.cl
+++ b/opencl/pixelize.cl
@@ -17,40 +17,49 @@
  * Copyright 2013 Carlos Zubieta  <czubieta dev gmail com>
  */
 
+int
+block_index (int pos,
+             int size)
+{
+  return pos < 0 ? ((pos + 1) / size - 1) : (pos / size);
+}
+
 __kernel void calc_block_color(__global float4 *in,
                                __global float4 *out,
                                         int     xsize,
                                         int     ysize,
                                         int     roi_x,
                                         int     roi_y,
-                                        int     total_width_x,
-                                        int     total_width_y,
+                                        int4    bbox,
                                         int     line_width,
                                         int     block_count_x )
 {
   int gidx = get_global_id(0);
   int gidy = get_global_id(1);
 
-  int cx = roi_x / xsize + gidx;
-  int cy = roi_y / ysize + gidy;
+  int cx = block_index (roi_x, xsize) + gidx;
+  int cy = block_index (roi_y, ysize) + gidy;
+
+  int px0 = max (bbox.s0, cx * xsize) - roi_x + xsize;
+  int py0 = max (bbox.s1, cy * ysize) - roi_y + ysize;
 
-  int px = cx * xsize - roi_x;
-  int py = cy * ysize - roi_y;
+  int px1 = min (bbox.s2, cx * xsize + xsize) - roi_x + xsize;
+  int py1 = min (bbox.s3, cy * ysize + ysize) - roi_y + ysize;
 
   int i, j;
 
   float4 col = (float4)(0.0f, 0.0f, 0.0f, 0.0f);
 
-  int real_xsize = min (total_width_x - px - roi_x, xsize);
-  int real_ysize = min (total_width_y - py - roi_y, ysize);
+  int real_xsize = px1 - px0;
+  int real_ysize = py1 - py0;
 
   float weight = 1.0f / (real_xsize * real_ysize);
 
-  for (j = py; j < py + real_ysize; ++j)
+  for (j = py0; j < py1; ++j)
     {
-      for (i = px; i < px + real_xsize; ++i)
+      for (i = px0; i < px1; ++i)
         {
-          col += in[(j + ysize) * line_width + i + xsize];
+          col += in[j * line_width + i];
         }
     }
   out[gidy * block_count_x + gidx] = col * weight;
@@ -78,8 +87,8 @@ __kernel void kernel_pixelize(__global float4 *in,
   int gidy = get_global_id(1);
 
   int src_width  = get_global_size(0);
-  int cx = (gidx + roi_x) / xsize - roi_x / xsize;
-  int cy = (gidy + roi_y) / ysize - roi_y / ysize;
+  int cx = block_index (gidx + roi_x, xsize) - block_index (roi_x, xsize);
+  int cy = block_index (gidy + roi_y, ysize) - block_index (roi_y, ysize);
 
   float4 grid_color = in[cx + cy * block_count_x];
   float4 out_color = bg_color;
@@ -93,8 +102,8 @@ __kernel void kernel_pixelize(__global float4 *in,
   int off_shape_x = floor ((xsize - xratio * xsize) / 2.0f);
   int off_shape_y = floor ((ysize - yratio * ysize) / 2.0f);
 
-  int start_x = (x_pos / xsize) * xsize - roi_x;
-  int start_y = (y_pos / ysize) * ysize - roi_y;
+  int start_x = block_index (x_pos, xsize) * xsize - roi_x;
+  int start_y = block_index (y_pos, ysize) * ysize - roi_y;
 
   float shape_area = rect_shape_width * rect_shape_height;
 
diff --git a/opencl/pixelize.cl.h b/opencl/pixelize.cl.h
index 00b3ac7..15ef3e2 100644
--- a/opencl/pixelize.cl.h
+++ b/opencl/pixelize.cl.h
@@ -18,40 +18,49 @@ static const char* pixelize_cl_source =
 " * Copyright 2013 Carlos Zubieta  <czubieta dev gmail com>                    \n"
 " */                                                                           \n"
 "                                                                              \n"
+"int                                                                           \n"
+"block_index (int pos,                                                         \n"
+"             int size)                                                        \n"
+"{                                                                             \n"
+"  return pos < 0 ? ((pos + 1) / size - 1) : (pos / size);                     \n"
+"}                                                                             \n"
+"                                                                              \n"
 "__kernel void calc_block_color(__global float4 *in,                           \n"
 "                               __global float4 *out,                          \n"
 "                                        int     xsize,                        \n"
 "                                        int     ysize,                        \n"
 "                                        int     roi_x,                        \n"
 "                                        int     roi_y,                        \n"
-"                                        int     total_width_x,                \n"
-"                                        int     total_width_y,                \n"
+"                                        int4    bbox,                         \n"
 "                                        int     line_width,                   \n"
 "                                        int     block_count_x )               \n"
 "{                                                                             \n"
 "  int gidx = get_global_id(0);                                                \n"
 "  int gidy = get_global_id(1);                                                \n"
 "                                                                              \n"
-"  int cx = roi_x / xsize + gidx;                                              \n"
-"  int cy = roi_y / ysize + gidy;                                              \n"
+"  int cx = block_index (roi_x, xsize) + gidx;                                 \n"
+"  int cy = block_index (roi_y, ysize) + gidy;                                 \n"
+"                                                                              \n"
+"  int px0 = max (bbox.s0, cx * xsize) - roi_x + xsize;                        \n"
+"  int py0 = max (bbox.s1, cy * ysize) - roi_y + ysize;                        \n"
 "                                                                              \n"
-"  int px = cx * xsize - roi_x;                                                \n"
-"  int py = cy * ysize - roi_y;                                                \n"
+"  int px1 = min (bbox.s2, cx * xsize + xsize) - roi_x + xsize;                \n"
+"  int py1 = min (bbox.s3, cy * ysize + ysize) - roi_y + ysize;                \n"
 "                                                                              \n"
 "  int i, j;                                                                   \n"
 "                                                                              \n"
 "  float4 col = (float4)(0.0f, 0.0f, 0.0f, 0.0f);                              \n"
 "                                                                              \n"
-"  int real_xsize = min (total_width_x - px - roi_x, xsize);                   \n"
-"  int real_ysize = min (total_width_y - py - roi_y, ysize);                   \n"
+"  int real_xsize = px1 - px0;                                                 \n"
+"  int real_ysize = py1 - py0;                                                 \n"
 "                                                                              \n"
 "  float weight = 1.0f / (real_xsize * real_ysize);                            \n"
 "                                                                              \n"
-"  for (j = py; j < py + real_ysize; ++j)                                      \n"
+"  for (j = py0; j < py1; ++j)                                                 \n"
 "    {                                                                         \n"
-"      for (i = px; i < px + real_xsize; ++i)                                  \n"
+"      for (i = px0; i < px1; ++i)                                             \n"
 "        {                                                                     \n"
-"          col += in[(j + ysize) * line_width + i + xsize];                    \n"
+"          col += in[j * line_width + i];                                      \n"
 "        }                                                                     \n"
 "    }                                                                         \n"
 "  out[gidy * block_count_x + gidx] = col * weight;                            \n"
@@ -79,8 +88,8 @@ static const char* pixelize_cl_source =
 "  int gidy = get_global_id(1);                                                \n"
 "                                                                              \n"
 "  int src_width  = get_global_size(0);                                        \n"
-"  int cx = (gidx + roi_x) / xsize - roi_x / xsize;                            \n"
-"  int cy = (gidy + roi_y) / ysize - roi_y / ysize;                            \n"
+"  int cx = block_index (gidx + roi_x, xsize) - block_index (roi_x, xsize);    \n"
+"  int cy = block_index (gidy + roi_y, ysize) - block_index (roi_y, ysize);    \n"
 "                                                                              \n"
 "  float4 grid_color = in[cx + cy * block_count_x];                            \n"
 "  float4 out_color = bg_color;                                                \n"
@@ -94,8 +103,8 @@ static const char* pixelize_cl_source =
 "  int off_shape_x = floor ((xsize - xratio * xsize) / 2.0f);                  \n"
 "  int off_shape_y = floor ((ysize - yratio * ysize) / 2.0f);                  \n"
 "                                                                              \n"
-"  int start_x = (x_pos / xsize) * xsize - roi_x;                              \n"
-"  int start_y = (y_pos / ysize) * ysize - roi_y;                              \n"
+"  int start_x = block_index (x_pos, xsize) * xsize - roi_x;                   \n"
+"  int start_y = block_index (y_pos, ysize) * ysize - roi_y;                   \n"
 "                                                                              \n"
 "  float shape_area = rect_shape_width * rect_shape_height;                    \n"
 "                                                                              \n"
diff --git a/operations/common/pixelize.c b/operations/common/pixelize.c
index fe5251f..686e001 100644
--- a/operations/common/pixelize.c
+++ b/operations/common/pixelize.c
@@ -267,6 +267,13 @@ set_rectangle_noalloc (GeglBuffer      *output,
     }
 }
 
+static int
+block_index (int pos,
+             int size)
+{
+  return pos < 0 ? ((pos + 1) / size - 1) : (pos / size);
+}
+
 static void
 pixelize_noalloc (GeglBuffer          *input,
                   GeglBuffer          *output,
@@ -274,8 +281,8 @@ pixelize_noalloc (GeglBuffer          *input,
                   const GeglRectangle *whole_region,
                   GeglChantO          *o)
 {
-  gint start_x = (roi->x / o->size_x) * o->size_x;
-  gint start_y = (roi->y / o->size_y) * o->size_y;
+  gint start_x = block_index (roi->x, o->size_x) * o->size_x;
+  gint start_y = block_index (roi->y, o->size_y) * o->size_y;
   gint x, y;
   gint off_shape_x, off_shape_y;
 
@@ -320,8 +327,8 @@ pixelize (gfloat              *input,
           const GeglRectangle *whole_region,
           GeglChantO          *o)
 {
-  gint          start_x = (roi->x / o->size_x) * o->size_x;
-  gint          start_y = (roi->y / o->size_y) * o->size_y;
+  gint          start_x = block_index (roi->x, o->size_x) * o->size_x;
+  gint          start_y = block_index (roi->y, o->size_y) * o->size_y;
   gint          x, y;
   gint          off_shape_x, off_shape_y;
   gfloat        color[4];
@@ -393,10 +400,13 @@ cl_pixelize (cl_mem               in_tex,
   cl_int cl_err = 0;
   const size_t gbl_size[2]= {roi->width, roi->height};
 
-  gint cx0 = roi->x / xsize;
-  gint cy0 = roi->y / ysize;
-  gint block_count_x = ((roi->x + roi->width  + xsize - 1) / xsize) - cx0;
-  gint block_count_y = ((roi->y + roi->height + ysize - 1) / ysize) - cy0;
+  gint cx0 = block_index (roi->x, xsize);
+  gint cy0 = block_index (roi->y, ysize);
+  gint block_count_x = block_index (roi->x + roi->width  + xsize - 1, xsize) - cx0;
+  gint block_count_y = block_index (roi->y + roi->height + ysize - 1, ysize) - cy0;
+  cl_int4 bbox = {{ image_extent->x, image_extent->y,
+                    image_extent->x + image_extent->width,
+                    image_extent->y + image_extent->height }};
 
   cl_int line_width = roi->width + 2 * xsize;
 
@@ -417,8 +427,7 @@ cl_pixelize (cl_mem               in_tex,
                                     sizeof(cl_int), (void*)&ysize,
                                     sizeof(cl_int), (void*)&roi->x,
                                     sizeof(cl_int), (void*)&roi->y,
-                                    sizeof(cl_int), (void*)&image_extent->width,
-                                    sizeof(cl_int), (void*)&image_extent->height,
+                                    sizeof(cl_int4), &bbox,
                                     sizeof(cl_int), (void*)&line_width,
                                     sizeof(cl_int), (void*)&block_count_x,
                                     NULL);


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