[gegl/soc-2011-ops] Added plasma op, working fast, result like bricks
- From: Robert Sasu <sasurobert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/soc-2011-ops] Added plasma op, working fast, result like bricks
- Date: Mon, 27 Jun 2011 13:17:24 +0000 (UTC)
commit 182cc6a26bde85b148789aa8a29a7e4117647fdc
Author: Robert Sasu <sasu robert gmail com>
Date: Mon Jun 27 16:16:52 2011 +0300
Added plasma op, working fast, result like bricks
operations/workshop/plasma.c | 309 +++++++++++++++++++++++++++++++++++-------
1 files changed, 258 insertions(+), 51 deletions(-)
---
diff --git a/operations/workshop/plasma.c b/operations/workshop/plasma.c
index a476fc6..422e40d 100644
--- a/operations/workshop/plasma.c
+++ b/operations/workshop/plasma.c
@@ -103,27 +103,77 @@ put_pixel_to_buffer (GeglBuffer *output,
GEGL_AUTO_ROWSTRIDE);
}
+
+static void
+init_rect_buf (GeglBuffer *input,
+ gfloat *src_buf,
+ GeglRectangle *roi,
+ gint x1,
+ gint y1,
+ gint x2,
+ gint y2)
+{
+ roi->x = x1;
+ roi->y = y1;
+ roi->width = x2 - x1;
+ roi->height = y2 - y1;
+}
+
+
+static void
+get_pixel (gfloat *src_buf,
+ const GeglRectangle *src,
+ gint x,
+ gint y,
+ gfloat *dst)
+{
+ gint i, offset;
+ offset = ((y - src->y) * src->width + x - src->x) * floats_per_pixel;
+
+ if (src_buf == NULL) printf("NULL \n");
+
+ for (i = 0; i < floats_per_pixel; i++)
+ dst[i] = src_buf[offset++];
+
+ dst[i] = dst[i];
+}
+
+static void
+put_pixel (gfloat *dst_buf,
+ gfloat *pixel,
+ gint offset)
+{
+ gint i;
+ for (i = 0; i < floats_per_pixel; i++)
+ dst_buf[offset++] = pixel[i];
+}
+
+
+
static gboolean
-do_plasma_big (GeglBuffer *output,
- gint x1,
- gint y1,
- gint x2,
- gint y2,
- gint depth,
- gint scale_depth,
- GRand *gr,
- GeglChantO *op)
+do_plasma_big (GeglBuffer *output,
+ gfloat *dst_buf,
+ const GeglRectangle *dst,
+ gint x1,
+ gint y1,
+ gint x2,
+ gint y2,
+ gint depth,
+ gint scale_depth,
+ GRand *gr,
+ GeglChantO *op,
+ gint small)
{
gfloat *tl, *ml, *bl, *mt, *mm, *mb, *tr, *mr, *br;
gfloat *tmp;
- gint xm, ym;
+ gint xm, ym, offset;
gfloat ran;
static gint count = 0;
- /*
+
GeglRectangle roi = {0, 0, 0, 0};
gfloat *src_buf;
gboolean toreturn;
- */
+
tl = ml = bl = mt = mm = mb = tr = mr = br = tmp
= g_new0 (gfloat, floats_per_pixel);
@@ -133,47 +183,64 @@ do_plasma_big (GeglBuffer *output,
if (depth == -1)
{
random_rgba (gr, tl);
- put_pixel_to_buffer (output, tl, x1, y1);
-
random_rgba (gr, tr);
- put_pixel_to_buffer (output, tr, x2, y1);
-
- random_rgba (gr, bl);
- put_pixel_to_buffer (output, bl, x1, y2);
-
+ random_rgba (gr, bl);
random_rgba (gr, br);
- put_pixel_to_buffer (output, br, x2, y2);
-
random_rgba (gr, mm);
- put_pixel_to_buffer (output, mm, xm, ym);
-
random_rgba (gr, ml);
- put_pixel_to_buffer (output, ml, x1, ym);
-
random_rgba (gr, mr);
- put_pixel_to_buffer (output, mr, x2, ym);
-
random_rgba (gr, mt);
- put_pixel_to_buffer (output, mt, xm, y1);
-
random_rgba (gr, mb);
- put_pixel_to_buffer (output, mb, xm, y2);
+
+ if (!small)
+ {
+ put_pixel_to_buffer (output, tl, x1, y1);
+ put_pixel_to_buffer (output, tr, x2, y1);
+ put_pixel_to_buffer (output, bl, x1, y2);
+ put_pixel_to_buffer (output, br, x2, y2);
+ put_pixel_to_buffer (output, mm, xm, ym);
+ put_pixel_to_buffer (output, ml, x1, ym);
+ put_pixel_to_buffer (output, mr, x2, ym);
+ put_pixel_to_buffer (output, mt, xm, y1);
+ put_pixel_to_buffer (output, mb, xm, y2);
+ }
+ else
+ {
+ offset = ((y1 - dst->y) * dst->width + x1 - dst->x) * 4;
+ put_pixel (dst_buf, tl, offset);
+ offset = ((y1 - dst->y) * dst->width + x2 - dst->x) * 4;
+ put_pixel (dst_buf, tr, offset);
+ offset = ((y2 - dst->y) * dst->width + x1 - dst->x) * 4;
+ put_pixel (dst_buf, bl, offset);
+ offset = ((y2 - dst->y) * dst->width + x2 - dst->x) * 4;
+ put_pixel (dst_buf, br, offset);
+ offset = ((ym - dst->y) * dst->width + xm - dst->x) * 4;
+ put_pixel (dst_buf, mm, offset);
+ offset = ((ym - dst->y) * dst->width + x1 - dst->x) * 4;
+ put_pixel (dst_buf, ml, offset);
+ offset = ((ym - dst->y) * dst->width + x2 - dst->x) * 4;
+ put_pixel (dst_buf, mr, offset);
+ offset = ((y1 - dst->y) * dst->width + xm - dst->x) * 4;
+ put_pixel (dst_buf, mt, offset);
+ offset = ((y2 - dst->y) * dst->width + xm - dst->x) * 4;
+ put_pixel (dst_buf, mb, offset);
+ }
/*ugly but working*/
return FALSE;
}
- if (!depth)
+ if (!depth && !small)
{
if (x1 == x2 && y1 == y2) return FALSE;
gegl_buffer_sample (output, x1, y1, 1.0, tl, babl_format ("RGBA float"),
- GEGL_INTERPOLATION_LINEAR);
+ GEGL_INTERPOLATION_NEAREST);
gegl_buffer_sample (output, x1, y2, 1.0, bl, babl_format ("RGBA float"),
- GEGL_INTERPOLATION_LINEAR);
+ GEGL_INTERPOLATION_NEAREST);
gegl_buffer_sample (output, x2, y1, 1.0, tr, babl_format ("RGBA float"),
- GEGL_INTERPOLATION_LINEAR);
+ GEGL_INTERPOLATION_NEAREST);
gegl_buffer_sample (output, x2, y2, 1.0, br, babl_format ("RGBA float"),
- GEGL_INTERPOLATION_LINEAR);
+ GEGL_INTERPOLATION_NEAREST);
ran = ((gfloat) op->turbulance / (2.0 * scale_depth));
@@ -227,20 +294,159 @@ do_plasma_big (GeglBuffer *output,
return x2 - x1 < 3 && y2 - y1 < 3;
}
+ if (!depth && small)
+ {
+ if (x1 == x2 && y1 == y2) return FALSE;
+
+ get_pixel (dst_buf, dst, x1, y1, tl);
+ get_pixel (dst_buf, dst, x1, y2, bl);
+ get_pixel (dst_buf, dst, x2, y1, tr);
+ get_pixel (dst_buf, dst, x2, y2, tr);
+
+ ran = ((gfloat) op->turbulance / (2.0 * scale_depth));
+
+ if (xm != x1 || xm != x2)
+ {
+ /*left*/
+ average_pixel (ml, tl, bl);
+ add_random (gr, ml, ran);
+ offset = ((ym - dst->y) * dst->width + x1 - dst->x) * 4;
+ put_pixel (dst_buf, ml, offset);
+
+ /*right*/
+ if (x1 != x2)
+ {
+ average_pixel (mr, tr, br);
+ add_random (gr, mr, ran);
+ offset = ((ym - dst->y) * dst->width + x2 - dst->x) * 4;
+ put_pixel (dst_buf, mr, offset);
+ }
+ }
+
+
+ if (ym != y1 || ym != x2)
+ {
+ /*bottom*/
+ if (x1 != xm || ym != y2)
+ {
+ average_pixel (mb, bl, br);
+ add_random (gr, mb, ran);
+ offset = ((y2 - dst->y) * dst->width + xm - dst->x) *4;
+ put_pixel (dst_buf, mb, offset);
+ }
+
+ if (y1 != y2)
+ {
+ /*top*/
+ average_pixel (mt, tl, tr);
+ add_random (gr, mt, ran);
+ offset = ((y1 - dst->y)* dst->width + xm - dst->x) * 4;
+ put_pixel (dst_buf, mt, offset);
+ }
+ }
+
+ if (y1 != y2 || x1 != x2)
+ {
+ average_pixel (mm, tl, br);
+ average_pixel (tmp, bl, tr);
+ average_pixel (mm, mm, tmp);
+
+ add_random (gr, mm, ran);
+ offset = ((ym - dst->y) * dst->width + xm - dst->x) * 4;
+ put_pixel (dst_buf, mm, offset);
+ }
+ count++;
+
+ return x2 - x1 < 3 && y2 - y1 < 3;
+ }
+
+
if (x1 < x2 || y1 < y2)
{
+ if (x2 - x1 < MANUAL_ROI_VAL && y2 - y1 < MANUAL_ROI_VAL && !small)
+ {
+ /*top-left*/
+ src_buf = NULL;
+ init_rect_buf (output, src_buf, &roi, x1, y1, xm, ym);
+
+ src_buf = g_new0 (gfloat, (roi.width + 1) * (roi.height + 1) * floats_per_pixel);
+ gegl_buffer_get (output, 1.0, &roi, babl_format ("RGBA float"), src_buf,
+ GEGL_AUTO_ROWSTRIDE);
+
+ do_plasma_big (NULL, src_buf, &roi, x1, y1, xm, ym, depth - 1,
+ scale_depth + 1, gr, op, 1);
+ gegl_buffer_set (output, &roi, babl_format ("RGBA float"), src_buf,
+ GEGL_AUTO_ROWSTRIDE);
+ g_free(src_buf);
+ /*bottom-left*/
+ init_rect_buf (output, src_buf, &roi, x1, ym, xm, y2);
+
+ src_buf = g_new0 (gfloat, (roi.width + 1) * (roi.height + 1) * floats_per_pixel);
+ gegl_buffer_get (output, 1.0, &roi, babl_format ("RGBA float"), src_buf,
+ GEGL_AUTO_ROWSTRIDE);
+
+ do_plasma_big (NULL, src_buf, &roi, x1, ym, xm, y2, depth - 1,
+ scale_depth + 1, gr, op, 1);
+ gegl_buffer_set (output, &roi, babl_format ("RGBA float"), src_buf,
+ GEGL_AUTO_ROWSTRIDE);
+ g_free(src_buf);
+ /*top-right*/
+ init_rect_buf (output, src_buf, &roi, xm, y1, x2, ym);
+
+ src_buf = g_new0 (gfloat, (roi.width + 1) * (roi.height + 1) * floats_per_pixel);
+ gegl_buffer_get (output, 1.0, &roi, babl_format ("RGBA float"), src_buf,
+ GEGL_AUTO_ROWSTRIDE);
+
+ do_plasma_big (NULL, src_buf, &roi, xm, y1, x2, ym, depth - 1,
+ scale_depth + 1, gr, op, 1);
+ gegl_buffer_set (output, &roi, babl_format ("RGBA float"), src_buf,
+ GEGL_AUTO_ROWSTRIDE);
+ g_free(src_buf);
+ /*bottom-right*/
+ init_rect_buf (output, src_buf, &roi, xm, ym, x2, y2);
+
+ src_buf = g_new0 (gfloat, (roi.width + 1) * (roi.height + 1) * floats_per_pixel);
+ gegl_buffer_get (output, 1.0, &roi, babl_format ("RGBA float"), src_buf,
+ GEGL_AUTO_ROWSTRIDE);
+
+ toreturn = do_plasma_big (NULL, src_buf, &roi, xm, ym, x2, y2, depth - 1,
+ scale_depth + 1, gr, op, 1);
+ gegl_buffer_set (output, &roi, babl_format ("RGBA float"), src_buf,
+ GEGL_AUTO_ROWSTRIDE);
+ g_free(src_buf);
+
+ return toreturn;
+ }
+ else if (x2 - x1 < MANUAL_ROI_VAL && y2 - y1 < MANUAL_ROI_VAL && small)
+ {
/*top-left*/
- do_plasma_big (output, x1, y1, xm, ym, depth - 1,
- scale_depth + 1, gr, op);
+ do_plasma_big (NULL, dst_buf, dst, x1, y1, xm, ym, depth - 1,
+ scale_depth + 1, gr, op, 1);
/*bottom-left*/
- do_plasma_big (output, x1, ym, xm, y2, depth - 1,
- scale_depth + 1, gr, op);
+ do_plasma_big (NULL, dst_buf, dst, x1, ym, xm, y2, depth - 1,
+ scale_depth + 1, gr, op, 1);
/*top-right*/
- do_plasma_big (output, xm, y1, x2, ym, depth - 1,
- scale_depth + 1, gr, op);
+ do_plasma_big (NULL, dst_buf, dst, xm, y1, x2, ym, depth - 1,
+ scale_depth + 1, gr, op, 1);
/*bottom-right*/
- return do_plasma_big (output, xm, ym, x2, y2, depth - 1,
- scale_depth + 1, gr, op);
+ return do_plasma_big (NULL, dst_buf, dst, xm, ym, x2, y2, depth - 1,
+ scale_depth + 1, gr, op, 1);
+ }
+ else
+ {
+ /*top-left*/
+ do_plasma_big (output, dst_buf, dst, x1, y1, xm, ym, depth - 1,
+ scale_depth + 1, gr, op, 0);
+ /*bottom-left*/
+ do_plasma_big (output, dst_buf, dst, x1, ym, xm, y2, depth - 1,
+ scale_depth + 1, gr, op, 0);
+ /*top-right*/
+ do_plasma_big (output, dst_buf, dst, xm, y1, x2, ym, depth - 1,
+ scale_depth + 1, gr, op, 0);
+ /*bottom-right*/
+ return do_plasma_big (output, dst_buf, dst, xm, ym, x2, y2, depth - 1,
+ scale_depth + 1, gr, op, 0);
+ }
}
else return TRUE;
@@ -270,11 +476,12 @@ process (GeglOperation *operation,
{
GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
- GeglRectangle boundary=plasma_get_bounding_box(operation);
+ GeglRectangle boundary = plasma_get_bounding_box(operation);
- GRand *gr = g_rand_new_with_seed (o->seed);
- gint depth;
- gint x, y;
+ GRand *gr = g_rand_new_with_seed (o->seed);
+ gint depth;
+ gint x, y;
+ gfloat *src = NULL;
/*
* The first time only puts seed pixels (corners, center of edges,
@@ -283,14 +490,14 @@ process (GeglOperation *operation,
x = boundary.x + boundary.width;
y = boundary.y + boundary.height;
- do_plasma_big (output, boundary.x, boundary.y, x-1, y-1, -1,
- 0, gr, o);
+ do_plasma_big (output, src, &boundary, boundary.x, boundary.y, x-1, y-1, -1,
+ 0, gr, o, 0);
/*
* Now we recurse through the images, going deeper each time
*/
depth = 1;
- while (!do_plasma_big (output, boundary.x, boundary.y, x-1,
- y-1, depth, 0, gr, o))
+ while (!do_plasma_big (output, src, &boundary, boundary.x, boundary.y, x-1,
+ y-1, depth, 0, gr, o, 0))
depth++;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]