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; }