mirror of https://github.com/GNOME/gimp.git
plug-ins: support color managed EXR loading
This generates an ICC profile from the embedded white point and chromaticities on the fly, assuming linear gamma images.
This commit is contained in:
parent
9550fbff3c
commit
d73cfa4a24
|
@ -26,6 +26,7 @@ AM_CPPFLAGS = \
|
|||
$(GTK_CFLAGS) \
|
||||
$(GEGL_CFLAGS) \
|
||||
$(OPENEXR_CFLAGS) \
|
||||
$(LCMS_CFLAGS) \
|
||||
-I$(includedir)
|
||||
|
||||
libexec_PROGRAMS = file-exr
|
||||
|
@ -48,4 +49,5 @@ file_exr_LDADD = \
|
|||
$(GEGL_LIBS) \
|
||||
$(RT_LIBS) \
|
||||
$(INTLLIBS) \
|
||||
$(LCMS_LIBS) \
|
||||
$(file_exr_RC)
|
||||
|
|
|
@ -280,6 +280,27 @@ load_image (const gchar *filename,
|
|||
gimp_progress_update ((gdouble) begin / (gdouble) height);
|
||||
}
|
||||
|
||||
// try to load an icc profile.
|
||||
// this will be generated on the fly if chromaticities are given
|
||||
if (image_type == GIMP_RGB)
|
||||
{
|
||||
cmsHPROFILE lcms_profile = NULL;
|
||||
GimpColorProfile *profile = NULL;
|
||||
|
||||
lcms_profile = exr_loader_icc_read_profile (loader);
|
||||
if (lcms_profile)
|
||||
{
|
||||
profile = gimp_color_profile_new_from_lcms_profile (lcms_profile,
|
||||
NULL);
|
||||
if (profile)
|
||||
{
|
||||
gimp_image_set_color_profile (image, profile);
|
||||
g_object_unref (profile);
|
||||
}
|
||||
cmsCloseProfile (lcms_profile);
|
||||
}
|
||||
}
|
||||
|
||||
gimp_progress_update (1.0);
|
||||
|
||||
status = image;
|
||||
|
|
|
@ -170,6 +170,76 @@ struct _EXRLoader
|
|||
return has_alpha_ ? 1 : 0;
|
||||
}
|
||||
|
||||
cmsHPROFILE readICCProfile() const {
|
||||
Chromaticities chromaticities;
|
||||
float whiteLuminance = 1.0;
|
||||
|
||||
cmsHPROFILE profile = NULL;
|
||||
|
||||
if (hasChromaticities (file_.header ()))
|
||||
chromaticities = Imf::chromaticities (file_.header ());
|
||||
else
|
||||
return NULL;
|
||||
|
||||
if (Imf::hasWhiteLuminance (file_.header ()))
|
||||
whiteLuminance = Imf::whiteLuminance (file_.header ());
|
||||
else
|
||||
return NULL;
|
||||
|
||||
#if 0
|
||||
std::cout << "hasChromaticities: "
|
||||
<< hasChromaticities (file_.header ())
|
||||
<< std::endl;
|
||||
std::cout << "hasWhiteLuminance: "
|
||||
<< hasWhiteLuminance (file_.header ())
|
||||
<< std::endl;
|
||||
std::cout << chromaticities.red << std::endl;
|
||||
std::cout << chromaticities.green << std::endl;
|
||||
std::cout << chromaticities.blue << std::endl;
|
||||
std::cout << chromaticities.white << std::endl;
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
|
||||
// TODO: maybe factor this out into libgimpcolor/gimpcolorprofile.h ?
|
||||
cmsCIExyY whitePoint = { chromaticities.white.x,
|
||||
chromaticities.white.y,
|
||||
whiteLuminance };
|
||||
cmsCIExyYTRIPLE CameraPrimaries = { { chromaticities.red.x,
|
||||
chromaticities.red.y,
|
||||
whiteLuminance },
|
||||
{ chromaticities.green.x,
|
||||
chromaticities.green.y,
|
||||
whiteLuminance },
|
||||
{ chromaticities.blue.x,
|
||||
chromaticities.blue.y,
|
||||
whiteLuminance } };
|
||||
|
||||
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);
|
||||
cmsFreeToneCurve (Gamma[0]);
|
||||
if (profile == NULL) return NULL;
|
||||
|
||||
cmsSetProfileVersion (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);
|
||||
cmsMLUfree (mlu0);
|
||||
cmsMLUfree (mlu1);
|
||||
cmsMLUfree (mlu2);
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
size_t refcount_;
|
||||
InputFile file_;
|
||||
const Box2i data_window_;
|
||||
|
@ -289,3 +359,9 @@ exr_loader_read_pixel_row (EXRLoader *loader,
|
|||
|
||||
return retval;
|
||||
}
|
||||
|
||||
cmsHPROFILE
|
||||
exr_loader_icc_read_profile (EXRLoader *loader)
|
||||
{
|
||||
return loader->readICCProfile ();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <lcms2.h>
|
||||
|
||||
/* This is fully opaque on purpose, as the calling C code must not be
|
||||
* exposed to more than this.
|
||||
*/
|
||||
|
@ -54,6 +56,9 @@ exr_loader_read_pixel_row (EXRLoader *loader,
|
|||
int bpp,
|
||||
int row);
|
||||
|
||||
cmsHPROFILE
|
||||
exr_loader_icc_read_profile (EXRLoader *loader);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue