[gimp] modules: add clip-warning display filter



commit 5b118a260b9bcd82a86a6cc41c64629977bf967e
Author: Ell <ell_se yahoo com>
Date:   Thu Nov 2 14:05:52 2017 -0400

    modules: add clip-warning display filter
    
    The clip-warning display filter highlights pixels with at least one
    componet whose value is outside the [0,1] range, or is NaN.

 modules/Makefile.am                   |    5 +
 modules/display-filter-clip-warning.c |  504 +++++++++++++++++++++++++++++++++
 po-libgimp/POTFILES.in                |    1 +
 3 files changed, 510 insertions(+), 0 deletions(-)
---
diff --git a/modules/Makefile.am b/modules/Makefile.am
index fa4e8de..867fb6d 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -35,6 +35,7 @@ lib_LTLIBRARIES = \
        libcolor-selector-cmyk.la               \
        libcolor-selector-water.la              \
        libcolor-selector-wheel.la              \
+       libdisplay-filter-clip-warning.la       \
        libdisplay-filter-color-blind.la        \
        libdisplay-filter-gamma.la              \
        libdisplay-filter-high-contrast.la      \
@@ -61,6 +62,10 @@ libcolor_selector_wheel_la_SOURCES = color-selector-wheel.c gimpcolorwheel.c gim
 libcolor_selector_wheel_la_LDFLAGS = -avoid-version -module $(no_undefined)
 libcolor_selector_wheel_la_LIBADD = $(color_selector_libadd)
 
+libdisplay_filter_clip_warning_la_SOURCES = display-filter-clip-warning.c
+libdisplay_filter_clip_warning_la_LDFLAGS = -avoid-version -module $(no_undefined)
+libdisplay_filter_clip_warning_la_LIBADD = $(display_filter_libadd)
+
 libdisplay_filter_color_blind_la_SOURCES = display-filter-color-blind.c
 libdisplay_filter_color_blind_la_LDFLAGS = -avoid-version -module $(no_undefined)
 libdisplay_filter_color_blind_la_LIBADD = $(display_filter_libadd)
