[gtk/heif-demo] testheif: Interpret some nclx profiles



commit c95f170ac4679479b44e1fa41622e153b0b5ee7c
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue May 10 08:35:12 2022 -0400

    testheif: Interpret some nclx profiles
    
    This is copied from what the gimp does.
    It does not handle hdr atm.

 tests/testheif.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 139 insertions(+), 11 deletions(-)
---
diff --git a/tests/testheif.c b/tests/testheif.c
index 14b6a395d7..26d68da176 100644
--- a/tests/testheif.c
+++ b/tests/testheif.c
@@ -1,5 +1,105 @@
 #include <gtk/gtk.h>
 #include <libheif/heif.h>
+#include <lcms2.h>
+
+extern GdkColorProfile *gdk_color_profile_new_from_lcms_profile (cmsHPROFILE   lcms_profile,
+                                                                 GError      **error);
+extern GdkColorProfile *gdk_color_profile_get_srgb_linear (void);
+
+
+static GdkColorProfile *
+nclx_to_color_profile (const struct heif_color_profile_nclx *nclx)
+{
+  cmsHPROFILE profile = NULL;
+  cmsCIExyY whitepoint;
+  cmsCIExyYTRIPLE primaries;
+  cmsToneCurve *curve[3];
+
+  cmsFloat64Number srgb_parameters[5] =
+  { 2.4, 1.0 / 1.055,  0.055 / 1.055, 1.0 / 12.92, 0.04045 };
+
+  cmsFloat64Number rec709_parameters[5] =
+  { 2.2, 1.0 / 1.099,  0.099 / 1.099, 1.0 / 4.5, 0.081 };
+
+  if (nclx == NULL)
+    {
+      return NULL;
+    }
+
+  if (nclx->color_primaries == heif_color_primaries_unspecified)
+    {
+      return NULL;
+    }
+
+  if (nclx->color_primaries == heif_color_primaries_ITU_R_BT_709_5)
+    {
+      if (nclx->transfer_characteristics == heif_transfer_characteristic_IEC_61966_2_1)
+        return gdk_color_profile_get_srgb ();
+      else if (nclx->transfer_characteristics == heif_transfer_characteristic_linear)
+        return gdk_color_profile_get_srgb_linear();
+    }
+
+  whitepoint.x = nclx->color_primary_white_x;
+  whitepoint.y = nclx->color_primary_white_y;
+  whitepoint.Y = 1.0f;
+
+  primaries.Red.x = nclx->color_primary_red_x;
+  primaries.Red.y = nclx->color_primary_red_y;
+  primaries.Red.Y = 1.0f;
+
+  primaries.Green.x = nclx->color_primary_green_x;
+  primaries.Green.y = nclx->color_primary_green_y;
+  primaries.Green.Y = 1.0f;
+
+  primaries.Blue.x = nclx->color_primary_blue_x;
+  primaries.Blue.y = nclx->color_primary_blue_y;
+  primaries.Blue.Y = 1.0f;
+
+  switch (nclx->transfer_characteristics)
+    {
+    case heif_transfer_characteristic_ITU_R_BT_709_5:
+      curve[0] = curve[1] = curve[2] = cmsBuildParametricToneCurve (NULL, 4,
+                                       rec709_parameters);
+      profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
+      cmsFreeToneCurve (curve[0]);
+      break;
+    case heif_transfer_characteristic_ITU_R_BT_470_6_System_M:
+      curve[0] = curve[1] = curve[2] = cmsBuildGamma (NULL, 2.2f);
+      profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
+      cmsFreeToneCurve (curve[0]);
+      break;
+    case heif_transfer_characteristic_ITU_R_BT_470_6_System_B_G:
+      curve[0] = curve[1] = curve[2] = cmsBuildGamma (NULL, 2.8f);
+      profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
+      cmsFreeToneCurve (curve[0]);
+      break;
+    case heif_transfer_characteristic_linear:
+      curve[0] = curve[1] = curve[2] = cmsBuildGamma (NULL, 1.0f);
+      profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
+      cmsFreeToneCurve (curve[0]);
+      break;
+    case heif_transfer_characteristic_IEC_61966_2_1:
+      /* same as default */
+    default:
+      curve[0] = curve[1] = curve[2] = cmsBuildParametricToneCurve (NULL, 4,
+                                       srgb_parameters);
+      profile = cmsCreateRGBProfile (&whitepoint, &primaries, curve);
+      cmsFreeToneCurve (curve[0]);
+      break;
+    }
+  if (profile)
+    {
+      GdkColorProfile *new_profile;
+
+      new_profile = gdk_color_profile_new_from_lcms_profile (profile, NULL);
+
+      cmsCloseProfile (profile);
+
+      return new_profile;
+    }
+
+  return NULL;
+}
 
 static GdkTexture *
 load_heif_image (const char  *filename,
@@ -18,8 +118,7 @@ load_heif_image (const char  *filename,
   GBytes *bytes;
   GdkTexture *texture = NULL;
   GdkColorProfile *profile = NULL;
-  gsize icc_size;
-  guchar *icc_data;
+  const char *profile_type = "";
 
   ctx = heif_context_alloc ();
 
@@ -38,16 +137,45 @@ load_heif_image (const char  *filename,
       goto out;
     }
 
-  icc_size = heif_image_handle_get_raw_color_profile_size (handle);
-  icc_data = g_new (guchar, icc_size);
-  err = heif_image_handle_get_raw_color_profile (handle, icc_data);
-  if (err.code == heif_error_Ok)
+  switch (heif_image_handle_get_color_profile_type (handle))
     {
-      bytes = g_bytes_new (icc_data, icc_size);
-      profile = gdk_color_profile_new_from_icc_bytes (bytes, NULL);
-      g_bytes_unref (bytes);
+    case heif_color_profile_type_not_present:
+      break;
+    case heif_color_profile_type_rICC:
+    case heif_color_profile_type_prof:
+      {
+        guchar *icc_data;
+        gsize icc_size;
+
+        profile_type = ", icc color profile";
+        icc_size = heif_image_handle_get_raw_color_profile_size (handle);
+        icc_data = g_new0 (guchar, icc_size);
+        err = heif_image_handle_get_raw_color_profile (handle, icc_data);
+        if (err.code == heif_error_Ok)
+          {
+            bytes = g_bytes_new (icc_data, icc_size);
+            profile = gdk_color_profile_new_from_icc_bytes (bytes, NULL);
+            g_bytes_unref (bytes);
+          }
+        g_free (icc_data);
+      }
+      break;
+    case heif_color_profile_type_nclx:
+      {
+        struct heif_color_profile_nclx *nclx = NULL;
+
+        err = heif_image_handle_get_nclx_color_profile (handle, &nclx);
+        if (err.code == heif_error_Ok)
+          {
+            profile_type = ", nclx color profile";
+            profile = nclx_to_color_profile (nclx);
+            heif_nclx_color_profile_free (nclx);
+          }
+      }
+      break;
+    default:
+      g_assert_not_reached ();
     }
-  g_free (icc_data);
 
   g_string_append_printf (details, "%dā€†Ć—ā€†%d pixels\n%d bits of luma, %d bits of chroma%s%s\n",
                           heif_image_handle_get_width (handle),
@@ -55,7 +183,7 @@ load_heif_image (const char  *filename,
                           heif_image_handle_get_luma_bits_per_pixel (handle),
                           heif_image_handle_get_chroma_bits_per_pixel (handle),
                           heif_image_handle_has_alpha_channel (handle) ? ", with alpha" : "",
-                          profile ? ", has ICC profile" : "");
+                          profile ? profile_type : "");
 
   if (profile == NULL)
     profile = gdk_color_profile_get_srgb ();


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