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 "config.h"
|
||||||
|
|
||||||
|
#include <cairo.h>
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
#include <gegl.h>
|
#include <gegl.h>
|
||||||
|
|
||||||
|
#include "libgimpcolor/gimpcolor.h"
|
||||||
|
|
||||||
#include "core-types.h"
|
#include "core-types.h"
|
||||||
|
|
||||||
#include "gegl/gimp-gegl-utils.h"
|
#include "gegl/gimp-babl.h"
|
||||||
|
|
||||||
#include "gimpdrawable.h"
|
#include "gimpdrawable.h"
|
||||||
#include "gimpimage.h"
|
#include "gimpimage.h"
|
||||||
|
#include "gimpimage-color-profile.h"
|
||||||
#include "gimpimage-convert-precision.h"
|
#include "gimpimage-convert-precision.h"
|
||||||
#include "gimpimage-undo.h"
|
#include "gimpimage-undo.h"
|
||||||
#include "gimpimage-undo-push.h"
|
#include "gimpimage-undo-push.h"
|
||||||
@ -47,10 +51,13 @@ gimp_image_convert_precision (GimpImage *image,
|
|||||||
gint mask_dither_type,
|
gint mask_dither_type,
|
||||||
GimpProgress *progress)
|
GimpProgress *progress)
|
||||||
{
|
{
|
||||||
GList *all_drawables;
|
GimpColorProfile *old_profile;
|
||||||
GList *list;
|
const Babl *old_format;
|
||||||
const gchar *undo_desc = NULL;
|
const Babl *new_format;
|
||||||
gint nth_drawable, n_drawables;
|
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 (GIMP_IS_IMAGE (image));
|
||||||
g_return_if_fail (precision != gimp_image_get_precision (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 */
|
/* Push the image precision to the stack */
|
||||||
gimp_image_undo_push_image_precision (image, NULL);
|
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 */
|
/* Set the new precision */
|
||||||
g_object_set (image, "precision", precision, NULL);
|
g_object_set (image, "precision", precision, NULL);
|
||||||
|
|
||||||
|
new_format = gimp_image_get_layer_format (image, FALSE);
|
||||||
|
|
||||||
for (list = all_drawables, nth_drawable = 0;
|
for (list = all_drawables, nth_drawable = 0;
|
||||||
list;
|
list;
|
||||||
list = g_list_next (list), nth_drawable++)
|
list = g_list_next (list), nth_drawable++)
|
||||||
@ -134,15 +146,42 @@ gimp_image_convert_precision (GimpImage *image,
|
|||||||
precision,
|
precision,
|
||||||
dither_type,
|
dither_type,
|
||||||
mask_dither_type,
|
mask_dither_type,
|
||||||
FALSE,
|
old_profile != NULL,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
if (progress)
|
if (progress)
|
||||||
gimp_progress_set_value (progress,
|
gimp_progress_set_value (progress,
|
||||||
(gdouble) nth_drawable / (gdouble) n_drawables);
|
(gdouble) nth_drawable / (gdouble) n_drawables);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_free (all_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 */
|
/* convert the selection mask */
|
||||||
{
|
{
|
||||||
GimpChannel *mask = gimp_image_get_mask (image);
|
GimpChannel *mask = gimp_image_get_mask (image);
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "config/gimpcoreconfig.h" /* FIXME profile convert config */
|
#include "config/gimpcoreconfig.h" /* FIXME profile convert config */
|
||||||
|
|
||||||
|
#include "gegl/gimp-babl.h"
|
||||||
#include "gegl/gimp-gegl-apply-operation.h"
|
#include "gegl/gimp-gegl-apply-operation.h"
|
||||||
#include "gegl/gimp-gegl-loops.h"
|
#include "gegl/gimp-gegl-loops.h"
|
||||||
#include "gegl/gimp-gegl-nodes.h"
|
#include "gegl/gimp-gegl-nodes.h"
|
||||||
@ -46,6 +47,7 @@
|
|||||||
#include "gimpimage-undo-push.h"
|
#include "gimpimage-undo-push.h"
|
||||||
#include "gimpimage-undo.h"
|
#include "gimpimage-undo.h"
|
||||||
#include "gimpimage.h"
|
#include "gimpimage.h"
|
||||||
|
#include "gimpimage-color-profile.h"
|
||||||
#include "gimplayer-floating-sel.h"
|
#include "gimplayer-floating-sel.h"
|
||||||
#include "gimplayer.h"
|
#include "gimplayer.h"
|
||||||
#include "gimplayermask.h"
|
#include "gimplayermask.h"
|
||||||
@ -1103,11 +1105,55 @@ gimp_layer_convert_type (GimpDrawable *drawable,
|
|||||||
|
|
||||||
if (convert_profile)
|
if (convert_profile)
|
||||||
{
|
{
|
||||||
src_profile =
|
GimpImage *src_image = gimp_item_get_image (GIMP_ITEM (layer));
|
||||||
gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer));
|
|
||||||
|
|
||||||
dest_profile =
|
if (src_image != dest_image)
|
||||||
gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (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)
|
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);
|
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);
|
gimp_drawable_set_buffer (drawable, push_undo, NULL, dest_buffer);
|
||||||
|
|
||||||
g_object_unref (src_buffer);
|
g_object_unref (src_buffer);
|
||||||
|
Reference in New Issue
Block a user