[gimp] Bug 766988 - Colors applied to images are not color managed
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 766988 - Colors applied to images are not color managed
- Date: Mon, 7 Nov 2016 14:42:10 +0000 (UTC)
commit 483c282687375a4a4161833c1b49349034746742
Author: Michael Natterer <mitch gimp org>
Date: Mon Nov 7 15:39:48 2016 +0100
Bug 766988 - Colors applied to images are not color managed
Add color management to GimpDrawableFilter and GimpFilterTool, GEGL
ops applied to drawables can be applied in color managed space
now. Sadly, this is very slow, so disabled by default.
I'm sure the profile guessing based on the operation's format doesn't
always work, but this general bug counts as fixed now.
app/core/gimpdrawablefilter.c | 98 +++++++++++++++++++++++++++++++++++++++++
app/core/gimpdrawablefilter.h | 3 +
app/tools/gimpfilteroptions.c | 17 +++++++
app/tools/gimpfilteroptions.h | 1 +
app/tools/gimpfiltertool.c | 43 +++++++++++++++---
5 files changed, 156 insertions(+), 6 deletions(-)
---
diff --git a/app/core/gimpdrawablefilter.c b/app/core/gimpdrawablefilter.c
index 64ba871..032f95e 100644
--- a/app/core/gimpdrawablefilter.c
+++ b/app/core/gimpdrawablefilter.c
@@ -32,11 +32,13 @@
#include <gegl.h>
#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
#include "core-types.h"
#include "gegl/gimp-babl.h"
#include "gegl/gimpapplicator.h"
+#include "gegl/gimp-gegl-utils.h"
#include "gimpchannel.h"
#include "gimpdrawable-filters.h"
@@ -66,6 +68,7 @@ struct _GimpDrawableFilter
gdouble preview_position;
gdouble opacity;
GimpLayerModeEffects paint_mode;
+ gboolean color_managed;
gboolean gamma_hack;
GeglRectangle filter_area;
@@ -73,6 +76,8 @@ struct _GimpDrawableFilter
GeglNode *translate;
GeglNode *crop;
GeglNode *cast_before;
+ GeglNode *transform_before;
+ GeglNode *transform_after;
GeglNode *cast_after;
GimpApplicator *applicator;
};
@@ -90,6 +95,7 @@ static void gimp_drawable_filter_sync_opacity (GimpDrawableFilter *fi
static void gimp_drawable_filter_sync_mode (GimpDrawableFilter *filter);
static void gimp_drawable_filter_sync_affect (GimpDrawableFilter *filter);
static void gimp_drawable_filter_sync_mask (GimpDrawableFilter *filter);
+static void gimp_drawable_filter_sync_transform (GimpDrawableFilter *filter);
static void gimp_drawable_filter_sync_gamma_hack (GimpDrawableFilter *filter);
static gboolean gimp_drawable_filter_is_filtering (GimpDrawableFilter *filter);
@@ -104,6 +110,8 @@ static void gimp_drawable_filter_affect_changed (GimpImage *im
GimpDrawableFilter *filter);
static void gimp_drawable_filter_mask_changed (GimpImage *image,
GimpDrawableFilter *filter);
+static void gimp_drawable_filter_profile_changed (GimpColorManaged *managed,
+ GimpDrawableFilter *filter);
static void gimp_drawable_filter_drawable_removed (GimpDrawable *drawable,
GimpDrawableFilter *filter);
@@ -223,6 +231,12 @@ gimp_drawable_filter_new (GimpDrawable *drawable,
filter->cast_before = gegl_node_new_child (node,
"operation", "gegl:nop",
NULL);
+ filter->transform_before = gegl_node_new_child (node,
+ "operation", "gegl:nop",
+ NULL);
+ filter->transform_after = gegl_node_new_child (node,
+ "operation", "gegl:nop",
+ NULL);
filter->cast_after = gegl_node_new_child (node,
"operation", "gegl:nop",
NULL);
@@ -235,11 +249,13 @@ gimp_drawable_filter_new (GimpDrawable *drawable,
filter->translate,
filter->crop,
filter->cast_before,
+ filter->transform_before,
filter->operation,
NULL);
}
gegl_node_link_many (filter->operation,
+ filter->transform_after,
filter->cast_after,
NULL);
@@ -333,6 +349,23 @@ gimp_drawable_filter_set_mode (GimpDrawableFilter *filter,
}
void
+gimp_drawable_filter_set_color_managed (GimpDrawableFilter *filter,
+ gboolean color_managed)
+{
+ g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter));
+
+ if (color_managed != filter->color_managed)
+ {
+ filter->color_managed = color_managed;
+
+ gimp_drawable_filter_sync_transform (filter);
+
+ if (gimp_drawable_filter_is_filtering (filter))
+ gimp_drawable_filter_update_drawable (filter, NULL);
+ }
+}
+
+void
gimp_drawable_filter_set_gamma_hack (GimpDrawableFilter *filter,
gboolean gamma_hack)
{
@@ -605,6 +638,56 @@ gimp_drawable_filter_sync_mask (GimpDrawableFilter *filter)
}
static void
+gimp_drawable_filter_sync_transform (GimpDrawableFilter *filter)
+{
+ GimpColorManaged *managed = GIMP_COLOR_MANAGED (filter->drawable);
+
+ if (filter->color_managed)
+ {
+ const Babl *filter_format;
+ GimpColorProfile *filter_profile;
+ GimpColorProfile *drawable_profile;
+
+ filter_format = gimp_gegl_node_get_format (filter->operation, "output");
+
+ g_printerr ("filter format: %s\n", babl_get_name (filter_format));
+
+ filter_profile = gimp_babl_format_get_color_profile (filter_format);
+ drawable_profile = gimp_color_managed_get_color_profile (managed);
+
+ if (! gimp_color_transform_can_gegl_copy (filter_profile,
+ drawable_profile))
+ {
+ g_printerr ("using gimp:profile-transform\n");
+
+ gegl_node_set (filter->transform_before,
+ "operation", "gimp:profile-transform",
+ "src-profile", drawable_profile,
+ "dest-profile", filter_profile,
+ NULL);
+
+ gegl_node_set (filter->transform_after,
+ "operation", "gimp:profile-transform",
+ "src-profile", filter_profile,
+ "dest-profile", drawable_profile,
+ NULL);
+
+ return;
+ }
+ }
+
+ g_printerr ("using gegl copy\n");
+
+ gegl_node_set (filter->transform_before,
+ "operation", "gegl:nop",
+ NULL);
+
+ gegl_node_set (filter->transform_after,
+ "operation", "gegl:nop",
+ NULL);
+}
+
+static void
gimp_drawable_filter_sync_gamma_hack (GimpDrawableFilter *filter)
{
if (filter->gamma_hack)
@@ -670,6 +753,7 @@ gimp_drawable_filter_add_filter (GimpDrawableFilter *filter)
gimp_drawable_filter_sync_opacity (filter);
gimp_drawable_filter_sync_mode (filter);
gimp_drawable_filter_sync_affect (filter);
+ gimp_drawable_filter_sync_transform (filter);
gimp_drawable_filter_sync_gamma_hack (filter);
gimp_drawable_add_filter (filter->drawable,
@@ -681,6 +765,9 @@ gimp_drawable_filter_add_filter (GimpDrawableFilter *filter)
g_signal_connect (image, "mask-changed",
G_CALLBACK (gimp_drawable_filter_mask_changed),
filter);
+ g_signal_connect (image, "profile-changed",
+ G_CALLBACK (gimp_drawable_filter_profile_changed),
+ filter);
g_signal_connect (filter->drawable, "removed",
G_CALLBACK (gimp_drawable_filter_drawable_removed),
filter);
@@ -702,6 +789,9 @@ gimp_drawable_filter_remove_filter (GimpDrawableFilter *filter)
gimp_drawable_filter_drawable_removed,
filter);
g_signal_handlers_disconnect_by_func (image,
+ gimp_drawable_filter_profile_changed,
+ filter);
+ g_signal_handlers_disconnect_by_func (image,
gimp_drawable_filter_mask_changed,
filter);
g_signal_handlers_disconnect_by_func (image,
@@ -783,6 +873,14 @@ gimp_drawable_filter_mask_changed (GimpImage *image,
}
static void
+gimp_drawable_filter_profile_changed (GimpColorManaged *managed,
+ GimpDrawableFilter *filter)
+{
+ gimp_drawable_filter_sync_transform (filter);
+ gimp_drawable_filter_update_drawable (filter, NULL);
+}
+
+static void
gimp_drawable_filter_drawable_removed (GimpDrawable *drawable,
GimpDrawableFilter *filter)
{
diff --git a/app/core/gimpdrawablefilter.h b/app/core/gimpdrawablefilter.h
index d0bcf94..87630aa 100644
--- a/app/core/gimpdrawablefilter.h
+++ b/app/core/gimpdrawablefilter.h
@@ -66,6 +66,9 @@ void gimp_drawable_filter_set_opacity (GimpDrawableFilter *filter,
void gimp_drawable_filter_set_mode (GimpDrawableFilter *filter,
GimpLayerModeEffects paint_mode);
+void gimp_drawable_filter_set_color_managed
+ (GimpDrawableFilter *filter,
+ gboolean managed);
void gimp_drawable_filter_set_gamma_hack (GimpDrawableFilter *filter,
gboolean gamma_hack);
diff --git a/app/tools/gimpfilteroptions.c b/app/tools/gimpfilteroptions.c
index 406dea4..ef6933a 100644
--- a/app/tools/gimpfilteroptions.c
+++ b/app/tools/gimpfilteroptions.c
@@ -37,6 +37,7 @@ enum
PROP_PREVIEW_ALIGNMENT,
PROP_PREVIEW_POSITION,
PROP_REGION,
+ PROP_COLOR_MANAGED,
PROP_GAMMA_HACK,
PROP_SETTINGS
};
@@ -106,6 +107,14 @@ gimp_filter_options_class_init (GimpFilterOptionsClass *klass)
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
+ g_object_class_install_property (object_class, PROP_COLOR_MANAGED,
+ g_param_spec_boolean ("color-managed",
+ _("Color _managed"),
+ NULL,
+ FALSE,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
g_object_class_install_property (object_class, PROP_GAMMA_HACK,
g_param_spec_boolean ("gamma-hack",
"Gamma hack (temp hack, please ignore)",
@@ -171,6 +180,10 @@ gimp_filter_options_set_property (GObject *object,
options->region = g_value_get_enum (value);
break;
+ case PROP_COLOR_MANAGED:
+ options->color_managed = g_value_get_boolean (value);
+ break;
+
case PROP_GAMMA_HACK:
options->gamma_hack = g_value_get_boolean (value);
break;
@@ -217,6 +230,10 @@ gimp_filter_options_get_property (GObject *object,
g_value_set_enum (value, options->region);
break;
+ case PROP_COLOR_MANAGED:
+ g_value_set_boolean (value, options->color_managed);
+ break;
+
case PROP_GAMMA_HACK:
g_value_set_boolean (value, options->gamma_hack);
break;
diff --git a/app/tools/gimpfilteroptions.h b/app/tools/gimpfilteroptions.h
index 7916ccf..758d646 100644
--- a/app/tools/gimpfilteroptions.h
+++ b/app/tools/gimpfilteroptions.h
@@ -41,6 +41,7 @@ struct _GimpFilterOptions
GimpAlignmentType preview_alignment;
gdouble preview_position;
GimpFilterRegion region;
+ gboolean color_managed;
gboolean gamma_hack;
GFile *settings;
diff --git a/app/tools/gimpfiltertool.c b/app/tools/gimpfiltertool.c
index 4858e70..37f6a9b 100644
--- a/app/tools/gimpfiltertool.c
+++ b/app/tools/gimpfiltertool.c
@@ -332,6 +332,10 @@ gimp_filter_tool_initialize (GimpTool *tool,
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *toggle;
+ GtkWidget *expander;
+ GtkWidget *frame;
+ GtkWidget *vbox2;
+ GtkWidget *combo;
gchar *operation_name;
/* disabled for at least GIMP 2.8 */
@@ -400,12 +404,6 @@ gimp_filter_tool_initialize (GimpTool *tool,
gtk_widget_show (settings_ui);
}
- /* The gamma hack toggle */
- toggle = gimp_prop_check_button_new (G_OBJECT (tool_info->tool_options),
- "gamma-hack", NULL);
- gtk_box_pack_end (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
- gtk_widget_show (toggle);
-
/* The preview and split view toggles */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
@@ -425,6 +423,33 @@ gimp_filter_tool_initialize (GimpTool *tool,
toggle, "sensitive",
G_BINDING_SYNC_CREATE);
+ /* The Color Options expander */
+ expander = gtk_expander_new (_("Advanced Color Options"));
+ gtk_box_pack_end (GTK_BOX (vbox), expander, FALSE, FALSE, 0);
+ gtk_widget_show (expander);
+
+ frame = gimp_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (expander), frame);
+ gtk_widget_show (frame);
+
+ vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
+ gtk_container_add (GTK_CONTAINER (frame), vbox2);
+ gtk_widget_show (vbox2);
+
+ /* The color managed combo */
+ combo = gimp_prop_boolean_combo_box_new
+ (G_OBJECT (tool_info->tool_options), "color-managed",
+ _("Apply filter in color managed space (slow)"),
+ _("Apply filter to the layer's raw pixels"));
+ gtk_box_pack_start (GTK_BOX (vbox2), combo, FALSE, FALSE, 0);
+ gtk_widget_show (combo);
+
+ /* The gamma hack toggle */
+ toggle = gimp_prop_check_button_new (G_OBJECT (tool_info->tool_options),
+ "gamma-hack", NULL);
+ gtk_box_pack_start (GTK_BOX (vbox2), toggle, FALSE, FALSE, 0);
+ gtk_widget_show (toggle);
+
/* The area combo */
gegl_node_get (filter_tool->operation,
"operation", &operation_name,
@@ -780,6 +805,12 @@ gimp_filter_tool_options_notify (GimpTool *tool,
gimp_drawable_filter_set_region (filter_tool->filter,
filter_options->region);
}
+ else if (! strcmp (pspec->name, "color-managed") &&
+ filter_tool->filter)
+ {
+ gimp_drawable_filter_set_color_managed (filter_tool->filter,
+ filter_options->color_managed);
+ }
else if (! strcmp (pspec->name, "gamma-hack") &&
filter_tool->filter)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]