Bug 751553 - Linear precision doesn't display the image correctly
When converting and image with a color profileimage between linear and gamma, create a new profile using the new API in GimpColorProfile, convert the layers to that profile and tag the image with the new profile. If creating a new profile fails, convert to the right builtin profile (linear rgb or sRGB from GimpColorProfile), but that code should be considered a fallback that will be prevented from happening in the convert dialog (at least the user will be informed).
This commit is contained in:
@ -20,15 +20,19 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cairo.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gegl.h>
|
||||
|
||||
#include "libgimpcolor/gimpcolor.h"
|
||||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "gegl/gimp-gegl-utils.h"
|
||||
#include "gegl/gimp-babl.h"
|
||||
|
||||
#include "gimpdrawable.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-color-profile.h"
|
||||
#include "gimpimage-convert-precision.h"
|
||||
#include "gimpimage-undo.h"
|
||||
#include "gimpimage-undo-push.h"
|
||||
@ -47,10 +51,13 @@ gimp_image_convert_precision (GimpImage *image,
|
||||
gint mask_dither_type,
|
||||
GimpProgress *progress)
|
||||
{
|
||||
GList *all_drawables;
|
||||
GList *list;
|
||||
const gchar *undo_desc = NULL;
|
||||
gint nth_drawable, n_drawables;
|
||||
GimpColorProfile *old_profile;
|
||||
const Babl *old_format;
|
||||
const Babl *new_format;
|
||||
GList *all_drawables;
|
||||
GList *list;
|
||||
const gchar *undo_desc = NULL;
|
||||
gint nth_drawable, n_drawables;
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (image));
|
||||
g_return_if_fail (precision != gimp_image_get_precision (image));
|
||||
@ -114,9 +121,14 @@ gimp_image_convert_precision (GimpImage *image,
|
||||
/* Push the image precision to the stack */
|
||||
gimp_image_undo_push_image_precision (image, NULL);
|
||||
|
||||
old_profile = gimp_image_get_color_profile (image);
|
||||
old_format = gimp_image_get_layer_format (image, FALSE);
|
||||
|
||||
/* Set the new precision */
|
||||
g_object_set (image, "precision", precision, NULL);
|
||||
|
||||
new_format = gimp_image_get_layer_format (image, FALSE);
|
||||
|
||||
for (list = all_drawables, nth_drawable = 0;
|
||||
list;
|
||||
list = g_list_next (list), nth_drawable++)
|
||||
@ -134,15 +146,42 @@ gimp_image_convert_precision (GimpImage *image,
|
||||
precision,
|
||||
dither_type,
|
||||
mask_dither_type,
|
||||
FALSE,
|
||||
old_profile != NULL,
|
||||
TRUE);
|
||||
|
||||
if (progress)
|
||||
gimp_progress_set_value (progress,
|
||||
(gdouble) nth_drawable / (gdouble) n_drawables);
|
||||
}
|
||||
|
||||
g_list_free (all_drawables);
|
||||
|
||||
if (old_profile &&
|
||||
gimp_babl_format_get_linear (old_format) !=
|
||||
gimp_babl_format_get_linear (new_format))
|
||||
{
|
||||
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_rgb_from_color_profile (old_profile);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_profile =
|
||||
gimp_color_profile_new_srgb_gamma_from_color_profile (old_profile);
|
||||
}
|
||||
|
||||
gimp_image_set_color_profile (image, new_profile, NULL);
|
||||
|
||||
if (new_profile)
|
||||
g_object_unref (new_profile);
|
||||
}
|
||||
|
||||
/* convert the selection mask */
|
||||
{
|
||||
GimpChannel *mask = gimp_image_get_mask (image);
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "config/gimpcoreconfig.h" /* FIXME profile convert config */
|
||||
|
||||
#include "gegl/gimp-babl.h"
|
||||
#include "gegl/gimp-gegl-apply-operation.h"
|
||||
#include "gegl/gimp-gegl-loops.h"
|
||||
#include "gegl/gimp-gegl-nodes.h"
|
||||
@ -46,6 +47,7 @@
|
||||
#include "gimpimage-undo-push.h"
|
||||
#include "gimpimage-undo.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-color-profile.h"
|
||||
#include "gimplayer-floating-sel.h"
|
||||
#include "gimplayer.h"
|
||||
#include "gimplayermask.h"
|
||||
@ -1103,11 +1105,55 @@ gimp_layer_convert_type (GimpDrawable *drawable,
|
||||
|
||||
if (convert_profile)
|
||||
{
|
||||
src_profile =
|
||||
gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer));
|
||||
GimpImage *src_image = gimp_item_get_image (GIMP_ITEM (layer));
|
||||
|
||||
dest_profile =
|
||||
gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (dest_image));
|
||||
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);
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
if (gimp_babl_format_get_linear (src_format) !=
|
||||
gimp_babl_format_get_linear (new_format))
|
||||
{
|
||||
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_rgb_from_color_profile (src_profile);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest_profile =
|
||||
gimp_color_profile_new_srgb_gamma_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (src_profile && dest_profile)
|
||||
@ -1122,6 +1168,9 @@ 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);
|
||||
|
Reference in New Issue
Block a user