[gegl/soc-2011-ops] Added plasma op, working fast, result like bricks



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]