Commit ba85bb78 authored by Michael Natterer's avatar Michael Natterer 😴

Bug 727185 - Converting to GIMP built-in sRGB produces the wrong RGB values

Profiles from disk have a lower precision than those created from
scratch via lcms API. Ensure identical profiles by returning a
"loaded" profile from gimp_lcms_create_srgb_profile() (simply do a
save/load roundtrip in memory).
parent 48b01cf2
......@@ -49,6 +49,7 @@ EXPORTS
gimp_lcms_profile_is_rgb
gimp_lcms_profile_open_from_data
gimp_lcms_profile_open_from_file
gimp_lcms_profile_save_to_data
gimp_param_rgb_get_type
gimp_param_spec_rgb
gimp_param_spec_rgb_has_alpha
......
......@@ -111,6 +111,37 @@ gimp_lcms_profile_open_from_data (const guint8 *data,
return profile;
}
guint8 *
gimp_lcms_profile_save_to_data (GimpColorProfile profile,
gsize *length,
GError **error)
{
cmsUInt32Number size;
g_return_val_if_fail (profile != NULL, NULL);
g_return_val_if_fail (length != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
if (cmsSaveProfileToMem (profile, NULL, &size))
{
guint8 *data = g_malloc (size);
if (cmsSaveProfileToMem (profile, data, &size))
{
*length = size;
return data;
}
g_free (data);
}
g_set_error_literal (error, gimp_lcms_error_quark (), 0,
_("Could not save color profile to memory"));
return NULL;
}
static gchar *
gimp_lcms_profile_get_info (GimpColorProfile profile,
cmsInfoType info)
......@@ -289,39 +320,8 @@ gimp_lcms_profile_set_tag (cmsHPROFILE profile,
cmsMLUfree (mlu);
}
/**
* gimp_lcms_create_srgb_profile:
*
* This function is a replacement for cmsCreate_sRGBProfile() and
* returns an sRGB profile that is functionally the same as the
* ArgyllCMS sRGB.icm profile. "Functionally the same" means it has
* the same red, green, and blue colorants and the V4 "chad"
* equivalent of the ArgyllCMS V2 white point. The profile TRC is also
* functionally equivalent to the ArgyllCMS sRGB.icm TRC and is the
* same as the LCMS sRGB built-in profile TRC.
*
* The actual primaries in the sRGB specification are
* red xy: {0.6400, 0.3300, 1.0}
* green xy: {0.3000, 0.6000, 1.0}
* blue xy: {0.1500, 0.0600, 1.0}
*
* The sRGB primaries given below are "pre-quantized" to compensate
* for hexadecimal quantization during the profile-making process.
* Unless the profile-making code compensates for this quantization,
* the resulting profile's red, green, and blue colorants will deviate
* slightly from the correct XYZ values.
*
* LCMS2 doesn't compensate for hexadecimal quantization. The
* "pre-quantized" primaries below were back-calculated from the
* ArgyllCMS sRGB.icm profile. The resulting sRGB profile's colorants
* exactly matches the ArgyllCMS sRGB.icm profile colorants.
*
* Return value: the sRGB cmsHPROFILE.
*
* Since: GIMP 2.10
**/
GimpColorProfile
gimp_lcms_create_srgb_profile (void)
static GimpColorProfile
gimp_lcms_create_srgb_profile_internal (void)
{
cmsHPROFILE srgb_profile;
cmsCIExyY d65_srgb_specs = { 0.3127, 0.3290, 1.0 };
......@@ -371,3 +371,55 @@ gimp_lcms_create_srgb_profile (void)
return srgb_profile;
}
/**
* gimp_lcms_create_srgb_profile:
*
* This function is a replacement for cmsCreate_sRGBProfile() and
* returns an sRGB profile that is functionally the same as the
* ArgyllCMS sRGB.icm profile. "Functionally the same" means it has
* the same red, green, and blue colorants and the V4 "chad"
* equivalent of the ArgyllCMS V2 white point. The profile TRC is also
* functionally equivalent to the ArgyllCMS sRGB.icm TRC and is the
* same as the LCMS sRGB built-in profile TRC.
*
* The actual primaries in the sRGB specification are
* red xy: {0.6400, 0.3300, 1.0}
* green xy: {0.3000, 0.6000, 1.0}
* blue xy: {0.1500, 0.0600, 1.0}
*
* The sRGB primaries given below are "pre-quantized" to compensate
* for hexadecimal quantization during the profile-making process.
* Unless the profile-making code compensates for this quantization,
* the resulting profile's red, green, and blue colorants will deviate
* slightly from the correct XYZ values.
*
* LCMS2 doesn't compensate for hexadecimal quantization. The
* "pre-quantized" primaries below were back-calculated from the
* ArgyllCMS sRGB.icm profile. The resulting sRGB profile's colorants
* exactly matches the ArgyllCMS sRGB.icm profile colorants.
*
* Return value: the sRGB cmsHPROFILE.
*
* Since: GIMP 2.10
**/
GimpColorProfile
gimp_lcms_create_srgb_profile (void)
{
static guint8 *profile_data = NULL;
static gsize profile_length = 0;
if (G_UNLIKELY (profile_data == NULL))
{
GimpColorProfile profile;
profile = gimp_lcms_create_srgb_profile_internal ();
profile_data = gimp_lcms_profile_save_to_data (profile, &profile_length,
NULL);
cmsCloseProfile (profile);
}
return gimp_lcms_profile_open_from_data (profile_data, profile_length, NULL);
}
......@@ -40,6 +40,9 @@ GimpColorProfile gimp_lcms_profile_open_from_file (const gchar *filena
GimpColorProfile gimp_lcms_profile_open_from_data (const guint8 *data,
gsize length,
GError **error);
guint8 * gimp_lcms_profile_save_to_data (GimpColorProfile profile,
gsize *length,
GError **error);
gchar * gimp_lcms_profile_get_description (GimpColorProfile profile);
gchar * gimp_lcms_profile_get_manufacturer (GimpColorProfile profile);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment