[gegl] operations: yet another bunch of improvments for noise-pick.c
- From: Téo Mazars <teom src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] operations: yet another bunch of improvments for noise-pick.c
- Date: Sat, 19 Oct 2013 06:26:36 +0000 (UTC)
commit 8ccd3ddaa3f4da398b90f307ef719dcfa1a99fba
Author: Téo Mazars <teo mazars ensimag fr>
Date: Sat Oct 19 08:20:23 2013 +0200
operations: yet another bunch of improvments for noise-pick.c
as suggested by massimo :
- use iterators + samplers instead of buffer_get/set
- Avoid unnecessary calls to gegl_random
actual speed-up: 1.5x for repeat = 100 and randomness = 0.5
operations/common/noise-pick.c | 122 ++++++++++++---------------------------
1 files changed, 38 insertions(+), 84 deletions(-)
---
diff --git a/operations/common/noise-pick.c b/operations/common/noise-pick.c
index 31341fc..2cb8563 100644
--- a/operations/common/noise-pick.c
+++ b/operations/common/noise-pick.c
@@ -47,11 +47,6 @@ gegl_chant_int (repeat, _("Repeat"),
#include "gegl-chant.h"
-
-#define CHUNK_SIZE 1024
-#define MAX_HW_EXT 1224
-#define SQR(x) ((x)*(x))
-
static void
prepare (GeglOperation *operation)
{
@@ -70,48 +65,11 @@ prepare (GeglOperation *operation)
gegl_operation_set_format (operation, "output", format);
}
-static void
-iterate (GeglRectangle *current_roi,
- gint src_rowstride,
- gchar *src,
- gchar *dst,
- gint seed,
- gfloat pct_random,
- gint bpp,
- gint repeat)
-{
- gint x, y;
-
- for(y = 0; y < current_roi->height; y++)
- for(x = 0; x < current_roi->width; x++)
- {
- gint pos_x = current_roi->x + x;
- gint pos_y = current_roi->y + y;
- gint i;
-
- for (i = 0; i < repeat; i++)
- {
- gfloat rand;
-
- rand = gegl_random_float_range (seed, pos_x, pos_y, 0, i, 0.0, 100.0);
-
- if (rand <= pct_random)
- {
- gint k = gegl_random_int_range (seed, pos_x, pos_y, 0, i, 0, 9);
-
- pos_x += (k % 3) - 1;
- pos_y += (k / 3) - 1;
- }
- }
-
- pos_x -= current_roi->x;
- pos_y -= current_roi->y;
- memcpy (dst + (x + y * current_roi->width) * bpp,
- src + (pos_x + pos_y * src_rowstride) * bpp,
- bpp);
- }
-}
+/* We avoid unecessary calls to gegl_random
+ * by recomputing a small part ourselves.
+ * see gegl/gegl-random.c for details */
+#define RAND_UINT_TO_FLOAT(x) (((x) & 0xffff) * 0.00001525902189669642175)
static gboolean
process (GeglOperation *operation,
@@ -120,54 +78,50 @@ process (GeglOperation *operation,
const GeglRectangle *result,
gint level)
{
- GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
- GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
- GeglRectangle src_rect, chunked_result;
- gchar *input_buf, *output_buf;
- gchar *src_buf;
- gint rowstride;
- gint i, j;
- const Babl *format;
- gint bpp;
+ GeglChantO *o;
+ const Babl *format;
+ gint bpp;
+ GeglBufferIterator *gi;
+
+ o = GEGL_CHANT_PROPERTIES (operation);
format = gegl_operation_get_source_format (operation, "input");
bpp = babl_format_get_bytes_per_pixel (format);
- input_buf = g_malloc (SQR (MAX_HW_EXT) * bpp);
- output_buf = g_malloc (SQR (CHUNK_SIZE) * bpp);
-
- for (j = 0; (j-1) * CHUNK_SIZE < result->height; j++)
- for (i = 0; (i-1) * CHUNK_SIZE < result->width; i++)
- {
- chunked_result = *GEGL_RECTANGLE (result->x + i * CHUNK_SIZE,
- result->y + j * CHUNK_SIZE,
- CHUNK_SIZE, CHUNK_SIZE);
+ gi = gegl_buffer_iterator_new (output, result, 0, format,
+ GEGL_BUFFER_WRITE, GEGL_ABYSS_CLAMP);
- gegl_rectangle_intersect (&chunked_result, &chunked_result, result);
+ while (gegl_buffer_iterator_next (gi))
+ {
+ gchar *data = gi->data[0];
+ GeglRectangle roi = gi->roi[0];
+ gint i, j;
- if (chunked_result.width < 1 || chunked_result.height < 1)
- continue;
-
- src_rect.x = chunked_result.x - op_area->left;
- src_rect.y = chunked_result.y - op_area->top;
- src_rect.width = chunked_result.width + op_area->left + op_area->right;
- src_rect.height = chunked_result.height + op_area->top + op_area->bottom;
-
- gegl_buffer_get (input, &src_rect, 1.0, format, input_buf,
- GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
+ for (j = roi.y; j < roi.y + roi.height ; j++)
+ for (i = roi.x; i < roi.x + roi.width ; i++)
+ {
+ gint r;
+ gint pos_x = i, pos_y = j;
- rowstride = src_rect.width;
- src_buf = (input_buf + (o->repeat * rowstride + o->repeat) * bpp);
+ for (r = 0; r < o->repeat; r++)
+ {
+ guint rand = gegl_random_int (o->seed, pos_x, pos_y, 0, r);
+ gfloat pct = RAND_UINT_TO_FLOAT (rand) * 100.0;
- iterate (&chunked_result, rowstride, src_buf, output_buf,
- o->seed, o->pct_random, bpp, o->repeat);
+ if (pct <= o->pct_random)
+ {
+ gint rand2 = (gint) (rand % 9);
- gegl_buffer_set (output, &chunked_result, 1.0, format, output_buf,
- GEGL_AUTO_ROWSTRIDE);
- }
+ pos_x += (rand2 % 3) - 1;
+ pos_y += (rand2 / 3) - 1;
+ }
+ }
- g_free (input_buf);
- g_free (output_buf);
+ gegl_buffer_sample (input, pos_x, pos_y, NULL, data, format,
+ GEGL_SAMPLER_NEAREST, GEGL_ABYSS_CLAMP);
+ data += bpp;
+ }
+ }
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]