[gegl/soc-2011-ops] Added plasma op (segfault now, will resolve tommorow)
- From: Robert Sasu <sasurobert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/soc-2011-ops] Added plasma op (segfault now, will resolve tommorow)
- Date: Wed, 22 Jun 2011 20:51:01 +0000 (UTC)
commit 66d2b7c7647bb0df146e0047758ca51ed6b1e0a3
Author: Robert Sasu <sasu robert gmail com>
Date: Wed Jun 22 23:48:48 2011 +0300
Added plasma op (segfault now, will resolve tommorow)
operations/workshop/plasma.c | 314 +++++++++++++++++++++++++++++++++++-------
1 files changed, 267 insertions(+), 47 deletions(-)
---
diff --git a/operations/workshop/plasma.c b/operations/workshop/plasma.c
index 919d2b4..83f9790 100644
--- a/operations/workshop/plasma.c
+++ b/operations/workshop/plasma.c
@@ -31,11 +31,12 @@ gegl_chant_double (turbulance, _("Turbulance"), 0.1, 7.0, 2,
#else
-#define GEGL_CHANT_TYPE_AREA_FILTER
+#define GEGL_CHANT_TYPE_FILTER
#define GEGL_CHANT_C_FILE "plasma.c"
-#define RADIUS 5
#define floats_per_pixel 4
+#define MANUAL_ROI_VAL 200
+
#include "gegl-chant.h"
#include <math.h>
@@ -45,10 +46,6 @@ FILE *f;
static void prepare (GeglOperation *operation)
{
- GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
-
- op_area->left = op_area->right = op_area->top = op_area->bottom = RADIUS;
-
gegl_operation_set_format (operation, "input", babl_format ("RGBA float"));
gegl_operation_set_format (operation, "output", babl_format ("RGBA float"));
}
@@ -84,7 +81,6 @@ add_random (GRand *gr,
amount /= 2;
amount = fmod(amount, 1);
-// fprintf(f,"%lf \n",amount);
if (amount > 0)
for (i = 0; i < floats_per_pixel-1; i++)
{
@@ -105,6 +101,19 @@ put_pixel (gfloat *dst_buf,
static void
+put_pixel_to_buffer (GeglBuffer *output,
+ gfloat *pixel,
+ gint x,
+ gint y)
+{
+ GeglRectangle rect = {1, 1, 1, 1};
+ rect.x = x;
+ rect.y = y;
+ gegl_buffer_set (output, &rect, babl_format ("RGBA float"), pixel,
+ GEGL_AUTO_ROWSTRIDE);
+}
+
+static void
get_pixel (gfloat *src_buf,
const GeglRectangle *src,
gint x,
@@ -113,7 +122,7 @@ get_pixel (gfloat *src_buf,
{
gint i, offset;
offset = ((y - src->y) * src->width + x - src->x) * floats_per_pixel;
- // fprintf(f,"%d\n",offset);
+ fprintf(f, "%d \n", offset);
for (i = 0; i < floats_per_pixel; i++)
dst[i] = src_buf[offset++];
@@ -177,7 +186,7 @@ do_plasma (gfloat *src_buf,
random_rgba (gr, mb);
offset = ((y2 - dst->y) * dst->width + xm - dst->x) * 4;
put_pixel (dst_buf, mb, offset);
-/*ugly but working*/
+ /*ugly but working*/
return FALSE;
}
@@ -268,6 +277,218 @@ do_plasma (gfloat *src_buf,
}
+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;
+
+ src_buf = g_new0 (gfloat, roi->width * roi->height * floats_per_pixel);
+
+ gegl_buffer_get (input, 1.0, roi, babl_format ("RGBA float"), src_buf,
+ GEGL_AUTO_ROWSTRIDE);
+}
+
+
+static gboolean
+do_plasma_big (GeglBuffer *input,
+ GeglBuffer *output,
+ gint x1,
+ gint y1,
+ gint x2,
+ gint y2,
+ gint depth,
+ gint scale_depth,
+ GRand *gr,
+ GeglChantO *op)
+{
+ gfloat *tl, *ml, *bl, *mt, *mm, *mb, *tr, *mr, *br;
+ gfloat *tmp;
+ gint xm, ym;
+ gfloat ran;
+ static gint count = 0;
+
+ GeglRectangle roi = {0, 0, 0, 0};
+ gfloat *src_buf;
+
+ tl = ml = bl = mt = mm = mb = tr = mr = br = tmp
+ = g_new0 (gfloat, floats_per_pixel);
+
+ xm = (x1 + x2) / 2;
+ ym = (y1 + y2) / 2;
+
+ 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, 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);
+ /*ugly but working*/
+ return FALSE;
+ }
+
+ if (!depth)
+ {
+ if (x1 == x2 && y1 == y2) return FALSE;
+
+ gegl_buffer_sample (input, x1, y1, 1.0, tl, babl_format ("RGBA float"),
+ GEGL_INTERPOLATION_LINEAR);
+ gegl_buffer_sample (input, x1, y2, 1.0, bl, babl_format ("RGBA float"),
+ GEGL_INTERPOLATION_LINEAR);
+ gegl_buffer_sample (input, x2, y1, 1.0, tr, babl_format ("RGBA float"),
+ GEGL_INTERPOLATION_LINEAR);
+ gegl_buffer_sample (input, x2, y2, 1.0, br, babl_format ("RGBA float"),
+ GEGL_INTERPOLATION_LINEAR);
+/*
+ gegl_buffer_sample (output, x1, y1, 1.0, tl, babl_format ("RGBA float"),
+ GEGL_INTERPOLATION_LINEAR);
+ gegl_buffer_sample (output, x1, y2, 1.0, bl, babl_format ("RGBA float"),
+ GEGL_INTERPOLATION_LINEAR);
+ gegl_buffer_sample (output, x2, y1, 1.0, tr, babl_format ("RGBA float"),
+ GEGL_INTERPOLATION_LINEAR);
+ gegl_buffer_sample (output, x2, y2, 1.0, br, babl_format ("RGBA float"),
+ GEGL_INTERPOLATION_LINEAR);*/
+
+ ran = (1.0 / (2.0 * scale_depth)) * op->turbulance;
+
+ if (xm != x1 || xm != x2)
+ {
+ /*left*/
+ average_pixel (ml, tl, bl);
+ add_random (gr, ml, ran);
+ put_pixel_to_buffer (output, ml, x1, ym);
+
+ /*right*/
+ if (x1 != x2)
+ {
+ average_pixel (mr, tr, br);
+ add_random (gr, mr, ran);
+ put_pixel_to_buffer (output, mr, x2, ym);
+ }
+ }
+
+
+ if (ym != y1 || ym != x2)
+ {
+ /*bottom*/
+ if (x1 != xm || ym != y2)
+ {
+ average_pixel (mb, bl, br);
+ add_random (gr, mb, ran);
+ put_pixel_to_buffer (output, mb, xm, y2);
+ }
+
+ if (y1 != y2)
+ {
+ /*top*/
+ average_pixel (mt, tl, tr);
+ add_random (gr, mt, ran);
+ put_pixel_to_buffer (output, mt, xm, y1);
+ }
+ }
+
+ 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);
+ put_pixel_to_buffer (output, mm, xm, ym);
+ }
+ count++;
+
+ return x2 - x1 < 3 && y2 - y1 < 3;
+ }
+
+ if (x1 < x2 || y1 < y2)
+ {
+ if (x2 - x1 < MANUAL_ROI_VAL && y2 - y1 < MANUAL_ROI_VAL)
+ {
+ /*top-left*/
+ src_buf = NULL;
+ init_rect_buf (output, src_buf, &roi, x1, y1, xm, ym);
+ do_plasma (src_buf, &roi, src_buf, &roi, x1, y1, xm, ym, depth - 1,
+ scale_depth + 1, gr, op);
+ /*bottom-left*/
+ init_rect_buf (output, src_buf, &roi, x1, ym, xm, y2);
+ do_plasma (src_buf, &roi, src_buf, &roi, x1, ym, xm, y2, depth - 1,
+ scale_depth + 1, gr, op);
+ /*top-right*/
+ init_rect_buf (output, src_buf, &roi, xm, y1, x2, ym);
+ do_plasma (src_buf, &roi, src_buf, &roi, xm, y1, x2, ym, depth - 1,
+ scale_depth + 1, gr, op);
+ /*bottom-right*/
+ init_rect_buf (output, src_buf, &roi, xm, ym, x2, y2);
+ return do_plasma (src_buf, &roi, src_buf, &roi, xm, ym, x2, y2, depth - 1,
+ scale_depth + 1, gr, op);
+ }
+ else
+ {
+ /*top-left*/
+ do_plasma_big (input, output, x1, y1, xm, ym, depth - 1,
+ scale_depth + 1, gr, op);
+ /*bottom-left*/
+ do_plasma_big (input, output, x1, ym, xm, y2, depth - 1,
+ scale_depth + 1, gr, op);
+ /*top-right*/
+ do_plasma_big (input, output, xm, y1, x2, ym, depth - 1,
+ scale_depth + 1, gr, op);
+ /*bottom-right*/
+ return do_plasma_big (input, output, xm, ym, x2, y2, depth - 1,
+ scale_depth + 1, gr, op);
+ }
+ }
+ else return TRUE;
+
+ return TRUE;
+}
+
+
+
+static GeglRectangle
+plasma_get_bounding_box (GeglOperation *operation)
+{
+ GeglRectangle result = {0,0,0,0};
+ GeglRectangle *in_rect = gegl_operation_source_get_bounding_box (operation, "input");
+
+ gegl_rectangle_copy (&result, in_rect);
+
+ return result;
+}
+
+
+
static gboolean
process (GeglOperation *operation,
GeglBuffer *input,
@@ -275,54 +496,51 @@ process (GeglOperation *operation,
const GeglRectangle *result)
{
GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
- GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
- GeglRectangle rect;
- gfloat *src_buf;
+ GeglRectangle boundary=plasma_get_bounding_box(operation);
GRand *gr = g_rand_new_with_seed (o->seed);
gint depth;
gint x, y;
- rect.x = result->x - op_area->left;
- rect.width = result->width + op_area->left + op_area->right;
- rect.y = result->y - op_area->top;
- rect.height = result->height + op_area->top + op_area->bottom;
-
- src_buf = g_new0 (gfloat, rect.width * rect.height * floats_per_pixel);
-
- gegl_buffer_get (input, 1.0, &rect, babl_format ("RGBA float"),
- src_buf, GEGL_AUTO_ROWSTRIDE);
-
- g_rand_set_seed (gr, o->seed);
-
- if (result->height && result->width)
- {
- /*
- * The first time only puts seed pixels (corners, center of edges,
- * center of image)
- */
- x = rect.x + rect.width;
- y = rect.y + rect.height;
- if (rect.x < 0) rect.x = 0;
- if (rect.y < 0) rect.y = 0;
- do_plasma (src_buf, &rect, src_buf, &rect, rect.x, rect.y, x-1, y-1, -1, 0, gr, o);
- /*
- * Now we recurse through the images, going deeper each time
- */
- depth = 1;
- while (!do_plasma (src_buf, &rect, src_buf, &rect, rect.x, rect.y, x-1, y-1, depth, 0, gr, o))
- depth++;
- }
-
- gegl_buffer_set (output, &rect, babl_format ("RGBA float"),
- src_buf, GEGL_AUTO_ROWSTRIDE);
-
- g_free (src_buf);
+ /*
+ * The first time only puts seed pixels (corners, center of edges,
+ * center of image)
+ */
+ x = boundary.x + boundary.width;
+ y = boundary.y + boundary.height;
+
+ do_plasma_big (input, output, boundary.x, boundary.y, x-1, y-1, -1,
+ 0, gr, o);
+ /*
+ * Now we recurse through the images, going deeper each time
+ */
+ depth = 1;
+ while (!do_plasma_big (input, output, boundary.x, boundary.y, x-1,
+ y-1, depth, 0, gr, o))
+ depth++;
return TRUE;
}
+static GeglRectangle
+get_required_for_output (GeglOperation *operation,
+ const gchar *input_pad,
+ const GeglRectangle *roi)
+{
+ GeglRectangle result = *gegl_operation_source_get_bounding_box (operation,
+ "input");
+ return result;
+}
+
+static GeglRectangle
+get_cached_region (GeglOperation *operation,
+ const GeglRectangle *roi)
+{
+ return *gegl_operation_source_get_bounding_box (operation, "input");
+}
+
+
static void
gegl_chant_class_init (GeglChantClass *klass)
{
@@ -336,6 +554,8 @@ gegl_chant_class_init (GeglChantClass *klass)
filter_class->process = process;
operation_class->prepare = prepare;
+ operation_class->get_required_for_output = get_required_for_output;
+ operation_class->get_cached_region = get_cached_region;
operation_class->categories = "render";
operation_class->name = "gegl:plasma";
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]