[gegl/next-API: 6/7] fractal-explorer: enhance in modern GEGL way * produce float colors * produce color for infinite pla
- From: Michael Murà <mmure src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/next-API: 6/7] fractal-explorer: enhance in modern GEGL way * produce float colors * produce color for infinite pla
- Date: Mon, 18 Jun 2012 12:09:44 +0000 (UTC)
commit 72844095e5ee07f5e6a5fb31879a83ed80289433
Author: Michael Murà <batolettre gmail com>
Date: Fri Jun 8 22:33:46 2012 +0900
fractal-explorer: enhance in modern GEGL way
* produce float colors
* produce color for infinite plane
* inherit from point-renderer for speed
* cleaning
operations/common/fractal-explorer.c | 458 +++++++++++++++-------------------
1 files changed, 196 insertions(+), 262 deletions(-)
---
diff --git a/operations/common/fractal-explorer.c b/operations/common/fractal-explorer.c
index 8e6a5e4..a330222 100644
--- a/operations/common/fractal-explorer.c
+++ b/operations/common/fractal-explorer.c
@@ -27,11 +27,6 @@
#ifdef GEGL_CHANT_PROPERTIES
-gegl_chant_int_ui (width, _("Width"), 1, 10000000, 400, 1, 2000, 1.5,
- _("Width"))
-gegl_chant_int_ui (height, _("Height"), 1, 10000000, 400, 1, 2000, 1.5,
- _("Height"))
-
gegl_chant_register_enum (gegl_fractal_explorer_type)
enum_value (GEGl_FRACTAL_EXPLORER_TYPE_MANDELBROT, "Mandelbrot")
enum_value (GEGl_FRACTAL_EXPLORER_TYPE_JULIA, "Julia")
@@ -48,11 +43,6 @@ gegl_chant_enum (fractaltype, _("Fractal type"), GeglFractalExplorerType,
gegl_fractal_explorer_type, GEGl_FRACTAL_EXPLORER_TYPE_MANDELBROT,
_("Type of a fractal"))
-gegl_chant_double (xmin, _("Left"), -3.0, 3.0, -2.0, _("Left"))
-gegl_chant_double (xmax, _("Right"), -3.0, 3.0, 2.0, _("Right"))
-gegl_chant_double (ymin, _("Top"), -3.0, 3.0, -2.0, _("Top"))
-gegl_chant_double (ymax, _("Bottom"), -3.0, 3.0, 2.0, _("Bottom"))
-
gegl_chant_int (iter, _("Iterations"), 1, 1000, 50, _("Iterations"))
gegl_chant_double (cx, _("CX"), -2.5, 2.5, -0.75, _("CX (No effect in Mandelbrot and Sierpinski)"))
@@ -96,7 +86,7 @@ gegl_chant_boolean (useloglog, _("Loglog smoothing"), FALSE,
#else
-#define GEGL_CHANT_TYPE_SOURCE
+#define GEGL_CHANT_TYPE_POINT_RENDER
#define GEGL_CHANT_C_FILE "fractal-explorer.c"
#include "gegl-chant.h"
@@ -105,337 +95,284 @@ gegl_chant_boolean (useloglog, _("Loglog smoothing"), FALSE,
typedef struct
{
- guchar r, g, b;
-} gucharRGB;
+ gfloat r, g, b;
+} gfloatRGB;
+
+typedef gfloatRGB clrmap[MAXNCOLORS];
-typedef gucharRGB clrmap[MAXNCOLORS];
+static void
+make_color_map (GeglChantO *o, clrmap colormap)
+{
+ gint i;
+ gfloat r;
+ gfloat gr;
+ gfloat bl;
+
+ for (i = 0; i < o->ncolors; i++)
+ {
+ double x = (i*2.0) / o->ncolors;
+ r = gr = bl = 0;
+
+ switch (o->redmode)
+ {
+ case GEGl_FRACTAL_EXPLORER_MODE_SIN:
+ r = 0.5 * o->redstretch *(1.0 + sin((x - 1) * G_PI));
+ break;
+ case GEGl_FRACTAL_EXPLORER_MODE_COS:
+ r = 0.5 * o->redstretch *(1.0 + cos((x - 1) * G_PI));
+ break;
+ case GEGl_FRACTAL_EXPLORER_MODE_NONE:
+ r = 0.5 * o->redstretch * x;
+ break;
+ default:
+ break;
+ }
+ switch (o->greenmode)
+ {
+ case GEGl_FRACTAL_EXPLORER_MODE_SIN:
+ gr = 0.5 * o->greenstretch *(1.0 + sin((x - 1) * G_PI));
+ break;
+ case GEGl_FRACTAL_EXPLORER_MODE_COS:
+ gr = 0.5 * o->greenstretch *(1.0 + cos((x - 1) * G_PI));
+ break;
+ case GEGl_FRACTAL_EXPLORER_MODE_NONE:
+ gr = 0.5 * o->greenstretch * x;
+ break;
+ default:
+ break;
+ }
+
+ switch (o->bluemode)
+ {
+ case GEGl_FRACTAL_EXPLORER_MODE_SIN:
+ bl = 0.5 * o->bluestretch * (1.0 + sin ((x - 1) * G_PI));
+ break;
+ case GEGl_FRACTAL_EXPLORER_MODE_COS:
+ bl = 0.5 * o->bluestretch * (1.0 + cos ((x - 1) * G_PI));
+ break;
+ case GEGl_FRACTAL_EXPLORER_MODE_NONE:
+ bl = 0.5 * o->bluestretch * x;
+ break;
+ default:
+ break;
+ }
+
+ if (o->redinvert)
+ r = 1.0 - r;
+
+ if (o->greeninvert)
+ gr = 1.0 - gr;
+
+ if (o->blueinvert)
+ bl = 1.0 - bl;
+
+ colormap[i].r = r;
+ colormap[i].g = gr;
+ colormap[i].b = bl;
+ }
+}
static void
-explorer_render_row (GeglChantO *o,
- gint col_start,
- gint col_end,
- gint row,
- clrmap colormap,
- guchar **dest_row)
+prepare (GeglOperation *operation)
{
- gint col;
- gdouble a;
- gdouble b;
- gdouble x;
- gdouble y;
- gdouble oldx;
- gdouble oldy;
- gdouble tempsqrx;
- gdouble tempsqry;
- gdouble tmpx = 0;
- gdouble tmpy = 0;
- gdouble foldxinitx;
- gdouble foldxinity;
- gdouble foldyinitx;
- gdouble foldyinity;
- gdouble xx = 0;
- gdouble adjust;
- gint counter;
- gint color;
- gdouble xdiff;
- gdouble ydiff;
- gdouble log2;
-
- log2 = log (2.0);
-
- xdiff = (o->xmax - o->xmin) / o->width;
- ydiff = (o->ymax - o->ymin) / o->height;
-
- for (col = col_start; col < col_end; col++)
+ gegl_operation_set_format (operation, "output", babl_format ("RGBA float"));
+}
+
+static GeglRectangle
+get_bounding_box (GeglOperation *operation)
+{
+ return gegl_rectangle_infinite_plane ();
+}
+
+static gboolean
+process (GeglOperation *operation,
+ void *out_buf,
+ glong n_pixels,
+ const GeglRectangle *roi,
+ gint level)
+{
+ GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+ gfloat *out_pixel = out_buf;
+ gint pixelx = roi->x; /* initial x */
+ gint pixely = roi->y; /* and y coordinates */
+ gdouble x,y; /* coordinate in fractal space */
+ gdouble a,b; /* main fractal variable in iteration loop */
+ gdouble nexta;
+ gdouble tmpx, tmpy;
+ gdouble foldxinitx;
+ gdouble foldxinity;
+ gdouble foldyinitx;
+ gdouble foldyinity;
+ gdouble tempsqrx;
+ gdouble tempsqry;
+ gdouble olda,oldb;
+ gdouble adjust = 0.0;
+ gint counter; /* iteration counter */
+ gdouble log2 = log (2.0);
+ gint color;
+
+ clrmap colormap;
+
+ make_color_map (o, colormap);
+
+ while (n_pixels--)
{
- a = o->xmin + (gdouble) col * xdiff;
- b = o->ymin + (gdouble) row * ydiff;
- if (o->fractaltype != GEGl_FRACTAL_EXPLORER_TYPE_MANDELBROT)
+ x = pixelx / 400.0; /* room for moving in the fractal space */
+ y = pixely / 400.0;
+
+ if (o->fractaltype == GEGl_FRACTAL_EXPLORER_TYPE_MANDELBROT)
{
- tmpx = x = a;
- tmpy = y = b;
+ a = b = 0;
}
else
{
- x = 0;
- y = 0;
+ tmpx = a = x;
+ tmpy = b = y;
}
for (counter = 0; counter < o->iter; counter++)
{
- oldx=x;
- oldy=y;
+ olda = a;
+ oldb = b;
switch (o->fractaltype)
{
case GEGl_FRACTAL_EXPLORER_TYPE_MANDELBROT:
- xx = x * x - y * y + a;
- y = 2.0 * x * y + b;
+ nexta = a * a - b * b + x;
+ b = 2.0 * a * b + y;
break;
case GEGl_FRACTAL_EXPLORER_TYPE_JULIA:
- xx = x * x - y * y + o->cx;
- y = 2.0 * x * y + o->cy;
+ nexta = a * a - b * b + o->cx;
+ b = 2.0 * a * b + o->cy;
break;
case GEGl_FRACTAL_EXPLORER_TYPE_BARNSLEY_1:
- foldxinitx = oldx * o->cx;
- foldyinity = oldy * o->cy;
- foldxinity = oldx * o->cy;
- foldyinitx = oldy * o->cx;
+ foldxinitx = olda * o->cx;
+ foldyinity = oldb * o->cy;
+ foldxinity = olda * o->cy;
+ foldyinitx = oldb * o->cx;
/* orbit calculation */
- if (oldx >= 0)
+ if (olda >= 0)
{
- xx = (foldxinitx - o->cx - foldyinity);
- y = (foldyinitx - o->cy + foldxinity);
+ nexta = (foldxinitx - o->cx - foldyinity);
+ b = (foldyinitx - o->cy + foldxinity);
}
else
{
- xx = (foldxinitx + o->cx - foldyinity);
- y = (foldyinitx + o->cy + foldxinity);
+ nexta = (foldxinitx + o->cx - foldyinity);
+ b = (foldyinitx + o->cy + foldxinity);
}
break;
case GEGl_FRACTAL_EXPLORER_TYPE_BARNSLEY_2:
- foldxinitx = oldx * o->cx;
- foldyinity = oldy * o->cy;
- foldxinity = oldx * o->cy;
- foldyinitx = oldy * o->cx;
+ foldxinitx = olda * o->cx;
+ foldyinity = oldb * o->cy;
+ foldxinity = olda * o->cy;
+ foldyinitx = oldb * o->cx;
/* orbit calculation */
if (foldxinity + foldyinitx >= 0)
{
- xx = foldxinitx - o->cx - foldyinity;
- y = foldyinitx - o->cy + foldxinity;
+ nexta = foldxinitx - o->cx - foldyinity;
+ b = foldyinitx - o->cy + foldxinity;
}
else
{
- xx = foldxinitx + o->cx - foldyinity;
- y = foldyinitx + o->cy + foldxinity;
+ nexta = foldxinitx + o->cx - foldyinity;
+ b = foldyinitx + o->cy + foldxinity;
}
break;
case GEGl_FRACTAL_EXPLORER_TYPE_BARNSLEY_3:
- foldxinitx = oldx * oldx;
- foldyinity = oldy * oldy;
- foldxinity = oldx * oldy;
+ foldxinitx = olda * olda;
+ foldyinity = oldb * oldb;
+ foldxinity = olda * oldb;
/* orbit calculation */
- if (oldx > 0)
+ if (olda > 0)
{
- xx = foldxinitx - foldyinity - 1.0;
- y = foldxinity * 2;
+ nexta = foldxinitx - foldyinity - 1.0;
+ b = foldxinity * 2;
}
else
{
- xx = foldxinitx - foldyinity -1.0 + o->cx * oldx;
- y = foldxinity * 2;
- y += o->cy * oldx;
+ nexta = foldxinitx - foldyinity -1.0 + o->cx * olda;
+ b = foldxinity * 2;
+ b += o->cy * olda;
}
break;
case GEGl_FRACTAL_EXPLORER_TYPE_SPIDER:
/* { c=z=pixel: z=z*z+c; c=c/2+z, |z|<=4 } */
- xx = x*x - y*y + tmpx + o->cx;
- y = 2 * oldx * oldy + tmpy + o->cy;
- tmpx = tmpx/2 + xx;
- tmpy = tmpy/2 + y;
+ nexta = a*a - b*b + tmpx + o->cx;
+ b = 2 * olda * oldb + tmpy + o->cy;
+ tmpx = tmpx/2 + nexta;
+ tmpy = tmpy/2 + b;
break;
case GEGl_FRACTAL_EXPLORER_TYPE_MAN_O_WAR:
- xx = x*x - y*y + tmpx + o->cx;
- y = 2.0 * x * y + tmpy + o->cy;
- tmpx = oldx;
- tmpy = oldy;
+ nexta = a*a - b*b + tmpx + o->cx;
+ b = 2.0 * a * b + tmpy + o->cy;
+ tmpx = olda;
+ tmpy = oldb;
break;
case GEGl_FRACTAL_EXPLORER_TYPE_LAMBDA:
- tempsqrx = x * x;
- tempsqry = y * y;
- tempsqrx = oldx - tempsqrx + tempsqry;
- tempsqry = -(oldy * oldx);
- tempsqry += tempsqry + oldy;
- xx = o->cx * tempsqrx - o->cy * tempsqry;
- y = o->cx * tempsqry + o->cy * tempsqrx;
+ tempsqrx = a * a;
+ tempsqry = b * b;
+ tempsqrx = olda - tempsqrx + tempsqry;
+ tempsqry = -(oldb * olda);
+ tempsqry += tempsqry + oldb;
+ nexta = o->cx * tempsqrx - o->cy * tempsqry;
+ b = o->cx * tempsqry + o->cy * tempsqrx;
break;
case GEGl_FRACTAL_EXPLORER_TYPE_SIERPINSKI:
- xx = oldx + oldx;
- y = oldy + oldy;
- if (oldy > .5)
- y = y - 1;
- else if (oldx > .5)
- xx = xx - 1;
+ nexta = olda + olda;
+ b = oldb + oldb;
+ if (oldb > .5)
+ b = b - 1;
+ else if (olda > .5)
+ nexta = nexta - 1;
break;
default:
break;
}
- x = xx;
+ a = nexta;
- if (((x * x) + (y * y)) >= 4.0)
+ if (((a * a) + (b * b)) >= 4.0)
break;
}
if (o->useloglog)
{
- gdouble modulus_square = (x * x) + (y * y);
+ gdouble modulus_square = (a * a) + (b * b);
if (modulus_square > (G_E * G_E))
adjust = log (log (modulus_square) / 2.0) / log2;
else
adjust = 0.0;
}
- else
- {
- adjust = 0.0;
- }
color = (gint) (((counter - adjust) * (o->ncolors - 1)) / o->iter);
- (*dest_row)[0] = colormap[color].r;
- (*dest_row)[1] = colormap[color].g;
- (*dest_row)[2] = colormap[color].b;
- (*dest_row) += 3;
- }
-}
-
-static void
-make_color_map (GeglChantO *o, clrmap colormap)
-{
- gint i;
- gint r;
- gint gr;
- gint bl;
- gdouble redstretch;
- gdouble greenstretch;
- gdouble bluestretch;
- gdouble pi = atan (1) * 4;
-
- redstretch = o->redstretch * 127.5;
- greenstretch = o->greenstretch * 127.5;
- bluestretch = o->bluestretch * 127.5;
-
- for (i = 0; i < o->ncolors; i++)
- {
- double x = (i*2.0) / o->ncolors;
- r = gr = bl = 0;
-
- switch (o->redmode)
- {
- case GEGl_FRACTAL_EXPLORER_MODE_SIN:
- r = (int) redstretch *(1.0 + sin((x - 1) * pi));
- break;
- case GEGl_FRACTAL_EXPLORER_MODE_COS:
- r = (int) redstretch *(1.0 + cos((x - 1) * pi));
- break;
- case GEGl_FRACTAL_EXPLORER_MODE_NONE:
- r = (int)(redstretch *(x));
- break;
- default:
- break;
- }
+ out_pixel[0] = colormap[color].r;
+ out_pixel[1] = colormap[color].g;
+ out_pixel[2] = colormap[color].b;
+ out_pixel[3] = 1.0;
- switch (o->greenmode)
- {
- case GEGl_FRACTAL_EXPLORER_MODE_SIN:
- gr = (int) greenstretch *(1.0 + sin((x - 1) * pi));
- break;
- case GEGl_FRACTAL_EXPLORER_MODE_COS:
- gr = (int) greenstretch *(1.0 + cos((x - 1) * pi));
- break;
- case GEGl_FRACTAL_EXPLORER_MODE_NONE:
- gr = (int)(greenstretch *(x));
- break;
- default:
- break;
- }
+ out_pixel += 4;
- switch (o->bluemode)
+ /* update x and y coordinates */
+ pixelx++;
+ if (pixelx>=roi->x + roi->width)
{
- case GEGl_FRACTAL_EXPLORER_MODE_SIN:
- bl = (int) bluestretch * (1.0 + sin ((x - 1) * pi));
- break;
- case GEGl_FRACTAL_EXPLORER_MODE_COS:
- bl = (int) bluestretch * (1.0 + cos ((x - 1) * pi));
- break;
- case GEGl_FRACTAL_EXPLORER_MODE_NONE:
- bl = (int) (bluestretch * x);
- break;
- default:
- break;
+ pixelx=roi->x;
+ pixely++;
}
-
- r = MIN (r, 255);
- gr = MIN (gr, 255);
- bl = MIN (bl, 255);
-
- if (o->redinvert)
- r = 255 - r;
-
- if (o->greeninvert)
- gr = 255 - gr;
-
- if (o->blueinvert)
- bl = 255 - bl;
-
- colormap[i].r = r;
- colormap[i].g = gr;
- colormap[i].b = bl;
}
-}
-
-static void
-prepare (GeglOperation *operation)
-{
- gegl_operation_set_format (operation, "output", babl_format ("R'G'B' u8"));
-}
-
-static GeglRectangle
-get_bounding_box (GeglOperation *operation)
-{
- GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
- GeglRectangle result = {0,0,0,0};
-
- result.width = o->width;
- result.height = o->height;
-
- return result;
-}
-
-static gboolean
-process (GeglOperation *operation,
- GeglBuffer *output,
- const GeglRectangle *result,
- gint level)
-{
- GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
- clrmap colormap;
- guchar *buf;
- gint pxsize;
-
- make_color_map (o, colormap);
-
- g_object_get (output, "px-size", &pxsize, NULL);
-
- buf = g_new (guchar, result->width * result->height * pxsize);
- {
- guchar *dst=buf;
- gint y;
- for (y=0; y < result->height; y++)
- {
- explorer_render_row (o,
- result->x,
- result->x + result->width ,
- result->y + y,
- colormap,
- &dst);
- }
- }
-
- gegl_buffer_set (output, NULL, 0, babl_format ("R'G'B' u8"), buf,
- GEGL_AUTO_ROWSTRIDE);
- g_free (buf);
return TRUE;
}
@@ -444,13 +381,13 @@ process (GeglOperation *operation,
static void
gegl_chant_class_init (GeglChantClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationSourceClass *source_class;
+ GeglOperationClass *operation_class;
+ GeglOperationPointRenderClass *point_render_class;
- operation_class = GEGL_OPERATION_CLASS (klass);
- source_class = GEGL_OPERATION_SOURCE_CLASS (klass);
+ operation_class = GEGL_OPERATION_CLASS (klass);
+ point_render_class = GEGL_OPERATION_POINT_RENDER_CLASS (klass);
- source_class->process = process;
+ point_render_class->process = process;
operation_class->get_bounding_box = get_bounding_box;
operation_class->prepare = prepare;
@@ -459,9 +396,6 @@ gegl_chant_class_init (GeglChantClass *klass)
"categories" , "render",
"description", _("Fractal Explorer"),
NULL);
-
- operation_class->no_cache = TRUE;
- operation_class->get_cached_region = NULL;
}
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]