From ef4ab94a1258929a9e365b8494d4d5e829df3636 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Fri, 29 Apr 2016 00:42:42 +0200 Subject: [PATCH] app: change GimpDrawable::convert_type() to take a target profile instead of just a boolean "convert_profile". This takes the logic to figure the right target profile out of gimp_layer_convert_type(), it can't possibly know everything about how to convert anyway, and having the logic in the callers conveniently splits it up and distributes its parts to the places they belong. This commit should cause no behavor change and is just preparation for fixing bug 765176. --- app/core/gimpchannel.c | 6 +- app/core/gimpdrawable.c | 14 ++-- app/core/gimpdrawable.h | 4 +- app/core/gimpgrouplayer.c | 7 +- app/core/gimpimage-convert-precision.c | 60 ++++++++------ app/core/gimpimage-convert-type.c | 25 ++++-- app/core/gimplayer.c | 105 +++++-------------------- app/core/gimplayermask.c | 6 +- app/core/gimpselection.c | 6 +- app/text/gimptextlayer.c | 6 +- app/text/gimptextundo.c | 2 +- 11 files changed, 98 insertions(+), 143 deletions(-) diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c index c37d14dde9..68a619c473 100644 --- a/app/core/gimpchannel.c +++ b/app/core/gimpchannel.c @@ -147,9 +147,9 @@ static void gimp_channel_convert_type (GimpDrawable *drawable, const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress); static void gimp_channel_invalidate_boundary (GimpDrawable *drawable); @@ -569,7 +569,7 @@ gimp_channel_convert (GimpItem *item, { gimp_drawable_convert_type (drawable, dest_image, GIMP_GRAY, gimp_image_get_precision (dest_image), - 0, 0, FALSE, + NULL, 0, 0, FALSE, NULL); } @@ -945,9 +945,9 @@ gimp_channel_convert_type (GimpDrawable *drawable, const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress) { diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c index 6d2cbad0e4..3753eae6b0 100644 --- a/app/core/gimpdrawable.c +++ b/app/core/gimpdrawable.c @@ -19,7 +19,6 @@ #include #include -#include /* gegl_operation_invalidate() */ #include #include "libgimpbase/gimpbase.h" @@ -152,9 +151,9 @@ static void gimp_drawable_real_convert_type (GimpDrawable *drawable, const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress); @@ -765,7 +764,7 @@ gimp_drawable_real_estimate_memsize (const GimpDrawable *drawable, } /* FIXME: this default impl is currently unused because no subclass - * chins up. the goal is to handle the almost identical subclass code + * chains up. the goal is to handle the almost identical subclass code * here again. */ static void @@ -774,9 +773,9 @@ gimp_drawable_real_convert_type (GimpDrawable *drawable, const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress) { @@ -1244,9 +1243,9 @@ gimp_drawable_convert_type (GimpDrawable *drawable, GimpImage *dest_image, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress) { @@ -1256,7 +1255,8 @@ gimp_drawable_convert_type (GimpDrawable *drawable, g_return_if_fail (GIMP_IS_IMAGE (dest_image)); g_return_if_fail (new_base_type != gimp_drawable_get_base_type (drawable) || new_precision != gimp_drawable_get_precision (drawable) || - convert_profile); + dest_profile); + g_return_if_fail (dest_profile == NULL || GIMP_IS_COLOR_PROFILE (dest_profile)); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); if (! gimp_item_is_attached (GIMP_ITEM (drawable))) @@ -1271,9 +1271,9 @@ gimp_drawable_convert_type (GimpDrawable *drawable, new_format, new_base_type, new_precision, + dest_profile, layer_dither_type, mask_dither_type, - convert_profile, push_undo, progress); diff --git a/app/core/gimpdrawable.h b/app/core/gimpdrawable.h index 5d72328955..3cb35e3f5b 100644 --- a/app/core/gimpdrawable.h +++ b/app/core/gimpdrawable.h @@ -66,9 +66,9 @@ struct _GimpDrawableClass const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress); void (* apply_buffer) (GimpDrawable *drawable, @@ -144,9 +144,9 @@ void gimp_drawable_convert_type (GimpDrawable *drawable, GimpImage *dest_image, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress); diff --git a/app/core/gimpgrouplayer.c b/app/core/gimpgrouplayer.c index b47f7ff0cb..122daad730 100644 --- a/app/core/gimpgrouplayer.c +++ b/app/core/gimpgrouplayer.c @@ -141,9 +141,9 @@ static void gimp_group_layer_convert_type (GimpDrawable *drawabl const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress); @@ -881,9 +881,9 @@ gimp_group_layer_convert_type (GimpDrawable *drawable, const Babl *new_format /* unused */, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress) { @@ -927,8 +927,7 @@ gimp_group_layer_convert_type (GimpDrawable *drawable, { gimp_drawable_convert_type (GIMP_DRAWABLE (mask), dest_image, GIMP_GRAY, new_precision, - layer_dither_type, mask_dither_type, - convert_profile, + NULL, layer_dither_type, mask_dither_type, push_undo, progress); } } diff --git a/app/core/gimpimage-convert-precision.c b/app/core/gimpimage-convert-precision.c index 4b3770453e..6553a33e7f 100644 --- a/app/core/gimpimage-convert-precision.c +++ b/app/core/gimpimage-convert-precision.c @@ -53,6 +53,7 @@ gimp_image_convert_precision (GimpImage *image, GimpProgress *progress) { GimpColorProfile *old_profile; + GimpColorProfile *new_profile = NULL; const Babl *old_format; const Babl *new_format; GList *all_drawables; @@ -134,6 +135,39 @@ gimp_image_convert_precision (GimpImage *image, new_format = gimp_image_get_layer_format (image, FALSE); + if (old_profile && + gimp_babl_format_get_linear (old_format) != + gimp_babl_format_get_linear (new_format)) + { + GimpColorProfile *new_profile; + + /* when converting between linear and gamma, we create a new + * profile using the original profile's chromacities and + * whitepoint, but a linear/sRGB-gamma TRC. + */ + + if (gimp_babl_format_get_linear (new_format)) + { + new_profile = + gimp_color_profile_new_linear_from_color_profile (old_profile); + } + else + { + new_profile = + gimp_color_profile_new_srgb_trc_from_color_profile (old_profile); + } + + /* if a new profile cannot be be generated, convert to the + * builtin profile, which is better than leaving the user with + * broken colors + */ + if (! new_profile) + { + new_profile = gimp_image_get_builtin_color_profile (image); + g_object_ref (new_profile); + } + } + for (list = all_drawables, nth_drawable = 0; list; list = g_list_next (list), nth_drawable++) @@ -153,38 +187,18 @@ gimp_image_convert_precision (GimpImage *image, gimp_drawable_convert_type (drawable, image, gimp_drawable_get_base_type (drawable), precision, + new_profile, dither_type, mask_dither_type, - old_profile != NULL, TRUE, sub_progress); } g_list_free (all_drawables); - if (old_profile && - gimp_babl_format_get_linear (old_format) != - gimp_babl_format_get_linear (new_format)) + if (old_profile) { - GimpColorProfile *new_profile; - - /* the comments in gimp_layer_convert_type() explain the logic - * here - */ - if (gimp_babl_format_get_linear (new_format)) - { - new_profile = - gimp_color_profile_new_linear_from_color_profile (old_profile); - } - else - { - new_profile = - gimp_color_profile_new_srgb_trc_from_color_profile (old_profile); - } - gimp_image_set_color_profile (image, new_profile, NULL); - - if (new_profile) - g_object_unref (new_profile); + g_object_unref (new_profile); } /* convert the selection mask */ diff --git a/app/core/gimpimage-convert-type.c b/app/core/gimpimage-convert-type.c index 6f2c24d0b2..ef5704cb2c 100644 --- a/app/core/gimpimage-convert-type.c +++ b/app/core/gimpimage-convert-type.c @@ -766,7 +766,8 @@ gimp_image_convert_type (GimpImage *image, GimpImageBaseType old_type; GList *all_layers; GList *list; - const gchar *undo_desc = NULL; + const gchar *undo_desc = NULL; + GimpColorProfile *dest_profile = NULL; gint nth_layer; gint n_layers; @@ -827,6 +828,18 @@ gimp_image_convert_type (GimpImage *image, g_object_set (image, "base-type", new_type, NULL); + if (gimp_image_get_color_profile (image)) + { + if (old_type == GIMP_GRAY || + new_type == GIMP_GRAY) + { + /* when converting to/from GRAY, convert to the new + * type's builtin profile. + */ + dest_profile = gimp_image_get_builtin_color_profile (image); + } + } + /* Convert to indexed? Build histogram if necessary. */ if (new_type == GIMP_INDEXED) { @@ -1021,7 +1034,7 @@ gimp_image_convert_type (GimpImage *image, { gimp_drawable_convert_type (GIMP_DRAWABLE (layer), image, new_type, gimp_drawable_get_precision (GIMP_DRAWABLE (layer)), - 0, 0, TRUE, + dest_profile, 0, 0, TRUE, NULL); } } @@ -1077,9 +1090,7 @@ gimp_image_convert_type (GimpImage *image, break; } - /* When converting to/from GRAY, remove the profile. - * gimp_layer_convert_type() has converted the layers to - * new_type's builtin profile. + /* When converting to/from GRAY, set the new profile. */ switch (new_type) { @@ -1088,7 +1099,7 @@ gimp_image_convert_type (GimpImage *image, if (old_type == GIMP_GRAY) { if (gimp_image_get_color_profile (image)) - gimp_image_set_color_profile (image, NULL, NULL); + gimp_image_set_color_profile (image, dest_profile, NULL); else gimp_color_managed_profile_changed (GIMP_COLOR_MANAGED (image)); } @@ -1096,7 +1107,7 @@ gimp_image_convert_type (GimpImage *image, case GIMP_GRAY: if (gimp_image_get_color_profile (image)) - gimp_image_set_color_profile (image, NULL, NULL); + gimp_image_set_color_profile (image, dest_profile, NULL); else gimp_color_managed_profile_changed (GIMP_COLOR_MANAGED (image)); break; diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c index b6f313e2dc..6c62f4a0a8 100644 --- a/app/core/gimplayer.c +++ b/app/core/gimplayer.c @@ -171,9 +171,9 @@ static void gimp_layer_convert_type (GimpDrawable *drawable, const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress); static void gimp_layer_invalidate_boundary (GimpDrawable *drawable); @@ -791,7 +791,7 @@ gimp_layer_convert (GimpItem *item, GimpImageBaseType new_base_type; GimpPrecision old_precision; GimpPrecision new_precision; - gboolean convert_profile; + GimpColorProfile *dest_profile = NULL; old_base_type = gimp_drawable_get_base_type (drawable); new_base_type = gimp_image_get_base_type (dest_image); @@ -799,20 +799,24 @@ gimp_layer_convert (GimpItem *item, old_precision = gimp_drawable_get_precision (drawable); new_precision = gimp_image_get_precision (dest_image); - convert_profile = (g_type_is_a (old_type, GIMP_TYPE_LAYER) && - /* FIXME: this is the wrong check, need - * something like file import conversion config - */ - (config->mode != GIMP_COLOR_MANAGEMENT_OFF)); + if (g_type_is_a (old_type, GIMP_TYPE_LAYER) && + /* FIXME: this is the wrong check, need + * something like file import conversion config + */ + (config->mode != GIMP_COLOR_MANAGEMENT_OFF)) + { + dest_profile = + gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (dest_image)); + } if (old_base_type != new_base_type || old_precision != new_precision || - convert_profile) + dest_profile) { gimp_drawable_convert_type (drawable, dest_image, new_base_type, new_precision, + dest_profile, 0, 0, - convert_profile, FALSE, NULL); } @@ -1065,17 +1069,15 @@ gimp_layer_convert_type (GimpDrawable *drawable, const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress) { GimpLayer *layer = GIMP_LAYER (drawable); GeglBuffer *src_buffer; GeglBuffer *dest_buffer; - GimpColorProfile *src_profile = NULL; - GimpColorProfile *dest_profile = NULL; if (layer_dither_type == 0) { @@ -1105,79 +1107,11 @@ gimp_layer_convert_type (GimpDrawable *drawable, gimp_item_get_height (GIMP_ITEM (drawable))), new_format); - if (convert_profile) + if (dest_profile) { - GimpImage *src_image = gimp_item_get_image (GIMP_ITEM (layer)); + GimpColorProfile *src_profile = + gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer)); - if (src_image != dest_image) - { - src_profile = - gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer)); - - dest_profile = - gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (dest_image)); - g_object_ref (dest_profile); - } - else if (gimp_image_get_color_profile (src_image)) - { - const Babl *src_format = gimp_drawable_get_format (drawable); - - if (gimp_babl_format_get_linear (src_format) != - gimp_babl_format_get_linear (new_format)) - { - /* when converting between linear and gamma, we create a - * new profile using the original profile's chromacities - * and whitepoint, but a linear/sRGB-gamma TRC. - * gimp_image_convert_precision() will use the same - * profile. - */ - - src_profile = - gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer)); - - if (gimp_babl_format_get_linear (new_format)) - { - dest_profile = - gimp_color_profile_new_linear_from_color_profile (src_profile); - } - else - { - dest_profile = - gimp_color_profile_new_srgb_trc_from_color_profile (src_profile); - } - - /* if a new profile cannot be be generated, convert to - * the builtin profile, which is better than leaving the - * user with broken colors - */ - if (! dest_profile) - { - dest_profile = - gimp_image_get_builtin_color_profile (dest_image); - g_object_ref (dest_profile); - } - } - else if (gimp_drawable_get_base_type (drawable) != new_base_type && - (gimp_drawable_get_base_type (drawable) == GIMP_GRAY || - new_base_type == GIMP_GRAY)) - { - /* when converting to/from GRAY, convert to the new - * type's builtin profile because the conversion will - * get rid of the profile, see gimp_image_convert_type(). - */ - - src_profile = - gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer)); - - dest_profile = - gimp_image_get_builtin_color_profile (dest_image); - g_object_ref (dest_profile); - } - } - } - - if (src_profile && dest_profile) - { gimp_gegl_convert_color_profile (src_buffer, NULL, src_profile, dest_buffer, NULL, dest_profile, GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL, @@ -1188,9 +1122,6 @@ gimp_layer_convert_type (GimpDrawable *drawable, gegl_buffer_copy (src_buffer, NULL, GEGL_ABYSS_NONE, dest_buffer, NULL); } - if (dest_profile) - g_object_unref (dest_profile); - gimp_drawable_set_buffer (drawable, push_undo, NULL, dest_buffer); g_object_unref (src_buffer); @@ -1201,8 +1132,8 @@ gimp_layer_convert_type (GimpDrawable *drawable, { gimp_drawable_convert_type (GIMP_DRAWABLE (layer->mask), dest_image, GIMP_GRAY, new_precision, + NULL, layer_dither_type, mask_dither_type, - convert_profile, push_undo, NULL); } } diff --git a/app/core/gimplayermask.c b/app/core/gimplayermask.c index 0dd516ebde..435a60da3f 100644 --- a/app/core/gimplayermask.c +++ b/app/core/gimplayermask.c @@ -54,9 +54,9 @@ static void gimp_layer_mask_convert_type (GimpDrawable *dr const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress); @@ -168,9 +168,9 @@ gimp_layer_mask_convert_type (GimpDrawable *drawable, const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress) { @@ -180,9 +180,9 @@ gimp_layer_mask_convert_type (GimpDrawable *drawable, new_format, new_base_type, new_precision, + dest_profile, layer_dither_type, mask_dither_type, - convert_profile, push_undo, progress); } diff --git a/app/core/gimpselection.c b/app/core/gimpselection.c index 9c6441264e..0ab9763b93 100644 --- a/app/core/gimpselection.c +++ b/app/core/gimpselection.c @@ -92,9 +92,9 @@ static void gimp_selection_convert_type (GimpDrawable *drawable, const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress); static void gimp_selection_invalidate_boundary (GimpDrawable *drawable); @@ -356,9 +356,9 @@ gimp_selection_convert_type (GimpDrawable *drawable, const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress) { @@ -368,9 +368,9 @@ gimp_selection_convert_type (GimpDrawable *drawable, new_format, new_base_type, new_precision, + dest_profile, layer_dither_type, mask_dither_type, - convert_profile, push_undo, progress); } diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c index e1f76ff168..55cb63d505 100644 --- a/app/text/gimptextlayer.c +++ b/app/text/gimptextlayer.c @@ -89,9 +89,9 @@ static void gimp_text_layer_convert_type (GimpDrawable *drawable, const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress); static void gimp_text_layer_set_buffer (GimpDrawable *drawable, @@ -321,9 +321,9 @@ gimp_text_layer_convert_type (GimpDrawable *drawable, const Babl *new_format, GimpImageBaseType new_base_type, GimpPrecision new_precision, + GimpColorProfile *dest_profile, gint layer_dither_type, gint mask_dither_type, - gboolean convert_profile, gboolean push_undo, GimpProgress *progress) { @@ -336,9 +336,9 @@ gimp_text_layer_convert_type (GimpDrawable *drawable, new_format, new_base_type, new_precision, + dest_profile, layer_dither_type, mask_dither_type, - convert_profile, push_undo, progress); } diff --git a/app/text/gimptextundo.c b/app/text/gimptextundo.c index af551b85db..7e7856618a 100644 --- a/app/text/gimptextundo.c +++ b/app/text/gimptextundo.c @@ -273,7 +273,7 @@ gimp_text_undo_pop (GimpUndo *undo, gimp_item_get_image (GIMP_ITEM (layer)), gimp_babl_format_get_base_type (text_undo->format), gimp_babl_format_get_precision (text_undo->format), - 0, 0, FALSE, + NULL, 0, 0, FALSE, NULL); text_undo->format = format; }