[gimp/blend-tool-fun: 63/163] plug-ins: support color managed EXR loading



commit 0edd23ce546c716b978e7cc098efb73ce069e10c
Author: Tobias Ellinghaus <me houz org>
Date:   Sun Sep 20 23:42:24 2015 +0200

    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.

 plug-ins/file-exr/Makefile.am        |    2 +
 plug-ins/file-exr/file-exr.c         |   21 +++++++++
 plug-ins/file-exr/openexr-wrapper.cc |   76 ++++++++++++++++++++++++++++++++++
 plug-ins/file-exr/openexr-wrapper.h  |    5 ++
 4 files changed, 104 insertions(+), 0 deletions(-)
---
diff --git a/plug-ins/file-exr/Makefile.am b/plug-ins/file-exr/Makefile.am
index 37b5f6e..f3bda1b 100644
--- a/plug-ins/file-exr/Makefile.am
+++ b/plug-ins/file-exr/Makefile.am
@@ -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)
diff --git a/plug-ins/file-exr/file-exr.c b/plug-ins/file-exr/file-exr.c
index a155e53..9fda3c0 100644
--- a/plug-ins/file-exr/file-exr.c
+++ b/plug-ins/file-exr/file-exr.c
@@ -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;
diff --git a/plug-ins/file-exr/openexr-wrapper.cc b/plug-ins/file-exr/openexr-wrapper.cc
index 9cf1430..db0ce05 100644
--- a/plug-ins/file-exr/openexr-wrapper.cc
+++ b/plug-ins/file-exr/openexr-wrapper.cc
@@ -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 ();
+}
diff --git a/plug-ins/file-exr/openexr-wrapper.h b/plug-ins/file-exr/openexr-wrapper.h
index 3827607..7b3cd41 100644
--- a/plug-ins/file-exr/openexr-wrapper.h
+++ b/plug-ins/file-exr/openexr-wrapper.h
@@ -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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]