From 1c81c426ae5273959e2993522655787697fdc498 Mon Sep 17 00:00:00 2001 From: Nikc Date: Sat, 30 Apr 2022 01:51:20 +0000 Subject: [PATCH] Modules: Convert CMYK color selector to babl --- app/widgets/gimpcolordialog.c | 33 ++++ libgimpwidgets/gimpcolornotebook.c | 31 ++++ libgimpwidgets/gimpcolornotebook.h | 4 + libgimpwidgets/gimpcolorselection.c | 27 ++++ libgimpwidgets/gimpcolorselection.h | 5 + libgimpwidgets/gimpcolorselector.c | 28 ++++ libgimpwidgets/gimpcolorselector.h | 10 ++ libgimpwidgets/gimpwidgets.def | 3 + modules/color-selector-cmyk.c | 236 ++++++++++++++-------------- 9 files changed, 261 insertions(+), 116 deletions(-) diff --git a/app/widgets/gimpcolordialog.c b/app/widgets/gimpcolordialog.c index ae9998be93..47a5156b70 100644 --- a/app/widgets/gimpcolordialog.c +++ b/app/widgets/gimpcolordialog.c @@ -34,6 +34,7 @@ #include "core/gimp-palettes.h" #include "core/gimpcontext.h" #include "core/gimpimage.h" +#include "core/gimpimage-color-profile.h" #include "core/gimpimage-colormap.h" #include "core/gimpmarshal.h" #include "core/gimppalettemru.h" @@ -105,6 +106,8 @@ static void gimp_color_dialog_history_selected (GimpColorHistory *history, static void gimp_color_dialog_image_changed (GimpContext *context, GimpImage *image, GimpColorDialog *dialog); +static void gimp_color_dialog_update_simulation(GimpImage *image, + GimpColorDialog *dialog); static void gimp_color_dialog_update (GimpColorDialog *dialog); static void gimp_color_dialog_show (GimpColorDialog *dialog); static void gimp_color_dialog_hide (GimpColorDialog *dialog); @@ -712,6 +715,9 @@ gimp_color_dialog_image_changed (GimpContext *context, g_signal_handlers_disconnect_by_func (dialog->active_image, G_CALLBACK (gimp_color_dialog_update), dialog); + g_signal_handlers_disconnect_by_func (dialog->active_image, + gimp_color_dialog_update_simulation, + dialog); } dialog->active_image = image; if (image) @@ -721,11 +727,38 @@ gimp_color_dialog_image_changed (GimpContext *context, g_signal_connect_swapped (image, "notify::base-type", G_CALLBACK (gimp_color_dialog_update), dialog); + g_signal_connect (image, "simulation-profile-changed", + G_CALLBACK (gimp_color_dialog_update_simulation), + dialog); + g_signal_connect (image, "simulation-intent-changed", + G_CALLBACK (gimp_color_dialog_update_simulation), + dialog); + g_signal_connect (image, "simulation-bpc-changed", + G_CALLBACK (gimp_color_dialog_update_simulation), + dialog); + + gimp_color_dialog_update_simulation (image, dialog); } gimp_color_dialog_update (dialog); } } +static void +gimp_color_dialog_update_simulation (GimpImage *image, + GimpColorDialog *dialog) +{ + g_return_if_fail (GIMP_IS_COLOR_DIALOG (dialog)); + + if (image && GIMP_IS_COLOR_DIALOG (dialog)) + { + gimp_color_selection_set_simulation (GIMP_COLOR_SELECTION (dialog->selection), + gimp_image_get_simulation_profile (image), + gimp_image_get_simulation_intent (image), + gimp_image_get_simulation_bpc (image)); + } +} + + static void gimp_color_dialog_update (GimpColorDialog *dialog) { diff --git a/libgimpwidgets/gimpcolornotebook.c b/libgimpwidgets/gimpcolornotebook.c index 2973704304..1fe2ef7138 100644 --- a/libgimpwidgets/gimpcolornotebook.c +++ b/libgimpwidgets/gimpcolornotebook.c @@ -595,3 +595,34 @@ gimp_color_notebook_get_current_selector (GimpColorNotebook *notebook) return notebook->priv->cur_page; } + +/** + * gimp_color_notebook_set_simulation: + * @notebook: A #GimpColorNotebook widget. + * @profile: A #GimpColorProfile object. + * @intent: A #GimpColorRenderingIntent enum. + * @bpc: A gboolean. + * + * Updates all selectors with the current simulation settings. + * + * Since: 3.0 + **/ +void +gimp_color_notebook_set_simulation (GimpColorNotebook *notebook, + GimpColorProfile *profile, + GimpColorRenderingIntent intent, + gboolean bpc) +{ + GList *list; + + g_return_if_fail (GIMP_IS_COLOR_NOTEBOOK (notebook)); + g_return_if_fail (profile == NULL || GIMP_IS_COLOR_PROFILE (profile)); + + for (list = notebook->priv->selectors; list; list = g_list_next (list)) + { + GimpColorSelector *selector = list->data; + + if (selector) + gimp_color_selector_set_simulation (selector, profile, intent, bpc); + } +} diff --git a/libgimpwidgets/gimpcolornotebook.h b/libgimpwidgets/gimpcolornotebook.h index a90508d36a..6a36578ad2 100644 --- a/libgimpwidgets/gimpcolornotebook.h +++ b/libgimpwidgets/gimpcolornotebook.h @@ -77,6 +77,10 @@ GtkWidget * gimp_color_notebook_set_has_page (GimpColorNotebook GtkWidget * gimp_color_notebook_get_notebook (GimpColorNotebook *notebook); GList * gimp_color_notebook_get_selectors (GimpColorNotebook *notebook); GimpColorSelector * gimp_color_notebook_get_current_selector (GimpColorNotebook *notebook); +void gimp_color_notebook_set_simulation (GimpColorNotebook *notebook, + GimpColorProfile *profile, + GimpColorRenderingIntent intent, + gboolean bpc); G_END_DECLS diff --git a/libgimpwidgets/gimpcolorselection.c b/libgimpwidgets/gimpcolorselection.c index ae489269ec..6ae29a44d4 100644 --- a/libgimpwidgets/gimpcolorselection.c +++ b/libgimpwidgets/gimpcolorselection.c @@ -560,6 +560,33 @@ gimp_color_selection_color_changed (GimpColorSelection *selection) g_signal_emit (selection, selection_signals[COLOR_CHANGED], 0); } +/** + * gimp_color_selection_set_simulation: + * @selection: A #GimpColorSelection widget. + * @profile: A #GimpColorProfile object. + * @intent: A #GimpColorRenderingIntent enum. + * @bpc: A gboolean. + * + * Sets the simulation options to use with this color selection. + * + * Since: 3.0 + */ +void +gimp_color_selection_set_simulation (GimpColorSelection *selection, + GimpColorProfile *profile, + GimpColorRenderingIntent intent, + gboolean bpc) +{ + g_return_if_fail (GIMP_IS_COLOR_SELECTION (selection)); + + gimp_color_notebook_set_simulation (GIMP_COLOR_NOTEBOOK (selection->priv->notebook), + profile, + intent, + bpc); + + g_signal_emit (selection, selection_signals[COLOR_CHANGED], 0); +} + /** * gimp_color_selection_set_config: * @selection: A #GimpColorSelection widget. diff --git a/libgimpwidgets/gimpcolorselection.h b/libgimpwidgets/gimpcolorselection.h index b87a01baa5..4d9f0033f8 100644 --- a/libgimpwidgets/gimpcolorselection.h +++ b/libgimpwidgets/gimpcolorselection.h @@ -89,6 +89,11 @@ void gimp_color_selection_reset (GimpColorSelection *selection); void gimp_color_selection_color_changed (GimpColorSelection *selection); +void gimp_color_selection_set_simulation (GimpColorSelection *selection, + GimpColorProfile *profile, + GimpColorRenderingIntent intent, + gboolean bpc); + void gimp_color_selection_set_config (GimpColorSelection *selection, GimpColorConfig *config); diff --git a/libgimpwidgets/gimpcolorselector.c b/libgimpwidgets/gimpcolorselector.c index 8b330fd550..0f15e92f86 100644 --- a/libgimpwidgets/gimpcolorselector.c +++ b/libgimpwidgets/gimpcolorselector.c @@ -638,3 +638,31 @@ gimp_color_selector_set_config (GimpColorSelector *selector, if (selector_class->set_config) selector_class->set_config (selector, config); } + +/** + * gimp_color_selector_set_simulation + * @selector: a #GimpColorSelector widget. + * @profile: a #GimpColorProfile object. + * @intent: a #GimpColorRenderingIntent enum. + * @bpc: a gboolean. + * + * Sets the simulation options to use with this color selector. + * + * Since: 3.0 + */ +void +gimp_color_selector_set_simulation (GimpColorSelector *selector, + GimpColorProfile *profile, + GimpColorRenderingIntent intent, + gboolean bpc) +{ + GimpColorSelectorClass *selector_class; + + g_return_if_fail (GIMP_IS_COLOR_SELECTOR (selector)); + g_return_if_fail (profile == NULL || GIMP_IS_COLOR_PROFILE (profile)); + + selector_class = GIMP_COLOR_SELECTOR_GET_CLASS (selector); + + if (selector_class->set_simulation) + selector_class->set_simulation (selector, profile, intent, bpc); +} diff --git a/libgimpwidgets/gimpcolorselector.h b/libgimpwidgets/gimpcolorselector.h index 854f596ebd..214f364fee 100644 --- a/libgimpwidgets/gimpcolorselector.h +++ b/libgimpwidgets/gimpcolorselector.h @@ -105,6 +105,11 @@ struct _GimpColorSelectorClass void (* set_config) (GimpColorSelector *selector, GimpColorConfig *config); + void (* set_simulation) (GimpColorSelector *selector, + GimpColorProfile *profile, + GimpColorRenderingIntent intent, + gboolean bpc); + /* signals */ void (* color_changed) (GimpColorSelector *selector, const GimpRGB *rgb, @@ -171,6 +176,11 @@ void gimp_color_selector_emit_model_visible_changed (GimpColorSelector *sele void gimp_color_selector_set_config (GimpColorSelector *selector, GimpColorConfig *config); +void gimp_color_selector_set_simulation (GimpColorSelector *selector, + GimpColorProfile *profile, + GimpColorRenderingIntent intent, + gboolean bpc); + G_END_DECLS diff --git a/libgimpwidgets/gimpwidgets.def b/libgimpwidgets/gimpwidgets.def index e195ecb3a2..5b0b17a45b 100644 --- a/libgimpwidgets/gimpwidgets.def +++ b/libgimpwidgets/gimpwidgets.def @@ -84,6 +84,7 @@ EXPORTS gimp_color_notebook_get_selectors gimp_color_notebook_get_type gimp_color_notebook_set_has_page + gimp_color_notebook_set_simulation gimp_color_profile_chooser_dialog_get_type gimp_color_profile_chooser_dialog_new gimp_color_profile_combo_box_add_file @@ -123,6 +124,7 @@ EXPORTS gimp_color_selection_set_config gimp_color_selection_set_old_color gimp_color_selection_set_show_alpha + gimp_color_selection_set_simulation gimp_color_selector_channel_get_type gimp_color_selector_emit_channel_changed gimp_color_selector_emit_color_changed @@ -141,6 +143,7 @@ EXPORTS gimp_color_selector_set_config gimp_color_selector_set_model_visible gimp_color_selector_set_show_alpha + gimp_color_selector_set_simulation gimp_color_selector_set_toggles_sensitive gimp_color_selector_set_toggles_visible gimp_context_help diff --git a/modules/color-selector-cmyk.c b/modules/color-selector-cmyk.c index 189c91ce49..b8af09190b 100644 --- a/modules/color-selector-cmyk.c +++ b/modules/color-selector-cmyk.c @@ -44,9 +44,10 @@ struct _ColorselCmyk { GimpColorSelector parent_instance; - GimpColorConfig *config; - GimpColorTransform *rgb2cmyk; - GimpColorTransform *cmyk2rgb; + GimpColorConfig *config; + GimpColorProfile *simulation_profile; + GimpColorRenderingIntent simulation_intent; + gboolean simulation_bpc; GimpCMYK cmyk; GtkWidget *scales[4]; @@ -70,6 +71,10 @@ static void colorsel_cmyk_set_color (GimpColorSelector *selector, const GimpHSV *hsv); static void colorsel_cmyk_set_config (GimpColorSelector *selector, GimpColorConfig *config); +static void colorsel_cmyk_set_simulation (GimpColorSelector *selector, + GimpColorProfile *profile, + GimpColorRenderingIntent intent, + gboolean bpc); static void colorsel_cmyk_scale_update (GimpLabelSpin *scale, ColorselCmyk *module); @@ -111,13 +116,14 @@ colorsel_cmyk_class_init (ColorselCmykClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); GimpColorSelectorClass *selector_class = GIMP_COLOR_SELECTOR_CLASS (klass); - object_class->dispose = colorsel_cmyk_dispose; + object_class->dispose = colorsel_cmyk_dispose; - selector_class->name = _("CMYK"); - selector_class->help_id = "gimp-colorselector-cmyk"; - selector_class->icon_name = GIMP_ICON_COLOR_SELECTOR_CMYK; - selector_class->set_color = colorsel_cmyk_set_color; - selector_class->set_config = colorsel_cmyk_set_config; + selector_class->name = _("CMYK"); + selector_class->help_id = "gimp-colorselector-cmyk"; + selector_class->icon_name = GIMP_ICON_COLOR_SELECTOR_CMYK; + selector_class->set_color = colorsel_cmyk_set_color; + selector_class->set_config = colorsel_cmyk_set_config; + selector_class->set_simulation = colorsel_cmyk_set_simulation; gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (klass), "ColorselCmyk"); } @@ -152,9 +158,7 @@ colorsel_cmyk_init (ColorselCmyk *module) N_("Black") }; - module->config = NULL; - module->rgb2cmyk = NULL; - module->cmyk2rgb = NULL; + module->config = NULL; gtk_box_set_spacing (GTK_BOX (module), 6); @@ -198,6 +202,7 @@ colorsel_cmyk_dispose (GObject *object) module->in_destruction = TRUE; colorsel_cmyk_set_config (GIMP_COLOR_SELECTOR (object), NULL); + g_clear_object (&module->simulation_profile); G_OBJECT_CLASS (colorsel_cmyk_parent_class)->dispose (object); } @@ -207,40 +212,34 @@ colorsel_cmyk_set_color (GimpColorSelector *selector, const GimpRGB *rgb, const GimpHSV *hsv) { - ColorselCmyk *module = COLORSEL_CMYK (selector); - gdouble values[4]; - gint i; + GimpColorProfile *cmyk_profile = NULL; + GimpColorRenderingIntent intent = GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC; + const Babl *fish = NULL; + const Babl *space = NULL; + ColorselCmyk *module = COLORSEL_CMYK (selector); + gfloat values[4]; + gint i; - if (module->rgb2cmyk) + /* Try Image Soft-proofing profile first, then default CMYK profile */ + if (module->simulation_profile) + cmyk_profile = module->simulation_profile; + + if (! cmyk_profile && GIMP_IS_COLOR_CONFIG (module->config)) + cmyk_profile = gimp_color_config_get_cmyk_color_profile (GIMP_COLOR_CONFIG (module->config), + NULL); + + if (cmyk_profile && gimp_color_profile_is_cmyk (cmyk_profile)) { - gdouble rgb_values[3]; - gdouble cmyk_values[4]; + intent = module->simulation_intent; - rgb_values[0] = rgb->r; - rgb_values[1] = rgb->g; - rgb_values[2] = rgb->b; - - gimp_color_transform_process_pixels (module->rgb2cmyk, - babl_format ("R'G'B' double"), - rgb_values, - babl_format ("CMYK double"), - cmyk_values, - 1); - - module->cmyk.c = cmyk_values[0] / 100.0; - module->cmyk.m = cmyk_values[1] / 100.0; - module->cmyk.y = cmyk_values[2] / 100.0; - module->cmyk.k = cmyk_values[3] / 100.0; - } - else - { - gimp_rgb_to_cmyk (rgb, 1.0, &module->cmyk); + space = gimp_color_profile_get_space (cmyk_profile, intent, + NULL); } - values[0] = module->cmyk.c * 100.0; - values[1] = module->cmyk.m * 100.0; - values[2] = module->cmyk.y * 100.0; - values[3] = module->cmyk.k * 100.0; + fish = babl_fish (babl_format ("R'G'B'A double"), + babl_format_with_space ("CMYK float", space)); + + babl_process (fish, rgb, values, 1); for (i = 0; i < 4; i++) { @@ -248,12 +247,16 @@ colorsel_cmyk_set_color (GimpColorSelector *selector, colorsel_cmyk_scale_update, module); + values[i] *= 100.0; gimp_label_spin_set_value (GIMP_LABEL_SPIN (module->scales[i]), values[i]); g_signal_handlers_unblock_by_func (module->scales[i], colorsel_cmyk_scale_update, module); } + + if (cmyk_profile && ! module->simulation_profile) + g_object_unref (cmyk_profile); } static void @@ -280,67 +283,91 @@ colorsel_cmyk_set_config (GimpColorSelector *selector, } } +static void +colorsel_cmyk_set_simulation (GimpColorSelector *selector, + GimpColorProfile *profile, + GimpColorRenderingIntent intent, + gboolean bpc) +{ + ColorselCmyk *module = COLORSEL_CMYK (selector); + GimpColorProfile *cmyk_profile = NULL; + gchar *text; + + gtk_label_set_text (GTK_LABEL (module->name_label), _("Profile: (none)")); + gimp_help_set_help_data (module->name_label, NULL, NULL); + + g_set_object (&module->simulation_profile, profile); + + cmyk_profile = module->simulation_profile; + + if (! cmyk_profile && GIMP_IS_COLOR_CONFIG (module->config)) + cmyk_profile = gimp_color_config_get_cmyk_color_profile (GIMP_COLOR_CONFIG (module->config), + NULL); + + if (cmyk_profile && gimp_color_profile_is_cmyk (cmyk_profile)) + { + text = g_strdup_printf (_("Profile: %s"), + gimp_color_profile_get_label (cmyk_profile)); + gtk_label_set_text (GTK_LABEL (module->name_label), text); + g_free (text); + + gimp_help_set_help_data (module->name_label, + gimp_color_profile_get_summary (cmyk_profile), + NULL); + } + + module->simulation_intent = intent; + module->simulation_bpc = bpc; + + if (! module->in_destruction) + colorsel_cmyk_set_color (selector, &selector->rgb, &selector->hsv); +} + static void colorsel_cmyk_scale_update (GimpLabelSpin *scale, ColorselCmyk *module) { - GimpColorSelector *selector = GIMP_COLOR_SELECTOR (module); - gint i; - gdouble value; + GimpColorProfile *cmyk_profile = NULL; + GimpColorSelector *selector = GIMP_COLOR_SELECTOR (module); + GimpColorRenderingIntent intent = GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC; + const Babl *fish = NULL; + const Babl *space = NULL; + gfloat cmyk_values[4]; + gfloat rgb_values[3]; + gint i; for (i = 0; i < 4; i++) - if (GIMP_LABEL_SPIN (module->scales[i]) == scale) - break; + cmyk_values[i] = gimp_label_spin_get_value (GIMP_LABEL_SPIN (module->scales[i])) / 100.0; - value = gimp_label_spin_get_value (scale) / 100.0; + if (module->simulation_profile) + cmyk_profile = module->simulation_profile; - switch (i) + if (! cmyk_profile && GIMP_IS_COLOR_CONFIG (module->config)) + cmyk_profile = gimp_color_config_get_cmyk_color_profile (GIMP_COLOR_CONFIG (module->config), + NULL); + if (cmyk_profile) { - case 0: - module->cmyk.c = value; - break; - case 1: - module->cmyk.m = value; - break; - case 2: - module->cmyk.y = value; - break; - case 3: - module->cmyk.k = value; - break; - default: - return; + intent = module->simulation_intent; + + space = gimp_color_profile_get_space (cmyk_profile, intent, + NULL); } - if (module->cmyk2rgb) - { - gdouble cmyk_values[4]; - gdouble rgb_values[3]; + fish = babl_fish (babl_format_with_space ("CMYK float", space), + babl_format ("R'G'B'A float")); - cmyk_values[0] = module->cmyk.c * 100.0; - cmyk_values[1] = module->cmyk.m * 100.0; - cmyk_values[2] = module->cmyk.y * 100.0; - cmyk_values[3] = module->cmyk.k * 100.0; + babl_process (fish, cmyk_values, rgb_values, 1); - gimp_color_transform_process_pixels (module->cmyk2rgb, - babl_format ("CMYK double"), - cmyk_values, - babl_format ("R'G'B' double"), - rgb_values, - 1); - - selector->rgb.r = rgb_values[0]; - selector->rgb.g = rgb_values[1]; - selector->rgb.b = rgb_values[2]; - } - else - { - gimp_cmyk_to_rgb (&module->cmyk, &selector->rgb); - } + selector->rgb.r = rgb_values[0]; + selector->rgb.g = rgb_values[1]; + selector->rgb.b = rgb_values[2]; gimp_rgb_to_hsv (&selector->rgb, &selector->hsv); gimp_color_selector_emit_color_changed (selector); + + if (cmyk_profile && ! module->simulation_profile) + g_object_unref (cmyk_profile); } static void @@ -348,30 +375,23 @@ colorsel_cmyk_config_changed (ColorselCmyk *module) { GimpColorSelector *selector = GIMP_COLOR_SELECTOR (module); GimpColorConfig *config = module->config; - GimpColorTransformFlags flags = 0; GimpColorProfile *rgb_profile = NULL; GimpColorProfile *cmyk_profile = NULL; gchar *text; - if (module->rgb2cmyk) - { - g_object_unref (module->rgb2cmyk); - module->rgb2cmyk = NULL; - } - - if (module->cmyk2rgb) - { - g_object_unref (module->cmyk2rgb); - module->cmyk2rgb = NULL; - } - gtk_label_set_text (GTK_LABEL (module->name_label), _("Profile: (none)")); gimp_help_set_help_data (module->name_label, NULL, NULL); if (! config) goto out; - cmyk_profile = gimp_color_config_get_cmyk_color_profile (config, NULL); + if (module->simulation_profile) + cmyk_profile = module->simulation_profile; + + if (! cmyk_profile && GIMP_IS_COLOR_CONFIG (module->config)) + cmyk_profile = gimp_color_config_get_cmyk_color_profile (GIMP_COLOR_CONFIG (module->config), + NULL); + if (! cmyk_profile) goto out; @@ -386,28 +406,12 @@ colorsel_cmyk_config_changed (ColorselCmyk *module) gimp_color_profile_get_summary (cmyk_profile), NULL); - flags |= GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE; - flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION; - - module->rgb2cmyk = gimp_color_transform_new (rgb_profile, - babl_format ("R'G'B' double"), - cmyk_profile, - babl_format ("CMYK double"), - GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL, - flags); - module->cmyk2rgb = gimp_color_transform_new (cmyk_profile, - babl_format ("CMYK double"), - rgb_profile, - babl_format ("R'G'B' double"), - GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL, - flags); - out: if (rgb_profile) g_object_unref (rgb_profile); - if (cmyk_profile) + if (cmyk_profile && ! module->simulation_profile) g_object_unref (cmyk_profile); if (! module->in_destruction)