mirror of https://github.com/GNOME/gimp.git
plug-ins: Use GIMP's internal profile when loading EXR
... when it's appropriate.
This commit is contained in:
parent
1c4fc5620f
commit
3d86a6c709
|
@ -302,22 +302,13 @@ load_image (const gchar *filename,
|
|||
*/
|
||||
if (image_type == GIMP_RGB)
|
||||
{
|
||||
cmsHPROFILE lcms_profile;
|
||||
GimpColorProfile *profile;
|
||||
|
||||
lcms_profile = exr_loader_get_icc_profile (loader);
|
||||
if (lcms_profile)
|
||||
profile = exr_loader_get_profile (loader);
|
||||
if (profile)
|
||||
{
|
||||
GimpColorProfile *profile;
|
||||
|
||||
profile = gimp_color_profile_new_from_lcms_profile (lcms_profile,
|
||||
NULL);
|
||||
cmsCloseProfile (lcms_profile);
|
||||
|
||||
if (profile)
|
||||
{
|
||||
gimp_image_set_color_profile (image, profile);
|
||||
g_object_unref (profile);
|
||||
}
|
||||
gimp_image_set_color_profile (image, profile);
|
||||
g_object_unref (profile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
#include "libgimp/gimp.h"
|
||||
#include "libgimp/gimpui.h"
|
||||
#include "libgimpcolor/gimpcolor.h"
|
||||
|
||||
#include "openexr-wrapper.h"
|
||||
|
||||
|
@ -24,6 +25,15 @@ using namespace Imf;
|
|||
using namespace Imf::RgbaYca;
|
||||
using namespace Imath;
|
||||
|
||||
static bool XYZ_equal(cmsCIEXYZ *a, cmsCIEXYZ *b)
|
||||
{
|
||||
static const double epsilon = 0.0001;
|
||||
// Y is encoding the luminance, we normalize that for comparison
|
||||
return fabs ((a->X / a->Y * b->Y) - b->X) < epsilon &&
|
||||
fabs ((a->Y / a->Y * b->Y) - b->Y) < epsilon &&
|
||||
fabs ((a->Z / a->Y * b->Y) - b->Z) < epsilon;
|
||||
}
|
||||
|
||||
struct _EXRLoader
|
||||
{
|
||||
_EXRLoader(const char* filename) :
|
||||
|
@ -172,12 +182,20 @@ struct _EXRLoader
|
|||
return has_alpha_ ? 1 : 0;
|
||||
}
|
||||
|
||||
cmsHPROFILE getICCProfile() const {
|
||||
GimpColorProfile *getProfile() const {
|
||||
Chromaticities chromaticities;
|
||||
float whiteLuminance = 1.0;
|
||||
|
||||
cmsHPROFILE profile = NULL;
|
||||
GimpColorProfile *linear_srgb_profile;
|
||||
cmsHPROFILE linear_srgb_lcms;
|
||||
|
||||
GimpColorProfile *profile;
|
||||
cmsHPROFILE lcms_profile;
|
||||
|
||||
cmsCIEXYZ *gimp_r_XYZ, *gimp_g_XYZ, *gimp_b_XYZ, *gimp_w_XYZ;
|
||||
cmsCIEXYZ exr_r_XYZ, exr_g_XYZ, exr_b_XYZ, exr_w_XYZ;
|
||||
|
||||
// get the color information from the EXR
|
||||
if (hasChromaticities (file_.header ()))
|
||||
chromaticities = Imf::chromaticities (file_.header ());
|
||||
else
|
||||
|
@ -195,6 +213,7 @@ struct _EXRLoader
|
|||
std::cout << "hasWhiteLuminance: "
|
||||
<< hasWhiteLuminance (file_.header ())
|
||||
<< std::endl;
|
||||
std::cout << whiteLuminance << std::endl;
|
||||
std::cout << chromaticities.red << std::endl;
|
||||
std::cout << chromaticities.green << std::endl;
|
||||
std::cout << chromaticities.blue << std::endl;
|
||||
|
@ -202,7 +221,6 @@ struct _EXRLoader
|
|||
std::cout << std::endl;
|
||||
#endif
|
||||
|
||||
// TODO: maybe factor this out into libgimpcolor/gimpcolorprofile.h ?
|
||||
cmsCIExyY whitePoint = { chromaticities.white.x,
|
||||
chromaticities.white.y,
|
||||
whiteLuminance };
|
||||
|
@ -216,29 +234,61 @@ struct _EXRLoader
|
|||
chromaticities.blue.y,
|
||||
whiteLuminance } };
|
||||
|
||||
// get the primaries + wp from GIMP's internal linear sRGB profile
|
||||
linear_srgb_profile = gimp_color_profile_new_rgb_srgb_linear ();
|
||||
linear_srgb_lcms = gimp_color_profile_get_lcms_profile (linear_srgb_profile);
|
||||
|
||||
gimp_r_XYZ = (cmsCIEXYZ *) cmsReadTag (linear_srgb_lcms, cmsSigRedColorantTag);
|
||||
gimp_g_XYZ = (cmsCIEXYZ *) cmsReadTag (linear_srgb_lcms, cmsSigGreenColorantTag);
|
||||
gimp_b_XYZ = (cmsCIEXYZ *) cmsReadTag (linear_srgb_lcms, cmsSigBlueColorantTag);
|
||||
gimp_w_XYZ = (cmsCIEXYZ *) cmsReadTag (linear_srgb_lcms, cmsSigMediaWhitePointTag);
|
||||
|
||||
cmsxyY2XYZ(&exr_r_XYZ, &CameraPrimaries.Red);
|
||||
cmsxyY2XYZ(&exr_g_XYZ, &CameraPrimaries.Green);
|
||||
cmsxyY2XYZ(&exr_b_XYZ, &CameraPrimaries.Blue);
|
||||
cmsxyY2XYZ(&exr_w_XYZ, &whitePoint);
|
||||
|
||||
// ... and check if the data stored in the EXR matches GIMP's internal profile
|
||||
bool exr_is_linear_srgb = XYZ_equal (&exr_r_XYZ, gimp_r_XYZ) &&
|
||||
XYZ_equal (&exr_g_XYZ, gimp_g_XYZ) &&
|
||||
XYZ_equal (&exr_b_XYZ, gimp_b_XYZ) &&
|
||||
XYZ_equal (&exr_w_XYZ, gimp_w_XYZ);
|
||||
|
||||
// using GIMP's linear sRGB profile allows to skip the conversion popup
|
||||
if (exr_is_linear_srgb)
|
||||
return linear_srgb_profile;
|
||||
|
||||
// nope, it's something else. Clean up and build a new profile
|
||||
g_object_unref (linear_srgb_profile);
|
||||
|
||||
// TODO: maybe factor this out into libgimpcolor/gimpcolorprofile.h ?
|
||||
double Parameters[2] = { 1.0, 0.0 };
|
||||
cmsToneCurve *Gamma[3];
|
||||
Gamma[0] = Gamma[1] = Gamma[2] = cmsBuildParametricToneCurve(0,
|
||||
1,
|
||||
Parameters);
|
||||
profile = cmsCreateRGBProfile (&whitePoint, &CameraPrimaries, Gamma);
|
||||
lcms_profile = cmsCreateRGBProfile (&whitePoint, &CameraPrimaries, Gamma);
|
||||
cmsFreeToneCurve (Gamma[0]);
|
||||
if (profile == NULL) return NULL;
|
||||
if (lcms_profile == NULL) return NULL;
|
||||
|
||||
cmsSetProfileVersion (profile, 2.1);
|
||||
// cmsSetProfileVersion (lcms_profile, 2.1);
|
||||
cmsMLU *mlu0 = cmsMLUalloc (NULL, 1);
|
||||
cmsMLUsetASCII (mlu0, "en", "US", "(GIMP internal)");
|
||||
cmsMLU *mlu1 = cmsMLUalloc(NULL, 1);
|
||||
cmsMLUsetASCII (mlu1, "en", "US", "color profile from EXR chromaticities");
|
||||
cmsMLU *mlu2 = cmsMLUalloc(NULL, 1);
|
||||
cmsMLUsetASCII (mlu2, "en", "US", "color profile from EXR chromaticities");
|
||||
cmsWriteTag (profile, cmsSigDeviceMfgDescTag, mlu0);
|
||||
cmsWriteTag (profile, cmsSigDeviceModelDescTag, mlu1);
|
||||
cmsWriteTag (profile, cmsSigProfileDescriptionTag, mlu2);
|
||||
cmsWriteTag (lcms_profile, cmsSigDeviceMfgDescTag, mlu0);
|
||||
cmsWriteTag (lcms_profile, cmsSigDeviceModelDescTag, mlu1);
|
||||
cmsWriteTag (lcms_profile, cmsSigProfileDescriptionTag, mlu2);
|
||||
cmsMLUfree (mlu0);
|
||||
cmsMLUfree (mlu1);
|
||||
cmsMLUfree (mlu2);
|
||||
|
||||
profile = gimp_color_profile_new_from_lcms_profile (lcms_profile,
|
||||
NULL);
|
||||
cmsCloseProfile (lcms_profile);
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
@ -385,10 +435,10 @@ exr_loader_has_alpha (EXRLoader *loader)
|
|||
return loader->hasAlpha();
|
||||
}
|
||||
|
||||
cmsHPROFILE
|
||||
exr_loader_get_icc_profile (EXRLoader *loader)
|
||||
GimpColorProfile *
|
||||
exr_loader_get_profile (EXRLoader *loader)
|
||||
{
|
||||
return loader->getICCProfile ();
|
||||
return loader->getProfile ();
|
||||
}
|
||||
|
||||
gchar *
|
||||
|
|
|
@ -50,8 +50,8 @@ exr_loader_get_image_type (EXRLoader *loader);
|
|||
int
|
||||
exr_loader_has_alpha (EXRLoader *loader);
|
||||
|
||||
cmsHPROFILE
|
||||
exr_loader_get_icc_profile (EXRLoader *loader);
|
||||
GimpColorProfile *
|
||||
exr_loader_get_profile (EXRLoader *loader);
|
||||
|
||||
gchar *
|
||||
exr_loader_get_comment (EXRLoader *loader);
|
||||
|
|
Loading…
Reference in New Issue