[gegl] operations: Fix plasma.c's implementation
- From: Téo Mazars <teom src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] operations: Fix plasma.c's implementation
- Date: Thu, 12 Sep 2013 19:12:40 +0000 (UTC)
commit 4005509232d9e5955318e2f9105924d788590d72
Author: Téo Mazars <teo mazars ensimag fr>
Date: Thu Sep 12 20:31:40 2013 +0200
operations: Fix plasma.c's implementation
- Make it a GeglOperationSource
- Attributing works legitimately
- Don't leak GRand
- Works on R'G'B' instead of RGBA
- Try to stay in 80 columns
- Increase tile size to 512x512 to improve performances
- Some minor format fixes
operations/workshop/plasma.c | 128 ++++++++++++++++++++++-------------------
1 files changed, 69 insertions(+), 59 deletions(-)
---
diff --git a/operations/workshop/plasma.c b/operations/workshop/plasma.c
index e05ad77..ff73024 100644
--- a/operations/workshop/plasma.c
+++ b/operations/workshop/plasma.c
@@ -13,8 +13,11 @@
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
*
- * Copyright (C) 1996 Stephen Norris
- * Copyright (C) 2011 Robert Sasu (sasu robert gmail com)
+ * Copyright (C) 1996 Stephen Norris (srn flibble cs su oz au)
+ * Copyright (C) 1996 Eiichi Takamori (taka ma1 seikyou ne jp)
+ * Copyright (C) 2000 Tim Copperfield (timecop japan co jp)
+ * Copyright (C) 2011 Robert Sasu (sasu robert gmail com)
+ * Copyright (C) 2013 Téo Mazars (teo mazars ensimag fr)
*/
/*
@@ -31,19 +34,24 @@
#ifdef GEGL_CHANT_PROPERTIES
gegl_chant_int (seed, _("Seed"), -1, G_MAXINT, -1,
- _("Random seed. Passing -1 implies that the seed is randomly chosen."))
+ _("Random seed."
+ "Passing -1 implies that the seed is randomly chosen."))
gegl_chant_double (turbulence, _("Turbulence"), 0.1, 7.0, 1.0,
_("The value of the turbulence"))
+gegl_chant_int (width, _("Width"), 0, G_MAXINT, 1024,
+ _("Width of the generated buffer"))
+gegl_chant_int (height, _("Height"), 0, G_MAXINT, 768,
+ _("Height of the generated buffer"))
+
#else
-#define GEGL_CHANT_TYPE_FILTER
-#define GEGL_CHANT_C_FILE "plasma.c"
+#define GEGL_CHANT_TYPE_SOURCE
+#define GEGL_CHANT_C_FILE "plasma.c"
#include "gegl-chant.h"
-#include <math.h>
-#define TILE_SIZE 128
+#define TILE_SIZE 512
typedef struct
{
@@ -58,21 +66,14 @@ typedef struct
} PlasmaContext;
static void
-prepare (GeglOperation *operation)
-{
- gegl_operation_set_format (operation, "input", babl_format ("RGBA float"));
- gegl_operation_set_format (operation, "output", babl_format ("RGBA float"));
-}
-
-static void
average_pixel (gfloat *dst_buf,
gfloat *src_buf1,
gfloat *src_buf2)
{
gint i;
- for (i = 0; i < 4; i++)
- *dst_buf++ = (*src_buf1++ + *src_buf2++) / 2;
+ for (i = 0; i < 3; i++)
+ *dst_buf++ = (*src_buf1++ + *src_buf2++) / 2.0;
}
static void
@@ -81,8 +82,8 @@ random_rgba (GRand *gr,
{
gint i;
- for (i = 0; i < 4; i++)
- dest[i] = (gfloat) g_rand_double_range (gr, 0, 1);
+ for (i = 0; i < 3; i++)
+ dest[i] = (gfloat) g_rand_double_range (gr, 0.0, 1.0);
}
static void
@@ -93,13 +94,13 @@ add_random (GRand *gr,
gint i;
gfloat tmp;
- amount /= 2;
+ amount /= 2.0;
if (amount > 0)
- for (i = 0; i < 4; i++)
+ for (i = 0; i < 3; i++)
{
- tmp = dest[i] + (gfloat) g_rand_double_range(gr, -amount, amount);
- dest[i] = CLAMP (tmp, 0, 1);
+ tmp = dest[i] + (gfloat) g_rand_double_range (gr, -amount, amount);
+ dest[i] = CLAMP (tmp, 0.0, 1.0);
}
}
@@ -118,17 +119,20 @@ put_pixel (PlasmaContext *context,
rect.width = 1;
rect.height = 1;
- gegl_buffer_set (context->output, &rect, 0, babl_format ("RGBA float"), pixel,
- GEGL_AUTO_ROWSTRIDE);
+ gegl_buffer_set (context->output, &rect, 0, babl_format ("R'G'B' float"),
+ pixel, GEGL_AUTO_ROWSTRIDE);
return;
}
else
{
float *ptr;
+ gint index;
- ptr = context->buffer + ((y - context->buffer_y) * 4 * context->buffer_width) + ((x -
context->buffer_x) * 4);
+ index = ((y - context->buffer_y) * context->buffer_width +
+ x - context->buffer_x);
+
+ ptr = context->buffer + index * 3;
- *ptr++ = *pixel++;
*ptr++ = *pixel++;
*ptr++ = *pixel++;
*ptr++ = *pixel++;
@@ -144,8 +148,8 @@ do_plasma (PlasmaContext *context,
gint plasma_depth,
gint recursion_depth)
{
- gfloat tl[4], ml[4], bl[4], mt[4], mm[4], mb[4], tr[4], mr[4], br[4];
- gfloat tmp[4];
+ gfloat tl[3], ml[3], bl[3], mt[3], mm[3], mb[3], tr[3], mr[3], br[3];
+ gfloat tmp[3];
gint xm, ym;
gfloat ran;
@@ -161,7 +165,7 @@ do_plasma (PlasmaContext *context,
rect.width = x2 - x1 + 1;
rect.height = y2 - y1 + 1;
- gegl_buffer_get (context->output, &rect, 1.0, babl_format ("RGBA float"),
+ gegl_buffer_get (context->output, &rect, 1.0, babl_format ("R'G'B' float"),
context->buffer, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
context->using_buffer = TRUE;
@@ -173,7 +177,7 @@ do_plasma (PlasmaContext *context,
context->using_buffer = FALSE;
- gegl_buffer_set (context->output, &rect, 0, babl_format ("RGBA float"),
+ gegl_buffer_set (context->output, &rect, 0, babl_format ("R'G'B' float"),
context->buffer, GEGL_AUTO_ROWSTRIDE);
return ret;
@@ -219,13 +223,17 @@ do_plasma (PlasmaContext *context,
if (x1 == x2 && y1 == y2)
return FALSE;
- gegl_buffer_sample (context->output, x1, y1, NULL, tl, babl_format ("RGBA float"),
+ gegl_buffer_sample (context->output, x1, y1, NULL, tl,
+ babl_format ("R'G'B' float"),
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- gegl_buffer_sample (context->output, x1, y2, NULL, bl, babl_format ("RGBA float"),
+ gegl_buffer_sample (context->output, x1, y2, NULL, bl,
+ babl_format ("R'G'B' float"),
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- gegl_buffer_sample (context->output, x2, y1, NULL, tr, babl_format ("RGBA float"),
+ gegl_buffer_sample (context->output, x2, y1, NULL, tr,
+ babl_format ("R'G'B' float"),
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
- gegl_buffer_sample (context->output, x2, y2, NULL, br, babl_format ("RGBA float"),
+ gegl_buffer_sample (context->output, x2, y2, NULL, br,
+ babl_format ("R'G'B' float"),
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
ran = context->o->turbulence / (2.0 * recursion_depth);
@@ -289,65 +297,58 @@ do_plasma (PlasmaContext *context,
/* Top right. */
do_plasma (context, xm, y1, x2, ym, plasma_depth - 1, recursion_depth + 1);
/* Bottom right. */
- return do_plasma (context, xm, ym, x2, y2, plasma_depth - 1, recursion_depth + 1);
+ return do_plasma (context, xm, ym, x2, y2,
+ plasma_depth - 1, recursion_depth + 1);
}
return TRUE;
}
-static GeglRectangle
-plasma_get_bounding_box (GeglOperation *operation)
+static void
+prepare (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;
+ gegl_operation_set_format (operation, "output", babl_format ("R'G'B' float"));
}
static gboolean
process (GeglOperation *operation,
- GeglBuffer *input,
GeglBuffer *output,
const GeglRectangle *result,
gint level)
{
PlasmaContext *context;
- GeglRectangle boundary;
- gint depth;
- gint x, y;
+ gint depth;
+ gint x, y;
context = g_new (PlasmaContext, 1);
context->o = GEGL_CHANT_PROPERTIES (operation);
context->output = output;
- context->buffer = g_malloc (TILE_SIZE * TILE_SIZE * 4 * sizeof (float));
+ context->buffer = g_malloc (TILE_SIZE * TILE_SIZE * 3 * sizeof (gfloat));
context->using_buffer = FALSE;
- boundary = plasma_get_bounding_box (operation);
-
/*
* The first time only puts seed pixels (corners, center of edges,
* center of image)
*/
- x = boundary.x + boundary.width;
- y = boundary.y + boundary.height;
+ x = result->x + result->width;
+ y = result->y + result->height;
if (context->o->seed == -1)
context->gr = g_rand_new ();
else
context->gr = g_rand_new_with_seed (context->o->seed);
- do_plasma (context, boundary.x, boundary.y, x-1, y-1, -1, 0);
+ do_plasma (context, result->x, result->y, x-1, y-1, -1, 0);
/*
* Now we recurse through the images, going deeper each time
*/
depth = 1;
- while (!do_plasma (context, boundary.x, boundary.y, x-1, y-1, depth, 0))
+ while (!do_plasma (context, result->x, result->y, x-1, y-1, depth, 0))
depth++;
gegl_buffer_sample_cleanup (context->output);
+ g_rand_free (context->gr);
g_free (context->buffer);
g_free (context);
@@ -355,32 +356,41 @@ process (GeglOperation *operation,
}
static GeglRectangle
+get_bounding_box (GeglOperation *operation)
+{
+ GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+
+ return *GEGL_RECTANGLE (0, 0, o->width, o->height);
+}
+
+static GeglRectangle
get_required_for_output (GeglOperation *operation,
const gchar *input_pad,
const GeglRectangle *roi)
{
- return *gegl_operation_source_get_bounding_box (operation, "input");
+ return get_bounding_box (operation);
}
static GeglRectangle
get_cached_region (GeglOperation *operation,
const GeglRectangle *roi)
{
- return *gegl_operation_source_get_bounding_box (operation, "input");
+ return get_bounding_box (operation);
}
static void
gegl_chant_class_init (GeglChantClass *klass)
{
GeglOperationClass *operation_class;
- GeglOperationFilterClass *filter_class;
+ GeglOperationSourceClass *source_class;
operation_class = GEGL_OPERATION_CLASS (klass);
- filter_class = GEGL_OPERATION_FILTER_CLASS (klass);
+ source_class = GEGL_OPERATION_SOURCE_CLASS (klass);
- filter_class->process = process;
+ source_class->process = process;
operation_class->prepare = prepare;
operation_class->get_required_for_output = get_required_for_output;
+ operation_class->get_bounding_box = get_bounding_box;
operation_class->get_cached_region = get_cached_region;
gegl_operation_class_set_keys (operation_class,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]