Commit 2cb55d43 authored by Massimo Valentini's avatar Massimo Valentini Committed by Daniel Sabo

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
parent 089e3f37
......@@ -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;
......
......@@ -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"
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment