[gegl] mean-curvature-blur: add new operation to common
- From: Thomas Manni <tmanni src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] mean-curvature-blur: add new operation to common
- Date: Tue, 13 Feb 2018 19:59:56 +0000 (UTC)
commit 08a5397a322c85d4c890002df1db6a73969c9e8c
Author: Thomas Manni <thomas manni free fr>
Date: Tue Feb 13 20:30:33 2018 +0100
mean-curvature-blur: add new operation to common
operations/common/Makefile.am | 7 +-
operations/common/mean-curvature-blur.c | 252 +++++++++++++++++++++++++++++++
po/POTFILES.in | 1 +
3 files changed, 257 insertions(+), 3 deletions(-)
---
diff --git a/operations/common/Makefile.am b/operations/common/Makefile.am
index 964b618..afe85bf 100644
--- a/operations/common/Makefile.am
+++ b/operations/common/Makefile.am
@@ -14,8 +14,8 @@ op_LTLIBRARIES = \
gegl-common.la
gegl_common_la_SOURCES =\
- module.c \
- alien-map.c \
+ module.c \
+ alien-map.c \
bilateral-filter.c \
box-blur.c \
brightness-contrast.c \
@@ -65,6 +65,7 @@ gegl_common_la_SOURCES =\
map-relative.c \
matting-global.c \
mblur.c \
+ mean-curvature-blur.c \
median-blur.c \
mirrors.c \
mix.c \
@@ -91,7 +92,7 @@ gegl_common_la_SOURCES =\
rectangle.c \
reinhard05.c \
remap.c \
- rgb-clip.c \
+ rgb-clip.c \
saturation.c \
save.c \
sepia.c \
diff --git a/operations/common/mean-curvature-blur.c b/operations/common/mean-curvature-blur.c
new file mode 100644
index 0000000..5fa5abe
--- /dev/null
+++ b/operations/common/mean-curvature-blur.c
@@ -0,0 +1,252 @@
+/* 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 2018 Thomas Manni <thomas manni free fr>
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#ifdef GEGL_PROPERTIES
+
+property_int (iterations, _("Iterations"), 20)
+ description (_("Controls the number of iterations"))
+ value_range (0, 500)
+ ui_range (0, 60)
+
+#else
+
+#define GEGL_OP_AREA_FILTER
+#define GEGL_OP_NAME mean_curvature_blur
+#define GEGL_OP_C_SOURCE mean-curvature-blur.c
+
+#define POW2(x) ((x)*(x))
+
+#include "gegl-op.h"
+#include <math.h>
+
+static void
+prepare (GeglOperation *operation)
+{
+ GeglOperationAreaFilter *area = GEGL_OPERATION_AREA_FILTER (operation);
+ GeglProperties *o = GEGL_PROPERTIES (operation);
+ const Babl *format = babl_format ("R'G'B'A float");
+
+ area->left = area->right = area->top = area->bottom = o->iterations;
+
+ gegl_operation_set_format (operation, "input", format);
+ gegl_operation_set_format (operation, "output", format);
+}
+
+static GeglRectangle
+get_bounding_box (GeglOperation *operation)
+{
+ GeglRectangle result = { 0, 0, 0, 0 };
+ GeglRectangle *in_rect;
+
+ in_rect = gegl_operation_source_get_bounding_box (operation, "input");
+ if (in_rect)
+ {
+ result = *in_rect;
+ }
+
+ return result;
+}
+
+static void
+mean_curvature_flow (gfloat *src_buf,
+ gint src_stride,
+ gfloat *dst_buf,
+ gint dst_width,
+ gint dst_height,
+ gint dst_stride)
+{
+ gint c;
+ gint x, y;
+ gfloat *center_pix;
+
+#define O(u,v) (((u)+((v) * src_stride)) * 4)
+ gint offsets[8] = { O( -1, -1), O(0, -1), O(1, -1),
+ O( -1, 0), O(1, 0),
+ O( -1, 1), O(0, 1), O(1, 1)};
+#undef O
+
+#define LEFT(c) ((center_pix + offsets[3])[c])
+#define RIGHT(c) ((center_pix + offsets[4])[c])
+#define TOP(c) ((center_pix + offsets[1])[c])
+#define BOTTOM(c) ((center_pix + offsets[6])[c])
+#define TOPLEFT(c) ((center_pix + offsets[0])[c])
+#define TOPRIGHT(c) ((center_pix + offsets[2])[c])
+#define BOTTOMLEFT(c) ((center_pix + offsets[5])[c])
+#define BOTTOMRIGHT(c) ((center_pix + offsets[7])[c])
+
+ for (y = 0; y < dst_height; y++)
+ {
+ gint dst_offset = dst_stride * y;
+ center_pix = src_buf + ((y+1) * src_stride + 1) * 4;
+
+ for (x = 0; x < dst_width; x++)
+ {
+ for (c = 0; c < 3; c++) /* do each color component individually */
+ {
+ gdouble dx = RIGHT(c) - LEFT(c);
+ gdouble dy = BOTTOM(c) - TOP(c);
+ gdouble magnitude = sqrt (POW2(dx) + POW2(dy));
+
+ dst_buf[dst_offset * 4 + c] = center_pix[c];
+
+ if (magnitude)
+ {
+ gdouble dx2 = POW2(dx);
+ gdouble dy2 = POW2(dy);
+
+ gdouble dxx = RIGHT(c) + LEFT(c) - 2. * center_pix[c];
+ gdouble dyy = BOTTOM(c) + TOP(c) - 2. * center_pix[c];
+ gdouble dxy = 0.25 * (BOTTOMRIGHT(c) - TOPRIGHT(c) - BOTTOMLEFT(c) + TOPLEFT(c));
+
+ gdouble n = dx2 * dyy + dy2 * dxx - 2. * dx * dy * dxy;
+ gdouble d = sqrt (pow (dx2 + dy2, 3.));
+ gdouble mean_curvature = n / d;
+
+ dst_buf[dst_offset * 4 + c] += (0.25 * magnitude * mean_curvature);
+ }
+ }
+
+ dst_buf[dst_offset * 4 + 3] = center_pix[3];
+
+ dst_offset++;
+ center_pix += 4;
+ }
+ }
+
+#undef LEFT
+#undef RIGHT
+#undef TOP
+#undef BOTTOM
+#undef TOPLEFT
+#undef TOPRIGHT
+#undef BOTTOMLEFT
+#undef BOTTOMRIGHT
+
+}
+
+static gboolean
+process (GeglOperation *operation,
+ GeglBuffer *input,
+ GeglBuffer *output,
+ const GeglRectangle *roi,
+ gint level)
+{
+ GeglProperties *o = GEGL_PROPERTIES (operation);
+ const Babl *format = babl_format ("R'G'B'A float");
+
+ gint iteration;
+ gint stride;
+ gfloat *src_buf;
+ gfloat *dst_buf;
+ GeglRectangle rect;
+
+ rect = *roi;
+
+ rect.x -= o->iterations;
+ rect.y -= o->iterations;
+ rect.width += o->iterations*2;
+ rect.height += o->iterations*2;
+
+ stride = roi->width + o->iterations * 2;
+
+ src_buf = g_new (gfloat,
+ (stride) * (roi->height + o->iterations * 2) * 4);
+
+ dst_buf = g_new0 (gfloat,
+ (stride) * (roi->height + o->iterations * 2) * 4);
+
+ gegl_buffer_get (input, &rect, 1.0, format, src_buf, stride * 4 * 4,
+ GEGL_ABYSS_CLAMP);
+
+ for (iteration = 0; iteration < o->iterations; iteration++)
+ {
+ mean_curvature_flow (src_buf, stride,
+ dst_buf,
+ roi->width + (o->iterations - 1 - iteration) * 2,
+ roi->height + (o->iterations - 1 - iteration) * 2,
+ stride);
+
+ { /* swap buffers */
+ gfloat *tmp = src_buf;
+ src_buf = dst_buf;
+ dst_buf = tmp;
+ }
+ }
+
+ gegl_buffer_set (output, roi, 0, format, src_buf, stride * 4 * 4);
+
+ g_free (src_buf);
+ g_free (dst_buf);
+
+ return TRUE;
+}
+
+/* Pass-through when iterations parameter is set to zero */
+
+static gboolean
+operation_process (GeglOperation *operation,
+ GeglOperationContext *context,
+ const gchar *output_prop,
+ const GeglRectangle *result,
+ gint level)
+{
+ GeglOperationClass *operation_class;
+ GeglProperties *o = GEGL_PROPERTIES (operation);
+
+ operation_class = GEGL_OPERATION_CLASS (gegl_op_parent_class);
+
+ if (! o->iterations)
+ {
+ gpointer in = gegl_operation_context_get_object (context, "input");
+ gegl_operation_context_take_object (context, "output",
+ g_object_ref (G_OBJECT (in)));
+ return TRUE;
+ }
+
+ return operation_class->process (operation, context, output_prop, result,
+ gegl_operation_context_get_level (context));
+}
+
+static void
+gegl_op_class_init (GeglOpClass *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->process = operation_process;
+ operation_class->prepare = prepare;
+ operation_class->get_bounding_box = get_bounding_box;
+ operation_class->opencl_support = FALSE;
+
+ gegl_operation_class_set_keys (operation_class,
+ "name", "gegl:mean-curvature-blur",
+ "title", _("Mean Curvature Blur"),
+ "categories", "blur",
+ "reference-hash", "8856d371c39a439e501dc2f2a74d6417",
+ "description", _("Regularize geometry at a speed proportional to the local mean curvature value"),
+ NULL);
+}
+
+#endif
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3a1122f..efd7bde 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -56,6 +56,7 @@ operations/common/map-absolute.c
operations/common/map-relative.c
operations/common/matting-global.c
operations/common/mblur.c
+operations/common/mean-curvature-blur.c
operations/common/median-blur.c
operations/common/mirrors.c
operations/common/mix.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]