[gegl/soc-2011-ops] Added the fractal-trace op
- From: Robert Sasu <sasurobert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/soc-2011-ops] Added the fractal-trace op
- Date: Mon, 20 Jun 2011 12:01:47 +0000 (UTC)
commit 87b8274c450434b51f3784e0a1a32ab8db145219
Author: Robert Sasu <sasu robert gmail com>
Date: Mon Jun 20 15:01:17 2011 +0300
Added the fractal-trace op
operations/workshop/fractal-trace.c | 288 +++++++++++++++++++++++++++++++++++
1 files changed, 288 insertions(+), 0 deletions(-)
---
diff --git a/operations/workshop/fractal-trace.c b/operations/workshop/fractal-trace.c
new file mode 100644
index 0000000..b698633
--- /dev/null
+++ b/operations/workshop/fractal-trace.c
@@ -0,0 +1,288 @@
+/* This file is an image processing operation for GEGL
+ *
+ * GEGL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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 2011 Robert Sasu <sasu robert gmail com>
+ *
+ * Based on "Fractal-trace" GIMP plugin
+ * Copyright (C) 1997 Hirotsuna Mizuno
+ * s1041150 u-aizu ac jp
+ */
+
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#ifdef GEGL_CHANT_PROPERTIES
+
+gegl_chant_double (X1, _("X1"), -50.0, 50.0, -1.00,
+ _("X1 value, position"))
+gegl_chant_double (X2, _("X2"), -50.0, 50.0, 0.50,
+ _("X2 value, position"))
+gegl_chant_double (Y1, _("Y1"), -50.0, 50.0, -1.00,
+ _("X2 value, position"))
+gegl_chant_double (Y2, _("Y2"), -50.0, 50.0, 1.00,
+ _("Y2 value, position"))
+gegl_chant_int (depth, _("Depth"), 1, 50, 3,
+ _("Depth value"))
+gegl_chant_string (background, _("Background"), "wrap",
+ _("Optional parameter to override automatic selection of wrap background. "
+ "Choices are wrap, black, white and transparent"))
+
+# else
+
+#define GEGL_CHANT_TYPE_FILTER
+
+#define GEGL_CHANT_C_FILE "fractal-trace.c"
+
+#include "gegl-chant.h"
+#include <math.h>
+#include <stdio.h>
+
+enum
+{
+ OUTSIDE_TYPE_WRAP,
+ OUTSIDE_TYPE_TRANSPARENT,
+ OUTSIDE_TYPE_BLACK,
+ OUTSIDE_TYPE_WHITE,
+};
+
+
+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
+mandelbrot (gdouble x,
+ gdouble y,
+ gdouble *u,
+ gdouble *v,
+ gint depth)
+{
+ gint i;
+ gdouble xx = x;
+ gdouble yy = y;
+
+ for (i = 0; i < depth; i++)
+ {
+ gdouble x2, y2, tmp;
+
+ x2 = xx * xx;
+ y2 = yy * yy;
+ tmp = x2 - y2 + x;
+ yy = 2 * xx * yy + y;
+ xx = tmp;
+ }
+
+ *u = xx;
+ *v = yy;
+}
+
+static void
+fractaltrace (GeglBuffer *input,
+ const GeglRectangle *picture,
+ gfloat *dst_buf,
+ const GeglRectangle *roi,
+ GeglChantO *o,
+ gint y,
+ gint id,
+ Babl *format
+ )
+{
+ gint x, i, offset;
+ gdouble scale_x, scale_y;
+ gdouble cx, cy;
+ gdouble px, py;
+ gfloat dest[4];
+
+ scale_x = (gdouble) (o->X2 - o->X1) / (gdouble) picture->width;
+ scale_y = (gdouble) (o->Y2 - o->Y1) / (gdouble) picture->height;
+
+ cy = (gdouble) o->Y1 + ((gdouble) (y - picture->y)) * scale_y;
+ offset = (y - roi->y) * roi->width * 4;
+
+ for (x = roi->x; x < roi->x + roi->width; x++)
+ {
+ dest[1] = dest[2] = dest[3] = dest[0] = 0.0;
+ cx = o->X1 + (x - picture->x) * scale_x;
+ mandelbrot (cx, cy, &px, &py, o->depth);
+ px = (px - o->X1) / scale_x + picture->x;
+ py = (py - o->Y1) / scale_y + picture->y;
+
+ if (0 <= px && px < picture->width && 0 <= py && py < picture->height)
+ {
+ gegl_buffer_sample (input, px, py, 1.0, dest, format,
+ GEGL_INTERPOLATION_LINEAR);
+ }
+ else
+ {
+ switch (id)
+ {
+ case 0:
+ px = fmod (px, picture->width);
+ py = fmod (py, picture->height);
+ if (px < 0.0) px += picture->width;
+ if (py < 0.0) py += picture->height;
+ /*associating to NaN and -NaN values, if there is the case*/
+
+ if (isnan(px))
+ {
+ if (signbit(px))
+ {
+ px = 0.0;
+ }
+ else
+ {
+ px = (gdouble) picture->width - 1.0;
+ }
+ }
+
+ if (isnan(py))
+ {
+ if (signbit(py))
+ {
+ py = 0.0;
+ }
+ else
+ {
+ py = (gdouble) picture->height -1.0;
+ }
+ }
+
+ gegl_buffer_sample (input, px, py, 1.0, dest, format,
+ GEGL_INTERPOLATION_LINEAR);
+ break;
+ case 1:
+ dest[0] = dest[1] = dest[2] = dest[3] = 0.0;
+ break;
+ case 2:
+ dest[0] = dest[1] = dest[2] = 0.0;
+ dest[3] = 1.0;
+ break;
+ case 3:
+ dest[0] = dest[1] = dest[2] = dest[3] = 1.0;
+ break;
+ }
+ }
+ /*upload pixel value is destination buffer*/
+ for(i = 0;i < 4; i++)
+ dst_buf[offset++] = dest[i];
+ }
+}
+
+
+static gboolean
+process (GeglOperation *operation,
+ GeglBuffer *input,
+ GeglBuffer *output,
+ const GeglRectangle *result)
+{
+ GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+ GeglRectangle boundary = gegl_operation_get_bounding_box (operation);
+ Babl *format = babl_format ("RGBA float");
+
+ gint y,id;
+ gfloat *dst_buf;
+
+ id = 0; /*wrap is default*/
+ if (!strcmp(o->background,"wrap")) id = 0;
+ else if (!strcmp(o->background,"transparent")) id = 1;
+ else if (!strcmp(o->background,"black")) id = 2;
+ else if (!strcmp(o->background,"white")) id = 3;
+
+ dst_buf = g_new0 (gfloat, result->width * result->height * 4);
+
+ for (y = result->y; y < result->y + result->height; y++)
+ fractaltrace(input, &boundary, dst_buf, result, o, y, id, format);
+
+ gegl_buffer_set (output, result, format, dst_buf, GEGL_AUTO_ROWSTRIDE);
+
+ g_free (dst_buf);
+
+ return TRUE;
+}
+
+static GeglRectangle
+get_effective_area (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 GeglRectangle
+get_bounding_box (GeglOperation *operation)
+{
+ GeglRectangle result = {0,0,0,0};
+ GeglRectangle *in_rect = gegl_operation_source_get_bounding_box (operation, "input");
+
+ if (!in_rect){
+ return result;
+ }
+
+ gegl_rectangle_copy(&result, in_rect);
+
+ #ifdef TRACE
+ g_warning ("< get_bounding_box result = %dx%d+%d+%d", result.width, result.height, result.x, result.y);
+ #endif
+ return result;
+}
+
+
+/* Compute the input rectangle required to compute the specified region of interest (roi).
+ */
+static GeglRectangle
+get_required_for_output (GeglOperation *operation,
+ const gchar *input_pad,
+ const GeglRectangle *roi)
+{
+ GeglRectangle result = get_effective_area (operation);
+
+ #ifdef TRACE
+ g_warning ("> get_required_for_output src=%dx%d+%d+%d", result.width, result.height, result.x, result.y);
+ if (roi)
+ g_warning (" ROI == %dx%d+%d+%d", roi->width, roi->height, roi->x, roi->y);
+ #endif
+
+ return result;
+}
+
+
+static void
+gegl_chant_class_init (GeglChantClass *klass)
+{
+ GeglOperationClass *operation_class;
+ GeglOperationFilterClass *filter_class;
+
+ operation_class = GEGL_OPERATION_CLASS (klass);
+ filter_class = GEGL_OPERATION_FILTER_CLASS (klass);
+
+ filter_class->process = process;
+ operation_class->prepare = prepare;
+ operation_class->get_bounding_box = get_bounding_box;
+ operation_class->get_required_for_output = get_required_for_output;
+
+ operation_class->categories = "map";
+ operation_class->name = "gegl:fractal-trace";
+ operation_class->description =
+ _("Performs fractal trace on the image");
+}
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]