diff --git a/modules/display-filter-clip-warning.c b/modules/display-filter-clip-warning.c
new file mode 100644
index 0000000..3e859fe
--- /dev/null
+++ b/modules/display-filter-clip-warning.c
@@ -0,0 +1,504 @@
+/* GIMP - The GNU Image Manipulation Program
+ *
+ * Copyright (C) 2017 Ell
+ *
+ * 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/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpconfig/gimpconfig.h"
+#include "libgimpmath/gimpmath.h"
+#include "libgimpmodule/gimpmodule.h"
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "libgimp/libgimp-intl.h"
+
+
+#define DEFAULT_SHADOWS_COLOR    (&(GimpRGB) {0.25, 0.25, 1.00, 1.00})
+#define DEFAULT_HIGHLIGHTS_COLOR (&(GimpRGB) {1.00, 0.25, 0.25, 1.00})
+#define DEFAULT_NAN_COLOR        (&(GimpRGB) {1.00, 1.00, 0.25, 1.00})
+
+#define CDISPLAY_TYPE_CLIP_WARNING            (cdisplay_clip_warning_get_type ())
+#define CDISPLAY_CLIP_WARNING(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
CDISPLAY_TYPE_CLIP_WARNING, CdisplayClipWarning))
+#define CDISPLAY_CLIP_WARNING_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CDISPLAY_TYPE_CLIP_WARNING, 
CdisplayClipWarningClass))
+#define CDISPLAY_IS_CLIP_WARNING(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
CDISPLAY_TYPE_CLIP_WARNING))
+#define CDISPLAY_IS_CLIP_WARNING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CDISPLAY_TYPE_CLIP_WARNING))
+
+
+typedef enum
+{
+  WARNING_SHADOW    = 1 << 0,
+  WARNING_HIGHLIGHT = 1 << 1,
+  WARNING_NAN       = 1 << 2
+} Warning;
+
+
+typedef struct _CdisplayClipWarning      CdisplayClipWarning;
+typedef struct _CdisplayClipWarningClass CdisplayClipWarningClass;
+
+struct _CdisplayClipWarning
+{
+  GimpColorDisplay  parent_instance;
+
+  gboolean          show_shadows;
+  GimpRGB           shadows_color;
+  gboolean          show_highlights;
+  GimpRGB           highlights_color;
+  gboolean          show_nan;
+  GimpRGB           nan_color;
+  gboolean          include_alpha;
+  gboolean          opaque;
+
+  gfloat            colors[8][2][4];
+};
+
+struct _CdisplayClipWarningClass
+{
+  GimpColorDisplayClass  parent_instance;
+};
+
+
+enum
+{
+  PROP_0,
+  PROP_SHOW_SHADOWS,
+  PROP_SHADOWS_COLOR,
+  PROP_SHOW_HIGHLIGHTS,
+  PROP_HIGHLIGHTS_COLOR,
+  PROP_SHOW_NAN,
+  PROP_NAN_COLOR,
+  PROP_INCLUDE_ALPHA,
+  PROP_OPAQUE
+};
+
+
+static GType   cdisplay_clip_warning_get_type       (void);
+
+static void    cdisplay_clip_warning_set_property   (GObject             *object,
+                                                     guint                property_id,
+                                                     const GValue        *value,
+                                                     GParamSpec          *pspec);
+static void    cdisplay_clip_warning_get_property   (GObject             *object,
+                                                     guint                property_id,
+                                                     GValue              *value,
+                                                     GParamSpec          *pspec);
+
+static void    cdisplay_clip_warning_convert_buffer (GimpColorDisplay    *display,
+                                                     GeglBuffer          *buffer,
+                                                     GeglRectangle       *area);
+
+static void    cdisplay_clip_warning_set_member     (CdisplayClipWarning *clip_warning,
+                                                     const gchar         *property_name,
+                                                     gpointer             member,
+                                                     gconstpointer        value,
+                                                     gsize                size);
+static void    cdisplay_clip_warning_update_colors  (CdisplayClipWarning *clip_warning);
+
+
+static const GimpModuleInfo cdisplay_clip_warning_info =
+{
+  GIMP_MODULE_ABI_VERSION,
+  N_("Clip warning color display filter"),
+  "Ell",
+  "v1.0",
+  "(c) 2017, released under the GPL",
+  "2017"
+};
+
+
+G_DEFINE_DYNAMIC_TYPE (CdisplayClipWarning, cdisplay_clip_warning,
+                       GIMP_TYPE_COLOR_DISPLAY)
+
+
+G_MODULE_EXPORT const GimpModuleInfo *
+gimp_module_query (GTypeModule *module)
+{
+  return &cdisplay_clip_warning_info;
+}
+
+G_MODULE_EXPORT gboolean
+gimp_module_register (GTypeModule *module)
+{
+  cdisplay_clip_warning_register_type (module);
+
+  return TRUE;
+}
+
+static void
+cdisplay_clip_warning_class_init (CdisplayClipWarningClass *klass)
+{
+  GObjectClass          *object_class  = G_OBJECT_CLASS (klass);
+  GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
+
+  object_class->get_property = cdisplay_clip_warning_get_property;
+  object_class->set_property = cdisplay_clip_warning_set_property;
+
+  display_class->name        = _("Clip Warning");
+  display_class->help_id     = "gimp-colordisplay-clip-warning";
+  display_class->icon_name   = "gimp-warning";
+
+  GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_SHADOWS,
+                            "show-shadows",
+                            _("Show shadows"),
+                            _("Show warning for pixels with a negative component"),
+                            TRUE,
+                            GIMP_PARAM_STATIC_STRINGS);
+
+  GIMP_CONFIG_PROP_RGB (object_class, PROP_SHADOWS_COLOR,
+                        "shadows-color",
+                        _("Shadows color"),
+                        _("Shadows warning color"),
+                        FALSE,
+                        DEFAULT_SHADOWS_COLOR,
+                        GIMP_PARAM_STATIC_STRINGS |
+                        GIMP_CONFIG_PARAM_DEFAULTS);
+
+  gegl_param_spec_set_property_key (
+    g_object_class_find_property (G_OBJECT_CLASS (klass), "shadows-color"),
+    "sensitive", "show-shadows");
+
+  GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_HIGHLIGHTS,
+                            "show-highlights",
+                            _("Show highlights"),
+                            _("Show warning for pixels with a component greater than one"),
+                            TRUE,
+                            GIMP_PARAM_STATIC_STRINGS);
+
+  GIMP_CONFIG_PROP_RGB (object_class, PROP_HIGHLIGHTS_COLOR,
+                        "highlights-color",
+                        _("Highlights color"),
+                        _("Highlights warning color"),
+                        FALSE,
+                        DEFAULT_HIGHLIGHTS_COLOR,
+                        GIMP_PARAM_STATIC_STRINGS |
+                        GIMP_CONFIG_PARAM_DEFAULTS);
+
+  gegl_param_spec_set_property_key (
+    g_object_class_find_property (G_OBJECT_CLASS (klass), "highlights-color"),
+    "sensitive", "show-highlights");
+
+  GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_NAN,
+                            "show-nan",
+                            _("Show NaN"),
+                            _("Show warning for pixels with a NaN component"),
+                            TRUE,
+                            GIMP_PARAM_STATIC_STRINGS);
+
+  GIMP_CONFIG_PROP_RGB (object_class, PROP_NAN_COLOR,
+                        "nan-color",
+                        _("NaN color"),
+                        _("NaN warning color"),
+                        FALSE,
+                        DEFAULT_NAN_COLOR,
+                        GIMP_PARAM_STATIC_STRINGS |
+                        GIMP_CONFIG_PARAM_DEFAULTS);
+
+  gegl_param_spec_set_property_key (
+    g_object_class_find_property (G_OBJECT_CLASS (klass), "nan-color"),
+    "sensitive", "show-nan");
+
+  GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_INCLUDE_ALPHA,
+                            "include-alpha",
+                            _("Include alpha"),
+                            _("Include alpha component in the warnings"),
+                            TRUE,
+                            GIMP_PARAM_STATIC_STRINGS);
+
+  GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_OPAQUE,
+                            "opaque",
+                            _("Opaque"),
+                            _("Make warning pixels opaque"),
+                            TRUE,
+                            GIMP_PARAM_STATIC_STRINGS);
+
+  display_class->convert_buffer  = cdisplay_clip_warning_convert_buffer;
+}
+
+static void
+cdisplay_clip_warning_class_finalize (CdisplayClipWarningClass *klass)
+{
+}
+
+static void
+cdisplay_clip_warning_init (CdisplayClipWarning *clip_warning)
+{
+}
+
+static void
+cdisplay_clip_warning_get_property (GObject    *object,
+                                    guint       property_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+  CdisplayClipWarning *clip_warning = CDISPLAY_CLIP_WARNING (object);
+
+  switch (property_id)
+    {
+    case PROP_SHOW_SHADOWS:
+      g_value_set_boolean (value, clip_warning->show_shadows);
+      break;
+    case PROP_SHADOWS_COLOR:
+      g_value_set_boxed (value, &clip_warning->shadows_color);
+      break;
+
+    case PROP_SHOW_HIGHLIGHTS:
+      g_value_set_boolean (value, clip_warning->show_highlights);
+      break;
+    case PROP_HIGHLIGHTS_COLOR:
+      g_value_set_boxed (value, &clip_warning->highlights_color);
+      break;
+
+    case PROP_SHOW_NAN:
+      g_value_set_boolean (value, clip_warning->show_nan);
+      break;
+    case PROP_NAN_COLOR:
+      g_value_set_boxed (value, &clip_warning->nan_color);
+      break;
+
+    case PROP_INCLUDE_ALPHA:
+      g_value_set_boolean (value, clip_warning->include_alpha);
+      break;
+    case PROP_OPAQUE:
+      g_value_set_boolean (value, clip_warning->opaque);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+cdisplay_clip_warning_set_property (GObject      *object,
+                                    guint         property_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  CdisplayClipWarning *clip_warning = CDISPLAY_CLIP_WARNING (object);
+
+#define SET_PTR_MEMBER(member, value)                                          \
+  cdisplay_clip_warning_set_member (clip_warning,                              \
+                                    pspec->name,                               \
+                                    &clip_warning->member,                     \
+                                    (value),                                   \
+                                    sizeof (clip_warning->member))
+#define SET_VAL_MEMBER(member, type, value)                                    \
+  SET_PTR_MEMBER (member, &(type) {value})
+
+  switch (property_id)
+    {
+    case PROP_SHOW_SHADOWS:
+      SET_VAL_MEMBER (show_shadows, gboolean, g_value_get_boolean (value));
+      break;
+    case PROP_SHADOWS_COLOR:
+      SET_PTR_MEMBER (shadows_color, g_value_get_boxed (value));
+      break;
+
+    case PROP_SHOW_HIGHLIGHTS:
+      SET_VAL_MEMBER (show_highlights, gboolean, g_value_get_boolean (value));
+      break;
+    case PROP_HIGHLIGHTS_COLOR:
+      SET_PTR_MEMBER (highlights_color, g_value_get_boxed (value));
+      break;
+
+    case PROP_SHOW_NAN:
+      SET_VAL_MEMBER (show_nan, gboolean, g_value_get_boolean (value));
+      break;
+    case PROP_NAN_COLOR:
+      SET_PTR_MEMBER (nan_color, g_value_get_boxed (value));
+      break;
+
+    case PROP_INCLUDE_ALPHA:
+      SET_VAL_MEMBER (include_alpha, gboolean, g_value_get_boolean (value));
+      break;
+    case PROP_OPAQUE:
+      SET_VAL_MEMBER (opaque, gboolean, g_value_get_boolean (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+
+#undef SET_PTR_MEMBER
+#undef SET_VAL_MEMBER
+}
+
+static void
+cdisplay_clip_warning_convert_buffer (GimpColorDisplay *display,
+                                      GeglBuffer       *buffer,
+                                      GeglRectangle    *area)
+{
+  CdisplayClipWarning *clip_warning = CDISPLAY_CLIP_WARNING (display);
+  GeglBufferIterator  *iter;
+
+  g_printerr ("%d x %d\n", area->width, area->height);
+  iter = gegl_buffer_iterator_new (buffer, area, 0,
+                                   babl_format ("R'G'B'A float"),
+                                   GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE);
+
+  while (gegl_buffer_iterator_next (iter))
+    {
+      gfloat *data  = iter->data[0];
+      gint    count = iter->length;
+      gint    x     = iter->roi[0].x;
+      gint    y     = iter->roi[0].y;
+
+      while (count--)
+        {
+          gint warning      = 0;
+          gint n_components = clip_warning->opaque ? 4 : 3;
+
+          if (clip_warning->show_shadows)
+            {
+              if (clip_warning->include_alpha && data[3] < 0.0f)
+                {
+                  warning      |= WARNING_SHADOW;
+                  n_components  = 4;
+                }
+              else if (data[0] < 0.0f || data[1] < 0.0f || data[2] < 0.0f)
+                {
+                  warning      |= WARNING_SHADOW;
+                }
+            }
+
+          if (clip_warning->show_highlights)
+            {
+              if (clip_warning->include_alpha && data[3] > 1.0f)
+                {
+                  warning      |= WARNING_HIGHLIGHT;
+                  n_components  = 4;
+                }
+              else if (data[0] > 1.0f || data[1] > 1.0f || data[2] > 1.0f)
+                {
+                  warning      |= WARNING_HIGHLIGHT;
+                }
+            }
+
+          if (clip_warning->show_nan)
+            {
+              if (clip_warning->include_alpha && isnan (data[3]))
+                {
+                  warning      |= WARNING_NAN;
+                  n_components  = 4;
+                }
+              else if (isnan (data[0]) || isnan (data[1]) || isnan (data[2]))
+                {
+                  warning      |= WARNING_NAN;
+                }
+            }
+
+          if (warning)
+            {
+              gboolean alt = ((x + y) >> 3) & 1;
+
+              memcpy (data, clip_warning->colors[warning][alt],
+                      n_components * sizeof (gfloat));
+            }
+
+          data += 4;
+
+          if (++x == iter->roi[0].x + iter->roi[0].width)
+            {
+              x = iter->roi[0].x;
+              y++;
+            }
+        }
+    }
+}
+
+static void
+cdisplay_clip_warning_set_member (CdisplayClipWarning *clip_warning,
+                                  const gchar         *property_name,
+                                  gpointer             member,
+                                  gconstpointer        value,
+                                  gsize                size)
+{
+  if (memcmp (member, value, size))
+    {
+      memcpy (member, value, size);
+
+      cdisplay_clip_warning_update_colors (clip_warning);
+
+      g_object_notify (G_OBJECT (clip_warning), property_name);
+      gimp_color_display_changed (GIMP_COLOR_DISPLAY (clip_warning));
+    }
+}
+
+static void
+cdisplay_clip_warning_update_colors (CdisplayClipWarning *clip_warning)
+{
+  gint i;
+  gint j;
+
+  for (i = 0; i < 8; i++)
+    {
+      gfloat *color     = clip_warning->colors[i][0];
+      gfloat *alt_color = clip_warning->colors[i][1];
+      gfloat  alt_value;
+      gint    n         = 0;
+
+      memset (color, 0, 3 * sizeof (gfloat));
+
+      if (i & WARNING_SHADOW)
+        {
+          color[0] += clip_warning->shadows_color.r;
+          color[1] += clip_warning->shadows_color.g;
+          color[2] += clip_warning->shadows_color.b;
+
+          n++;
+        }
+
+      if (i & WARNING_HIGHLIGHT)
+        {
+          color[0] += clip_warning->highlights_color.r;
+          color[1] += clip_warning->highlights_color.g;
+          color[2] += clip_warning->highlights_color.b;
+
+          n++;
+        }
+
+      if (i & WARNING_NAN)
+        {
+          color[0] += clip_warning->nan_color.r;
+          color[1] += clip_warning->nan_color.g;
+          color[2] += clip_warning->nan_color.b;
+
+          n++;
+        }
+
+      if (n)
+        {
+          for (j = 0; j < 3; j++)
+            color[j] /= n;
+        }
+      color[3] = 1.0;
+
+      if (MAX (color[0], MAX (color[1], color[2])) <= 0.5)
+        alt_value = 1.0;
+      else
+        alt_value = 0.0;
+
+      for (j = 0; j < 3; j++)
+        alt_color[j] = 0.75 * color[j] + 0.25 * alt_value;
+      alt_color[3] = 1.0;
+    }
+}
diff --git a/po-libgimp/POTFILES.in b/po-libgimp/POTFILES.in
index a0b161b..d11bc6f 100644
--- a/po-libgimp/POTFILES.in
+++ b/po-libgimp/POTFILES.in
@@ -73,6 +73,7 @@ modules/color-selector-wheel.c
 modules/controller-dx-dinput.c
 modules/controller-linux-input.c
 modules/controller-midi.c
+modules/display-filter-clip-warning.c
 modules/display-filter-color-blind.c
 modules/display-filter-gamma.c
 modules/display-filter-high-contrast.c


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