[gegl/soc-2011-ops] Added plasma op (segfault now, will resolve tommorow)



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]