[gegl] operations: add gegl:video-degradation



commit 3a885dc28cdcd1d62dbc6cc4c03143c84aa1fbc4
Author: Thomas Manni <thomas manni free fr>
Date:   Tue Nov 11 19:33:32 2014 +0100

    operations: add gegl:video-degradation

 operations/common/Makefile.am                      |    1 +
 operations/common/video-degradation.c              |  277 ++++++++++++++++++++
 po/POTFILES.in                                     |    2 +
 tests/compositions/Makefile.am                     |    1 +
 tests/compositions/reference/video-degradation.png |  Bin 0 -> 211128 bytes
 tests/compositions/video-degradation.xml           |   16 ++
 6 files changed, 297 insertions(+), 0 deletions(-)
---
diff --git a/operations/common/Makefile.am b/operations/common/Makefile.am
index 1feba4a..c9fd1cd 100644
--- a/operations/common/Makefile.am
+++ b/operations/common/Makefile.am
@@ -120,6 +120,7 @@ op_LTLIBRARIES = \
        tile-glass.la \
        unsharp-mask.la \
        value-invert.la \
+       video-degradation.la \
        vignette.la \
        warp.la \
        waves.la \
diff --git a/operations/common/video-degradation.c b/operations/common/video-degradation.c
new file mode 100644
index 0000000..41f1b41
--- /dev/null
+++ b/operations/common/video-degradation.c
@@ -0,0 +1,277 @@
+/* This file is an image processing operation for GEGL
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Exchange one color with the other (settable threshold to convert from
+ * one color-shade to another...might do wonders on certain images, or be
+ * totally useless on others).
+ *
+ * Author: Adam D. Moss <adam foxbox org>
+ *
+ * GEGL port: Thomas Manni <thomas manni free fr>
+ *
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#ifdef GEGL_PROPERTIES
+
+enum_start (gegl_video_degradation_type)
+  enum_value (GEGL_VIDEO_DEGRADATION_TYPE_STAGGERED, "staggered",
+              N_("Staggered"))
+  enum_value (GEGL_VIDEO_DEGRADATION_TYPE_LARGE_STAGGERED, "large_staggered",
+              N_("Large staggered"))
+  enum_value (GEGL_VIDEO_DEGRADATION_TYPE_STRIPED, "striped",
+              N_("Striped"))
+  enum_value (GEGL_VIDEO_DEGRADATION_TYPE_WIDE_STRIPED, "wide_striped",
+              N_("Wide striped"))
+  enum_value (GEGL_VIDEO_DEGRADATION_TYPE_LONG_STAGGERED, "long_staggered",
+              N_("Long staggered"))
+  enum_value (GEGL_VIDEO_DEGRADATION_TYPE_3X3, "3x3",
+              N_("3x3"))
+  enum_value (GEGL_VIDEO_DEGRADATION_TYPE_LARGE_3X3, "large_3x3",
+              N_("Large 3x3"))
+  enum_value (GEGL_VIDEO_DEGRADATION_TYPE_Hex, "hex",
+              N_("Hex"))
+  enum_value (GEGL_VIDEO_DEGRADATION_TYPE_DOTS, "dots",
+              N_("Dots"))
+enum_end (GeglVideoDegradationType)
+
+property_enum (pattern, _("Pattern"), GeglVideoDegradationType,
+               gegl_video_degradation_type,
+               GEGL_VIDEO_DEGRADATION_TYPE_STRIPED)
+  description (_("Type of RGB pattern to use"))
+
+property_boolean (additive, _("Additive"), TRUE)
+  description(_("Whether the function adds the result to the original image."))
+
+property_boolean (rotated, _("Rotated"), FALSE)
+  description(_("Whether to rotate the RGB pattern by ninety degrees."))
+
+#else
+
+#define GEGL_OP_POINT_FILTER
+#define GEGL_OP_C_FILE "video-degradation.c"
+
+#include "gegl-op.h"
+
+#define MAX_PATTERNS       9
+#define MAX_PATTERN_SIZE 108
+
+static const gint   pattern_width[MAX_PATTERNS] = { 2, 4, 1, 1, 2, 3, 6, 6, 5 };
+static const gint   pattern_height[MAX_PATTERNS] = { 6, 12, 3, 6, 12, 3, 6,
+                                                     18, 15 };
+
+static const gint pattern[MAX_PATTERNS][MAX_PATTERN_SIZE] =
+{
+  {
+    0, 1,
+    0, 2,
+    1, 2,
+    1, 0,
+    2, 0,
+    2, 1,
+  },
+  {
+    0, 0, 1, 1,
+    0, 0, 1, 1,
+    0, 0, 2, 2,
+    0, 0, 2, 2,
+    1, 1, 2, 2,
+    1, 1, 2, 2,
+    1, 1, 0, 0,
+    1, 1, 0, 0,
+    2, 2, 0, 0,
+    2, 2, 0, 0,
+    2, 2, 1, 1,
+    2, 2, 1, 1,
+  },
+  {
+    0,
+    1,
+    2,
+  },
+  {
+    0,
+    0,
+    1,
+    1,
+    2,
+    2,
+  },
+  {
+    0, 1,
+    0, 1,
+    0, 2,
+    0, 2,
+    1, 2,
+    1, 2,
+    1, 0,
+    1, 0,
+    2, 0,
+    2, 0,
+    2, 1,
+    2, 1,
+  },
+  {
+    0, 1, 2,
+    2, 0, 1,
+    1, 2, 0,
+  },
+  {
+    0, 0, 1, 1, 2, 2,
+    0, 0, 1, 1, 2, 2,
+    2, 2, 0, 0, 1, 1,
+    2, 2, 0, 0, 1, 1,
+    1, 1, 2, 2, 0, 0,
+    1, 1, 2, 2, 0, 0,
+  },
+  {
+    2, 2, 0, 0, 0, 0,
+    2, 2, 2, 0, 0, 2,
+    2, 2, 2, 2, 2, 2,
+    2, 2, 2, 1, 1, 2,
+    2, 2, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1,
+    0, 0, 1, 1, 1, 1,
+    0, 0, 0, 1, 1, 0,
+    0, 0, 0, 0, 0, 0,
+    0, 0, 0, 2, 2, 0,
+    0, 0, 2, 2, 2, 2,
+    2, 2, 2, 2, 2, 2,
+    1, 1, 2, 2, 2, 2,
+    1, 1, 1, 2, 2, 1,
+    1, 1, 1, 1, 1, 1,
+    1, 1, 1, 0, 0, 1,
+    1, 1, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0,
+  },
+  {
+    0, 1, 2, 0, 0,
+    1, 1, 1, 2, 0,
+    0, 1, 2, 2, 2,
+    0, 0, 1, 2, 0,
+    0, 1, 1, 1, 2,
+    2, 0, 1, 2, 2,
+    0, 0, 0, 1, 2,
+    2, 0, 1, 1, 1,
+    2, 2, 0, 1, 2,
+    2, 0, 0, 0, 1,
+    1, 2, 0, 1, 1,
+    2, 2, 2, 0, 1,
+    1, 2, 0, 0, 0,
+    1, 1, 2, 0, 1,
+    1, 2, 2, 2, 0,
+  }
+};
+
+static void
+prepare (GeglOperation *operation)
+{
+  const Babl     *format = babl_format ("R'G'B'A float");
+
+  gegl_operation_set_format (operation, "input", format);
+  gegl_operation_set_format (operation, "output", format);
+}
+
+
+static gboolean
+process (GeglOperation       *operation,
+         void                *in_buf,
+         void                *out_buf,
+         glong                n_pixels,
+         const GeglRectangle *roi,
+         gint                 level)
+{
+  GeglProperties *o = GEGL_PROPERTIES (operation);
+  gfloat *input  = in_buf;
+  gfloat *output = out_buf;
+  gfloat value;
+  gint x, y;
+  gint real_x, real_y;
+  gint b;
+  gint sel_b;
+  gint idx;
+
+  for (y = 0 ; y < roi->height ; y++)
+    {
+      real_y = roi->y + y;
+      for (x = 0 ; x < roi->width ; x++)
+        {
+          real_x = roi->x + x;
+
+          if (o->rotated)
+            {
+              sel_b = pattern[o->pattern][pattern_width[o->pattern]*
+                (real_x % pattern_height[o->pattern]) +
+                 real_y % pattern_width[o->pattern] ];
+            }
+          else
+            {
+              sel_b = pattern[o->pattern][pattern_width[o->pattern]*
+                 (real_y % pattern_height[o->pattern]) +
+                 real_x % pattern_width[o->pattern] ];
+            }
+
+            for (b = 0; b < 4; b++)
+              {
+                idx = (x + y * roi->width) * 4 + b;
+                if (b < 3 )
+                  {
+                    value = (sel_b == b) ? input[idx] : 0.f;
+                    if (o->additive)
+                      {
+                        gfloat temp = value + input[idx];
+                        value = MIN (temp, 1.0);
+                      }
+                    output[idx] = value;
+                  }
+                else
+                 {
+                   output[idx] = input[idx];
+                 }
+              }
+        }
+    }
+
+  return TRUE;
+}
+
+static void
+gegl_op_class_init (GeglOpClass *klass)
+{
+  GeglOperationClass            *operation_class;
+  GeglOperationPointFilterClass *filter_class;
+
+  operation_class = GEGL_OPERATION_CLASS (klass);
+  filter_class    = GEGL_OPERATION_POINT_FILTER_CLASS (klass);
+
+  operation_class->prepare = prepare;
+  operation_class->opencl_support = FALSE;
+
+  filter_class->process    = process;
+
+  gegl_operation_class_set_keys (operation_class,
+    "name",        "gegl:video-degradation",
+    "title",       _("Video Degradation"),
+    "categories",  "distort",
+    "license",     "GPL3+",
+    "description", _("This function simulates the degradation of "
+                     "being on an old low-dotpitch RGB video monitor."),
+    NULL);
+}
+
+#endif
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e551acb..9ef49b0 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -19,6 +19,7 @@ operations/common/cartoon.c
 operations/common/channel-mixer.c
 operations/common/checkerboard.c
 operations/common/color.c
+operations/common/color-exchange.c
 operations/common/color-reduction.c
 operations/common/color-rotate.c
 operations/common/color-temperature.c
@@ -113,6 +114,7 @@ operations/common/tile-glass.c
 operations/common/tile-seamless.c
 operations/common/unsharp-mask.c
 operations/common/value-invert.c
+operations/common/video-degradation.c
 operations/common/vignette.c
 operations/common/warp.c
 operations/common/waves.c
diff --git a/tests/compositions/Makefile.am b/tests/compositions/Makefile.am
index db52448..f09afb1 100644
--- a/tests/compositions/Makefile.am
+++ b/tests/compositions/Makefile.am
@@ -48,6 +48,7 @@ TESTS = \
   softglow.xml                    \
   stretch-contrast.xml            \
   transform.xml                   \
+  video-degradation.xml           \
   weighted-blend.xml              \
   rectangles.xml
 
diff --git a/tests/compositions/reference/video-degradation.png 
b/tests/compositions/reference/video-degradation.png
new file mode 100644
index 0000000..5bb0b40
Binary files /dev/null and b/tests/compositions/reference/video-degradation.png differ
diff --git a/tests/compositions/video-degradation.xml b/tests/compositions/video-degradation.xml
new file mode 100644
index 0000000..2534a6b
--- /dev/null
+++ b/tests/compositions/video-degradation.xml
@@ -0,0 +1,16 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<gegl>
+  <node operation='gegl:video-degradation'>
+    <params>
+      <param name='pattern'>Striped</param>
+      <param name='additive'>true</param>
+      <param name='rotated'>false</param>
+    </params>
+  </node>
+  <node operation='gegl:load'>
+    <params>
+      <param name='path'>data/duck.png</param>
+    </params>
+  </node>
+</gegl>
+


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