[gegl] Revert "performance optimization in box-blur filter."
- From: Victor Matheus de Araujo Oliveira <vmaolive src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] Revert "performance optimization in box-blur filter."
- Date: Mon, 31 Dec 2012 19:02:52 +0000 (UTC)
commit 4f023ae21361f367e71627a81b01f2abbe02a71e
Author: Victor Oliveira <victormatheus gmail com>
Date: Mon Dec 31 17:02:28 2012 -0200
Revert "performance optimization in box-blur filter."
This reverts commit d2af5dc22dbab3ebd9542a8bfa6b106d39bc3efa.
operations/common/box-blur.c | 238 +++++++++++++++++++++++++-----------------
1 files changed, 140 insertions(+), 98 deletions(-)
---
diff --git a/operations/common/box-blur.c b/operations/common/box-blur.c
index eae2136..6c0b255 100644
--- a/operations/common/box-blur.c
+++ b/operations/common/box-blur.c
@@ -14,7 +14,6 @@
* License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2006 Ãyvind KolÃs <pippin gimp org>
- * 2012 Pavel Roschin <roshin scriptumplus ru>
*/
#include "config.h"
@@ -35,8 +34,91 @@ gegl_chant_double_ui (radius, _("Radius"), 0.0, 1000.0, 4.0, 0.0, 100.0, 1.5,
#include <stdio.h>
#include <math.h>
-#define SRC_OFFSET (row + u + radius * 2) * 4
+#ifdef USE_DEAD_CODE
+static inline float
+get_mean_component (gfloat *buf,
+ gint buf_width,
+ gint buf_height,
+ gint x0,
+ gint y0,
+ gint width,
+ gint height,
+ gint component)
+{
+ gint x, y;
+ gdouble acc=0;
+ gint count=0;
+
+ gint offset = (y0 * buf_width + x0) * 4 + component;
+
+ for (y=y0; y<y0+height; y++)
+ {
+ for (x=x0; x<x0+width; x++)
+ {
+ if (x>=0 && x<buf_width &&
+ y>=0 && y<buf_height)
+ {
+ acc += buf [offset];
+ count++;
+ }
+ offset+=4;
+ }
+ offset+= (buf_width * 4) - 4 * width;
+ }
+ if (count)
+ return acc/count;
+ return 0.0;
+}
+#endif
+
+static inline void
+get_mean_components (gfloat *buf,
+ gint buf_width,
+ gint buf_height,
+ gint x0,
+ gint y0,
+ gint width,
+ gint height,
+ gfloat *components)
+{
+ gint y;
+ gdouble acc[4]={0,0,0,0};
+ gint count[4]={0,0,0,0};
+
+ gint offset = (y0 * buf_width + x0) * 4;
+ for (y=y0; y<y0+height; y++)
+ {
+ gint x;
+ for (x=x0; x<x0+width; x++)
+ {
+ if (x>=0 && x<buf_width &&
+ y>=0 && y<buf_height)
+ {
+ gint c;
+ for (c=0;c<4;c++)
+ {
+ acc[c] += buf [offset+c];
+ count[c]++;
+ }
+ }
+ offset+=4;
+ }
+ offset+= (buf_width * 4) - 4 * width;
+ }
+ {
+ gint c;
+ for (c=0;c<4;c++)
+ {
+ if (count[c])
+ components[c] = acc[c]/count[c];
+ else
+ components[c] = 0.0;
+ }
+ }
+}
+
+/* expects src and dst buf to have the same extent */
static void
hor_blur (GeglBuffer *src,
const GeglRectangle *src_rect,
@@ -45,58 +127,44 @@ hor_blur (GeglBuffer *src,
gint radius)
{
gint u,v;
- gint i;
gint offset;
- gint src_offset;
- gint prev_rad = radius * 4 + 4;
- gint next_rad = radius * 4;
- gint row;
gfloat *src_buf;
gfloat *dst_buf;
- gfloat rad1 = 1.0 / (gfloat)(radius * 2 + 1);
+ /* src == dst for hor blur */
src_buf = g_new0 (gfloat, src_rect->width * src_rect->height * 4);
dst_buf = g_new0 (gfloat, dst_rect->width * dst_rect->height * 4);
- gegl_buffer_get (src, src_rect, 1.0, babl_format ("RaGaBaA float"),
- src_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
+ gegl_buffer_get (src, src_rect, 1.0, babl_format ("RaGaBaA float"), src_buf, GEGL_AUTO_ROWSTRIDE,
+ GEGL_ABYSS_NONE);
offset = 0;
- for (v = 0; v < dst_rect->height; v++)
- {
- /* here just radius, not radius * 2 as in ver_blur because
- * we enlarged dst_buf by y earlier */
- row = (v + radius) * src_rect->width;
- /* prepare - set first column of pixels */
- for (u = -radius; u <= radius; u++)
- {
- src_offset = SRC_OFFSET;
- for (i = 0; i < 4; i++)
- dst_buf[offset + i] += src_buf[src_offset + i] * rad1;
- }
- offset += 4;
- /* iterate other pixels by moving a window - very fast */
- for (u = 1; u < dst_rect->width; u++)
- {
- src_offset = SRC_OFFSET;
- for (i = 0; i < 4; i++)
- {
- dst_buf[offset] = dst_buf[offset - 4]
- - src_buf[src_offset - prev_rad] * rad1
- + src_buf[src_offset + next_rad] * rad1;
- src_offset++;
- offset++;
- }
- }
- }
-
- gegl_buffer_set (dst, dst_rect, 0, babl_format ("RaGaBaA float"),
- dst_buf, GEGL_AUTO_ROWSTRIDE);
-
+ for (v=0; v<dst_rect->height; v++)
+ for (u=0; u<dst_rect->width; u++)
+ {
+ gint i;
+ gfloat components[4];
+
+ get_mean_components (src_buf,
+ src_rect->width,
+ src_rect->height,
+ u - radius,
+ v,
+ 1 + radius*2,
+ 1,
+ components);
+
+ for (i=0; i<4; i++)
+ dst_buf [offset++] = components[i];
+ }
+
+ gegl_buffer_set (dst, dst_rect, 0, babl_format ("RaGaBaA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
g_free (src_buf);
g_free (dst_buf);
}
+
+/* expects dst buf to be radius smaller than src buf */
static void
ver_blur (GeglBuffer *src,
const GeglRectangle *src_rect,
@@ -104,62 +172,42 @@ ver_blur (GeglBuffer *src,
const GeglRectangle *dst_rect,
gint radius)
{
- gint u, v;
- gint i;
+ gint u,v;
gint offset;
- gint src_offset;
- gint prev_rad = (radius * 4 + 4) * src_rect->width;
- gint next_rad = (radius * 4) * src_rect->width;
- gint row;
gfloat *src_buf;
gfloat *dst_buf;
- gfloat rad1 = 1.0 / (gfloat)(radius * 2 + 1);
src_buf = g_new0 (gfloat, src_rect->width * src_rect->height * 4);
dst_buf = g_new0 (gfloat, dst_rect->width * dst_rect->height * 4);
- gegl_buffer_get (src, src_rect, 1.0, babl_format ("RaGaBaA float"),
- src_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
-
- /* prepare: set first row of pixels */
- for (v = -radius; v <= radius; v++)
- {
- row = (v + radius * 2) * src_rect->width;
- for (u = 0; u < dst_rect->width; u++)
- {
- src_offset = SRC_OFFSET;
- for (i = 0; i < 4; i++)
- dst_buf[u * 4 + i] += src_buf[src_offset + i] * rad1;
- }
- }
- /* skip first row */
- offset = dst_rect->width * 4;
- for (v = 1; v < dst_rect->height; v++)
- {
- row = (v + radius * 2) * src_rect->width;
- for (u = 0; u < dst_rect->width; u++)
- {
- src_offset = SRC_OFFSET;
- for (i = 0; i < 4; i++)
- {
- dst_buf[offset] = dst_buf[offset - 4 * dst_rect->width]
- - src_buf[src_offset - prev_rad] * rad1
- + src_buf[src_offset + next_rad] * rad1;
- src_offset++;
- offset++;
- }
- }
- }
-
- gegl_buffer_set (dst, dst_rect, 0, babl_format ("RaGaBaA float"),
- dst_buf, GEGL_AUTO_ROWSTRIDE);
-
+ gegl_buffer_get (src, src_rect, 1.0, babl_format ("RaGaBaA float"), src_buf, GEGL_AUTO_ROWSTRIDE,
+ GEGL_ABYSS_NONE);
+
+ offset=0;
+ for (v=0; v<dst_rect->height; v++)
+ for (u=0; u<dst_rect->width; u++)
+ {
+ gfloat components[4];
+ gint c;
+
+ get_mean_components (src_buf,
+ src_rect->width,
+ src_rect->height,
+ u + radius, /* 1x radius is the offset between the bufs */
+ v - radius + radius, /* 1x radius is the offset between the bufs */
+ 1,
+ 1 + radius * 2,
+ components);
+
+ for (c=0; c<4; c++)
+ dst_buf [offset++] = components[c];
+ }
+
+ gegl_buffer_set (dst, dst_rect, 0, babl_format ("RaGaBaA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
g_free (src_buf);
g_free (dst_buf);
}
-#undef SRC_OFFSET
-
static void prepare (GeglOperation *operation)
{
GeglChantO *o;
@@ -330,7 +378,6 @@ process (GeglOperation *operation,
gint level)
{
GeglRectangle rect;
- GeglRectangle tmprect;
GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
GeglBuffer *temp;
GeglOperationAreaFilter *op_area;
@@ -341,21 +388,16 @@ process (GeglOperation *operation,
return TRUE;
rect = *result;
- tmprect = *result;
- rect.x -= op_area->left * 2;
- rect.y -= op_area->top * 2;
- rect.width += (op_area->left + op_area->right) * 2;
- rect.height += (op_area->top + op_area->bottom) * 2;
- /* very tricky: enlarge temp buffer to avoid seams in second pass */
- tmprect.y -= o->radius;
- tmprect.height += o->radius * 2;
+ rect.x-=op_area->left;
+ rect.y-=op_area->top;
+ rect.width+=op_area->left + op_area->right;
+ rect.height+=op_area->top + op_area->bottom;
- temp = gegl_buffer_new (&tmprect,
+ temp = gegl_buffer_new (&rect,
babl_format ("RaGaBaA float"));
- /* doing second pass in separate gegl op may be significantly faster */
- hor_blur (input, &rect, temp, &tmprect, o->radius);
+ hor_blur (input, &rect, temp, &rect, o->radius);
ver_blur (temp, &rect, output, result, o->radius);
g_object_unref (temp);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]