[gegl/next-API] fractal-explorer: enhance in modern GEGL way * produce float colors * produce color for infinite pla



commit 1e505e7569a3529679fe7d58af20bbe96ba3aac0
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]