[gegl] operations: add the tile-seamless operation



commit d4e63b42ba596101ce38f84ce7bbc8e95bf66209
Author: Téo Mazars <teo mazars ensimag fr>
Date:   Sun Jul 28 14:51:29 2013 +0200

    operations: add the tile-seamless operation

 operations/common/tile-seamless.c |  171 +++++++++++++++++++++++++++++++++++++
 po/POTFILES.in                    |    1 +
 2 files changed, 172 insertions(+), 0 deletions(-)
---
diff --git a/operations/common/tile-seamless.c b/operations/common/tile-seamless.c
new file mode 100644
index 0000000..240b50a
--- /dev/null
+++ b/operations/common/tile-seamless.c
@@ -0,0 +1,171 @@
+/* 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/>.
+ *
+ * Original author:
+ *     Tim Rowley <tor cs brown edu>
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#ifdef GEGL_CHANT_PROPERTIES
+
+#else
+
+#define GEGL_CHANT_TYPE_FILTER
+#define GEGL_CHANT_C_FILE "tile-seamless.c"
+
+#include "gegl-chant.h"
+#include <math.h>
+
+
+static void
+prepare (GeglOperation *operation)
+{
+  gegl_operation_set_format (operation, "input",
+                             babl_format ("R'G'B'A float"));
+  gegl_operation_set_format (operation, "output",
+                             babl_format ("R'G'B'A float"));
+}
+
+static gboolean
+process (GeglOperation       *operation,
+         GeglBuffer          *input,
+         GeglBuffer          *output,
+         const GeglRectangle *result,
+         gint                 level)
+{
+  const GeglRectangle *whole_region;
+  GeglRectangle        shift_region;
+  GeglBufferIterator  *gi;
+  gint                 half_width;
+  gint                 half_height;
+  gint                 index_iter;
+  gint                 index_iter2;
+
+  whole_region = gegl_operation_source_get_bounding_box (operation, "input");
+
+  half_width  = whole_region->width / 2;
+  half_height = whole_region->height / 2;
+
+  shift_region.x = whole_region->x + half_width;
+  shift_region.y = whole_region->y + half_height;
+  shift_region.width  = whole_region->width;
+  shift_region.height = whole_region->height;
+
+  gi = gegl_buffer_iterator_new (output, whole_region,
+                                 0, babl_format ("R'G'B'A float"),
+                                 GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
+
+  index_iter = gegl_buffer_iterator_add (gi, input, whole_region,
+                                         0, babl_format ("R'G'B'A float"),
+                                         GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
+
+  index_iter2 = gegl_buffer_iterator_add (gi, input, &shift_region,
+                                          0, babl_format ("R'G'B'A float"),
+                                          GEGL_BUFFER_READ, GEGL_ABYSS_LOOP);
+
+  while (gegl_buffer_iterator_next (gi))
+    {
+      guint   k;
+      gfloat *data_out;
+      gfloat *data_in1;
+      gfloat *data_in2;
+
+      data_out = (gfloat*) gi->data[0];
+      data_in1 = (gfloat*) gi->data[index_iter];
+      data_in2 = (gfloat*) gi->data[index_iter2];
+
+      for (k = 0; k < gi->length; k++)
+        {
+          gint x, y, b;
+          gfloat alpha;
+          gfloat val_x, val_y;
+          gfloat w, w1, w2;
+          const gfloat eps = 1e-4;
+
+          x = gi->roi[0].x + k % gi->roi[0].width;
+          y = gi->roi[0].y + k / gi->roi[0].width;
+
+          val_x = (half_width - x) / (gfloat) half_width;
+          val_y = (half_height - y) / (gfloat) half_height;
+
+          val_x = ABS (CLAMP (val_x, -1.0, 1.0));
+          val_y = ABS (CLAMP (val_y, -1.0, 1.0));
+
+          /* ambiguous position */
+          if (ABS (val_x - val_y) >= 1.0 - eps)
+            w = 0.0;
+          else
+            w = val_x * val_y / (val_x * val_y + (1.0 - val_x) * (1.0 - val_y));
+
+          alpha = data_in1[3] * (1.0 - w) + data_in2[3] * w;
+
+          w1 = (1.0 - w) * data_in1[3] / alpha;
+          w2 = w * data_in2[3] / alpha;
+
+          for (b = 0; b < 3; b++)
+            data_out[b] = data_in1[b] * w1 + data_in2[b] * w2;
+
+          data_out[3] = alpha;
+
+          data_out += 4;
+          data_in1 += 4;
+          data_in2 += 4;
+        }
+    }
+
+  return TRUE;
+}
+
+static GeglRectangle
+get_required_for_output (GeglOperation       *operation,
+                         const gchar         *input_pad,
+                         const GeglRectangle *roi)
+{
+  return *gegl_operation_source_get_bounding_box (operation, "input");
+}
+
+static GeglRectangle
+get_cached_region (GeglOperation       *operation,
+                   const GeglRectangle *roi)
+{
+  return *gegl_operation_source_get_bounding_box (operation, "input");
+}
+
+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_required_for_output = get_required_for_output;
+  operation_class->get_cached_region       = get_cached_region;
+
+  gegl_operation_class_set_keys (operation_class,
+    "name"       , "gegl:tile-seamless",
+    "categories" , "misc",
+    "description", _("Make the input buffer seamlessly tileable."
+                     " The algorithm is not content-aware,"
+                     " so the result may need post-processing."),
+    NULL);
+}
+
+#endif
diff --git a/po/POTFILES.in b/po/POTFILES.in
index cd110b6..5eece1b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -93,6 +93,7 @@ operations/common/svg-matrix.c
 operations/common/svg-saturate.c
 operations/common/threshold.c
 operations/common/tile.c
+operations/common/tile-seamless.c
 operations/common/unsharp-mask.c
 operations/common/value-invert.c
 operations/common/vignette.c


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]