mirror of https://github.com/GNOME/gimp.git
Bug 768952 - Select by color works correctly only in srgb
Separate clearing/creating the image's cached color transforms from clearing/creating its color profile. Clear the transforms when the color profile changes, and when image type or precision change. Create the transforms only on demand, so clearing them multiple times doesn't trigger any redundant (and expensive) transform creations.
This commit is contained in:
parent
4ea518fee3
commit
f06f691a92
|
@ -68,6 +68,8 @@ static void gimp_image_convert_profile_colormap (GimpImage *ima
|
||||||
gboolean bpc,
|
gboolean bpc,
|
||||||
GimpProgress *progress);
|
GimpProgress *progress);
|
||||||
|
|
||||||
|
static void gimp_image_create_color_transforms (GimpImage *image);
|
||||||
|
|
||||||
|
|
||||||
/* public functions */
|
/* public functions */
|
||||||
|
|
||||||
|
@ -502,6 +504,8 @@ gimp_image_get_color_transform_to_srgb_u8 (GimpImage *image)
|
||||||
|
|
||||||
private = GIMP_IMAGE_GET_PRIVATE (image);
|
private = GIMP_IMAGE_GET_PRIVATE (image);
|
||||||
|
|
||||||
|
gimp_image_create_color_transforms (image);
|
||||||
|
|
||||||
if (private->is_color_managed)
|
if (private->is_color_managed)
|
||||||
return private->transform_to_srgb_u8;
|
return private->transform_to_srgb_u8;
|
||||||
|
|
||||||
|
@ -517,6 +521,8 @@ gimp_image_get_color_transform_from_srgb_u8 (GimpImage *image)
|
||||||
|
|
||||||
private = GIMP_IMAGE_GET_PRIVATE (image);
|
private = GIMP_IMAGE_GET_PRIVATE (image);
|
||||||
|
|
||||||
|
gimp_image_create_color_transforms (image);
|
||||||
|
|
||||||
if (private->is_color_managed)
|
if (private->is_color_managed)
|
||||||
return private->transform_from_srgb_u8;
|
return private->transform_from_srgb_u8;
|
||||||
|
|
||||||
|
@ -532,6 +538,8 @@ gimp_image_get_color_transform_to_srgb_double (GimpImage *image)
|
||||||
|
|
||||||
private = GIMP_IMAGE_GET_PRIVATE (image);
|
private = GIMP_IMAGE_GET_PRIVATE (image);
|
||||||
|
|
||||||
|
gimp_image_create_color_transforms (image);
|
||||||
|
|
||||||
if (private->is_color_managed)
|
if (private->is_color_managed)
|
||||||
return private->transform_to_srgb_double;
|
return private->transform_to_srgb_double;
|
||||||
|
|
||||||
|
@ -547,6 +555,8 @@ gimp_image_get_color_transform_from_srgb_double (GimpImage *image)
|
||||||
|
|
||||||
private = GIMP_IMAGE_GET_PRIVATE (image);
|
private = GIMP_IMAGE_GET_PRIVATE (image);
|
||||||
|
|
||||||
|
gimp_image_create_color_transforms (image);
|
||||||
|
|
||||||
if (private->is_color_managed)
|
if (private->is_color_managed)
|
||||||
return private->transform_from_srgb_double;
|
return private->transform_from_srgb_double;
|
||||||
|
|
||||||
|
@ -559,12 +569,15 @@ gimp_image_color_profile_pixel_to_srgb (GimpImage *image,
|
||||||
gpointer pixel,
|
gpointer pixel,
|
||||||
GimpRGB *color)
|
GimpRGB *color)
|
||||||
{
|
{
|
||||||
GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
|
GimpColorTransform *transform;
|
||||||
|
|
||||||
if (private->is_color_managed &&
|
g_return_if_fail (GIMP_IS_IMAGE (image));
|
||||||
private->transform_to_srgb_double)
|
|
||||||
|
transform = gimp_image_get_color_transform_to_srgb_double (image);
|
||||||
|
|
||||||
|
if (transform)
|
||||||
{
|
{
|
||||||
gimp_color_transform_process_pixels (private->transform_to_srgb_double,
|
gimp_color_transform_process_pixels (transform,
|
||||||
pixel_format,
|
pixel_format,
|
||||||
pixel,
|
pixel,
|
||||||
babl_format ("R'G'B'A double"),
|
babl_format ("R'G'B'A double"),
|
||||||
|
@ -583,15 +596,18 @@ gimp_image_color_profile_srgb_to_pixel (GimpImage *image,
|
||||||
const Babl *pixel_format,
|
const Babl *pixel_format,
|
||||||
gpointer pixel)
|
gpointer pixel)
|
||||||
{
|
{
|
||||||
GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
|
GimpColorTransform *transform;
|
||||||
|
|
||||||
if (private->is_color_managed &&
|
g_return_if_fail (GIMP_IS_IMAGE (image));
|
||||||
private->transform_from_srgb_double)
|
|
||||||
|
transform = gimp_image_get_color_transform_from_srgb_double (image);
|
||||||
|
|
||||||
|
if (transform)
|
||||||
{
|
{
|
||||||
/* for the alpha channel */
|
/* for the alpha channel */
|
||||||
gimp_rgba_get_pixel (color, pixel_format, pixel);
|
gimp_rgba_get_pixel (color, pixel_format, pixel);
|
||||||
|
|
||||||
gimp_color_transform_process_pixels (private->transform_from_srgb_double,
|
gimp_color_transform_process_pixels (transform,
|
||||||
babl_format ("R'G'B'A double"),
|
babl_format ("R'G'B'A double"),
|
||||||
color,
|
color,
|
||||||
pixel_format,
|
pixel_format,
|
||||||
|
@ -618,6 +634,14 @@ _gimp_image_free_color_profile (GimpImage *image)
|
||||||
private->color_profile = NULL;
|
private->color_profile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_gimp_image_free_color_transforms (image);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gimp_image_free_color_transforms (GimpImage *image)
|
||||||
|
{
|
||||||
|
GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
|
||||||
|
|
||||||
if (private->transform_to_srgb_u8)
|
if (private->transform_to_srgb_u8)
|
||||||
{
|
{
|
||||||
g_object_unref (private->transform_to_srgb_u8);
|
g_object_unref (private->transform_to_srgb_u8);
|
||||||
|
@ -641,6 +665,8 @@ _gimp_image_free_color_profile (GimpImage *image)
|
||||||
g_object_unref (private->transform_from_srgb_double);
|
g_object_unref (private->transform_from_srgb_double);
|
||||||
private->transform_from_srgb_double = NULL;
|
private->transform_from_srgb_double = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private->color_transforms_created = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -657,51 +683,6 @@ _gimp_image_update_color_profile (GimpImage *image,
|
||||||
gimp_color_profile_new_from_icc_profile (gimp_parasite_data (icc_parasite),
|
gimp_color_profile_new_from_icc_profile (gimp_parasite_data (icc_parasite),
|
||||||
gimp_parasite_data_size (icc_parasite),
|
gimp_parasite_data_size (icc_parasite),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (private->color_profile)
|
|
||||||
{
|
|
||||||
GimpColorProfile *srgb_profile;
|
|
||||||
GimpColorTransformFlags flags = 0;
|
|
||||||
|
|
||||||
srgb_profile = gimp_color_profile_new_rgb_srgb ();
|
|
||||||
|
|
||||||
flags |= GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE;
|
|
||||||
flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION;
|
|
||||||
|
|
||||||
private->transform_to_srgb_u8 =
|
|
||||||
gimp_color_transform_new (private->color_profile,
|
|
||||||
gimp_image_get_layer_format (image, TRUE),
|
|
||||||
srgb_profile,
|
|
||||||
babl_format ("R'G'B'A u8"),
|
|
||||||
GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
private->transform_from_srgb_u8 =
|
|
||||||
gimp_color_transform_new (srgb_profile,
|
|
||||||
babl_format ("R'G'B'A u8"),
|
|
||||||
private->color_profile,
|
|
||||||
gimp_image_get_layer_format (image, TRUE),
|
|
||||||
GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
private->transform_to_srgb_double =
|
|
||||||
gimp_color_transform_new (private->color_profile,
|
|
||||||
gimp_image_get_layer_format (image, TRUE),
|
|
||||||
srgb_profile,
|
|
||||||
babl_format ("R'G'B'A double"),
|
|
||||||
GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
private->transform_from_srgb_double =
|
|
||||||
gimp_color_transform_new (srgb_profile,
|
|
||||||
babl_format ("R'G'B'A double"),
|
|
||||||
private->color_profile,
|
|
||||||
gimp_image_get_layer_format (image, TRUE),
|
|
||||||
GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
g_object_unref (srgb_profile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gimp_color_managed_profile_changed (GIMP_COLOR_MANAGED (image));
|
gimp_color_managed_profile_changed (GIMP_COLOR_MANAGED (image));
|
||||||
|
@ -815,3 +796,59 @@ gimp_image_convert_profile_colormap (GimpImage *image,
|
||||||
|
|
||||||
g_free (cmap);
|
g_free (cmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_image_create_color_transforms (GimpImage *image)
|
||||||
|
{
|
||||||
|
GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
|
||||||
|
|
||||||
|
if (private->color_profile &&
|
||||||
|
! private->color_transforms_created)
|
||||||
|
{
|
||||||
|
GimpColorProfile *srgb_profile;
|
||||||
|
GimpColorTransformFlags flags = 0;
|
||||||
|
|
||||||
|
g_printerr ("XXXXXX %s XXXXXX\n", G_STRFUNC);
|
||||||
|
|
||||||
|
srgb_profile = gimp_color_profile_new_rgb_srgb ();
|
||||||
|
|
||||||
|
flags |= GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE;
|
||||||
|
flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION;
|
||||||
|
|
||||||
|
private->transform_to_srgb_u8 =
|
||||||
|
gimp_color_transform_new (private->color_profile,
|
||||||
|
gimp_image_get_layer_format (image, TRUE),
|
||||||
|
srgb_profile,
|
||||||
|
babl_format ("R'G'B'A u8"),
|
||||||
|
GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
private->transform_from_srgb_u8 =
|
||||||
|
gimp_color_transform_new (srgb_profile,
|
||||||
|
babl_format ("R'G'B'A u8"),
|
||||||
|
private->color_profile,
|
||||||
|
gimp_image_get_layer_format (image, TRUE),
|
||||||
|
GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
private->transform_to_srgb_double =
|
||||||
|
gimp_color_transform_new (private->color_profile,
|
||||||
|
gimp_image_get_layer_format (image, TRUE),
|
||||||
|
srgb_profile,
|
||||||
|
babl_format ("R'G'B'A double"),
|
||||||
|
GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
private->transform_from_srgb_double =
|
||||||
|
gimp_color_transform_new (srgb_profile,
|
||||||
|
babl_format ("R'G'B'A double"),
|
||||||
|
private->color_profile,
|
||||||
|
gimp_image_get_layer_format (image, TRUE),
|
||||||
|
GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
g_object_unref (srgb_profile);
|
||||||
|
|
||||||
|
private->color_transforms_created = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -105,6 +105,7 @@ void gimp_image_color_profile_srgb_to_pixel
|
||||||
/* internal API, to be called only from gimpimage.c */
|
/* internal API, to be called only from gimpimage.c */
|
||||||
|
|
||||||
void _gimp_image_free_color_profile (GimpImage *image);
|
void _gimp_image_free_color_profile (GimpImage *image);
|
||||||
|
void _gimp_image_free_color_transforms (GimpImage *image);
|
||||||
void _gimp_image_update_color_profile (GimpImage *image,
|
void _gimp_image_update_color_profile (GimpImage *image,
|
||||||
const GimpParasite *icc_parasite);
|
const GimpParasite *icc_parasite);
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ struct _GimpImagePrivate
|
||||||
GimpColorProfile *color_profile; /* image's color profile */
|
GimpColorProfile *color_profile; /* image's color profile */
|
||||||
|
|
||||||
/* Cached color transforms: from layer to sRGB u8 and double, and back */
|
/* Cached color transforms: from layer to sRGB u8 and double, and back */
|
||||||
|
gboolean color_transforms_created;
|
||||||
GimpColorTransform *transform_to_srgb_u8;
|
GimpColorTransform *transform_to_srgb_u8;
|
||||||
GimpColorTransform *transform_from_srgb_u8;
|
GimpColorTransform *transform_from_srgb_u8;
|
||||||
GimpColorTransform *transform_to_srgb_double;
|
GimpColorTransform *transform_to_srgb_double;
|
||||||
|
|
|
@ -865,24 +865,24 @@ gimp_image_set_property (GObject *object,
|
||||||
case PROP_GIMP:
|
case PROP_GIMP:
|
||||||
image->gimp = g_value_get_object (value);
|
image->gimp = g_value_get_object (value);
|
||||||
break;
|
break;
|
||||||
case PROP_ID:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
break;
|
|
||||||
case PROP_WIDTH:
|
case PROP_WIDTH:
|
||||||
private->width = g_value_get_int (value);
|
private->width = g_value_get_int (value);
|
||||||
break;
|
break;
|
||||||
case PROP_HEIGHT:
|
case PROP_HEIGHT:
|
||||||
private->height = g_value_get_int (value);
|
private->height = g_value_get_int (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_BASE_TYPE:
|
case PROP_BASE_TYPE:
|
||||||
private->base_type = g_value_get_enum (value);
|
private->base_type = g_value_get_enum (value);
|
||||||
|
_gimp_image_free_color_transforms (image);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_PRECISION:
|
case PROP_PRECISION:
|
||||||
private->precision = g_value_get_enum (value);
|
private->precision = g_value_get_enum (value);
|
||||||
|
_gimp_image_free_color_transforms (image);
|
||||||
break;
|
break;
|
||||||
case PROP_METADATA:
|
|
||||||
case PROP_BUFFER:
|
|
||||||
break;
|
|
||||||
case PROP_SYMMETRY:
|
case PROP_SYMMETRY:
|
||||||
{
|
{
|
||||||
GList *iter;
|
GList *iter;
|
||||||
|
@ -919,6 +919,10 @@ gimp_image_set_property (GObject *object,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_ID:
|
||||||
|
case PROP_METADATA:
|
||||||
|
case PROP_BUFFER:
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue