From 5c1676dfe6d2f3c837a5e074117b45613fd29a72 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:30:19 +0200 Subject: Adding upstream version 2.10.34. Signed-off-by: Daniel Baumann --- modules/display-filter-clip-warning.c | 494 ++++++++++++++++++++++++++++++++++ 1 file changed, 494 insertions(+) create mode 100644 modules/display-filter-clip-warning.c (limited to 'modules/display-filter-clip-warning.c') diff --git a/modules/display-filter-clip-warning.c b/modules/display-filter-clip-warning.c new file mode 100644 index 0000000..89d290d --- /dev/null +++ b/modules/display-filter-clip-warning.c @@ -0,0 +1,494 @@ +/* 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 . + */ + +#include "config.h" + +#include + +#include +#include + +#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_BOGUS_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_BOGUS = 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_bogus; + GimpRGB bogus_color; + gboolean include_alpha; + gboolean include_transparent; + + 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_BOGUS, + PROP_BOGUS_COLOR, + PROP_INCLUDE_ALPHA, + PROP_INCLUDE_TRANSPARENT +}; + + +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; + + 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_BOGUS, + "show-bogus", + _("Show bogus"), + _("Show warning for pixels with an infinite or NaN component"), + TRUE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_RGB (object_class, PROP_BOGUS_COLOR, + "bogus-color", + _("Bogus color"), + _("Bogus warning color"), + FALSE, + DEFAULT_BOGUS_COLOR, + GIMP_PARAM_STATIC_STRINGS | + GIMP_CONFIG_PARAM_DEFAULTS); + + gegl_param_spec_set_property_key ( + g_object_class_find_property (G_OBJECT_CLASS (klass), "bogus-color"), + "sensitive", "show-bogus"); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_INCLUDE_ALPHA, + "include-alpha", + _("Include alpha component"), + _("Include alpha component in the warning"), + TRUE, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_INCLUDE_TRANSPARENT, + "include-transparent", + _("Include transparent pixels"), + _("Include fully transparent pixels in the warning"), + TRUE, + GIMP_PARAM_STATIC_STRINGS); + + display_class->name = _("Clip Warning"); + display_class->help_id = "gimp-colordisplay-clip-warning"; + display_class->icon_name = GIMP_ICON_DISPLAY_FILTER_CLIP_WARNING; + + 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_BOGUS: + g_value_set_boolean (value, clip_warning->show_bogus); + break; + case PROP_BOGUS_COLOR: + g_value_set_boxed (value, &clip_warning->bogus_color); + break; + + case PROP_INCLUDE_ALPHA: + g_value_set_boolean (value, clip_warning->include_alpha); + break; + case PROP_INCLUDE_TRANSPARENT: + g_value_set_boolean (value, clip_warning->include_transparent); + 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_MEMBER_PTR(member, value) \ + cdisplay_clip_warning_set_member (clip_warning, \ + pspec->name, \ + &clip_warning->member, \ + (value), \ + sizeof (clip_warning->member)) +#define SET_MEMBER_VAL(member, type, value) \ + SET_MEMBER_PTR (member, &(type) {value}) + + switch (property_id) + { + case PROP_SHOW_SHADOWS: + SET_MEMBER_VAL (show_shadows, gboolean, g_value_get_boolean (value)); + break; + case PROP_SHADOWS_COLOR: + SET_MEMBER_PTR (shadows_color, g_value_get_boxed (value)); + break; + + case PROP_SHOW_HIGHLIGHTS: + SET_MEMBER_VAL (show_highlights, gboolean, g_value_get_boolean (value)); + break; + case PROP_HIGHLIGHTS_COLOR: + SET_MEMBER_PTR (highlights_color, g_value_get_boxed (value)); + break; + + case PROP_SHOW_BOGUS: + SET_MEMBER_VAL (show_bogus, gboolean, g_value_get_boolean (value)); + break; + case PROP_BOGUS_COLOR: + SET_MEMBER_PTR (bogus_color, g_value_get_boxed (value)); + break; + + case PROP_INCLUDE_ALPHA: + SET_MEMBER_VAL (include_alpha, gboolean, g_value_get_boolean (value)); + break; + case PROP_INCLUDE_TRANSPARENT: + SET_MEMBER_VAL (include_transparent, gboolean, g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } + +#undef SET_MEMBER_PTR +#undef SET_MEMBER_VAL +} + +static void +cdisplay_clip_warning_convert_buffer (GimpColorDisplay *display, + GeglBuffer *buffer, + GeglRectangle *area) +{ + CdisplayClipWarning *clip_warning = CDISPLAY_CLIP_WARNING (display); + GeglBufferIterator *iter; + + iter = gegl_buffer_iterator_new (buffer, area, 0, + babl_format ("R'G'B'A float"), + GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE, 1); + + while (gegl_buffer_iterator_next (iter)) + { + gfloat *data = iter->items[0].data; + gint count = iter->length; + gint x = iter->items[0].roi.x; + gint y = iter->items[0].roi.y; + + while (count--) + { + gint warning = 0; + + if (clip_warning->include_transparent || + ! (data[3] <= 0.0f) /* include nan */) + { + if (clip_warning->show_bogus && + (! isfinite (data[0]) || ! isfinite (data[1]) || ! isfinite (data[2]) || + (clip_warning->include_alpha && ! isfinite (data[3])))) + { + /* don't combine warning color of pixels with a bogus + * component with other warnings + */ + warning = WARNING_BOGUS; + } + else + { + if (clip_warning->show_shadows && + (data[0] < 0.0f || data[1] < 0.0f || data[2] < 0.0f || + (clip_warning->include_alpha && data[3] < 0.0f))) + { + warning |= WARNING_SHADOW; + } + + if (clip_warning->show_highlights && + (data[0] > 1.0f || data[1] > 1.0f || data[2] > 1.0f || + (clip_warning->include_alpha && data[3] > 1.0f))) + { + warning |= WARNING_HIGHLIGHT; + } + } + } + + if (warning) + { + gboolean alt = ((x + y) >> 3) & 1; + + memcpy (data, clip_warning->colors[warning][alt], + 4 * sizeof (gfloat)); + } + + data += 4; + + if (++x == iter->items[0].roi.x + iter->items[0].roi.width) + { + x = iter->items[0].roi.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_BOGUS) + { + color[0] += clip_warning->bogus_color.r; + color[1] += clip_warning->bogus_color.g; + color[2] += clip_warning->bogus_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; + } +} -- cgit v1.2.3