[gthumb] PNG loader ignores gAMA



commit d67d60caa12b8aa18c56c8993682f42ee234b7ae
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Mar 20 15:48:58 2022 +0100

    PNG loader ignores gAMA
    
    Fixes #194

 extensions/cairo_io/cairo-image-surface-png.c | 10 +++++++
 gthumb/gth-icc-profile.c                      | 42 +++++++++++++++++++++++++++
 gthumb/gth-icc-profile.h                      |  1 +
 3 files changed, 53 insertions(+)
---
diff --git a/extensions/cairo_io/cairo-image-surface-png.c b/extensions/cairo_io/cairo-image-surface-png.c
index 16f19f0d..6249482d 100644
--- a/extensions/cairo_io/cairo-image-surface-png.c
+++ b/extensions/cairo_io/cairo-image-surface-png.c
@@ -188,6 +188,9 @@ _cairo_image_surface_create_from_png (GInputStream  *istream,
        }
 
        png_set_read_fn (cairo_png_data->png_ptr, cairo_png_data, cairo_png_read_data_func);
+#ifndef HAVE_LCMS2
+       png_set_gamma (cairo_png_data->png_ptr, PNG_DEFAULT_sRGB, PNG_DEFAULT_sRGB);
+#endif
        png_read_info (cairo_png_data->png_ptr, cairo_png_data->png_info_ptr);
        png_get_IHDR (cairo_png_data->png_ptr,
                      cairo_png_data->png_info_ptr,
@@ -281,6 +284,7 @@ _cairo_image_surface_create_from_png (GInputStream  *istream,
                int            compression_type;
                png_bytep      icc_data;
                png_uint_32    icc_data_size;
+               double         gamma;
 
                if (png_get_sRGB (cairo_png_data->png_ptr,
                                  cairo_png_data->png_info_ptr,
@@ -298,6 +302,12 @@ _cairo_image_surface_create_from_png (GInputStream  *istream,
                        if ((icc_data_size > 0) && (icc_data != NULL))
                                profile = gth_icc_profile_new (GTH_ICC_PROFILE_ID_UNKNOWN, 
cmsOpenProfileFromMem (icc_data, icc_data_size));
                }
+               else if (png_get_gAMA (cairo_png_data->png_ptr,
+                                      cairo_png_data->png_info_ptr,
+                                      &gamma))
+               {
+                       profile = gth_icc_profile_new_rgb_with_gamma (1.0 / gamma);
+               }
 
                if (profile != NULL) {
                        gth_image_set_icc_profile (image, profile);
diff --git a/gthumb/gth-icc-profile.c b/gthumb/gth-icc-profile.c
index 6869a3cf..1c37bb05 100644
--- a/gthumb/gth-icc-profile.c
+++ b/gthumb/gth-icc-profile.c
@@ -32,6 +32,7 @@
 struct _GthICCProfilePrivate {
        GthCMSProfile cms_profile;
        char *id;
+       char *description;
 };
 
 
@@ -85,6 +86,7 @@ gth_icc_profile_finalize (GObject *object)
        icc_profile = GTH_ICC_PROFILE (object);
        gth_cms_profile_free (icc_profile->priv->cms_profile);
        g_free (icc_profile->priv->id);
+       g_free (icc_profile->priv->description);
 
        /* Chain up */
        G_OBJECT_CLASS (gth_icc_profile_parent_class)->finalize (object);
@@ -107,6 +109,7 @@ gth_icc_profile_init (GthICCProfile *self)
        self->priv = gth_icc_profile_get_instance_private (self);
        self->priv->cms_profile = NULL;
        self->priv->id = NULL;
+       self->priv->description = NULL;
 }
 
 
@@ -202,6 +205,42 @@ gth_icc_profile_new_srgb (void)
 }
 
 
+GthICCProfile *
+gth_icc_profile_new_rgb_with_gamma (double gamma)
+{
+#ifdef HAVE_LCMS2
+
+       cmsCIExyY        WhitePoint;
+       cmsCIExyYTRIPLE  Rec709Primaries = { {0.6400, 0.3300, 1.0}, {0.3000, 0.6000, 1.0}, {0.1500, 0.0600, 
1.0} };
+       cmsToneCurve*    Gamma[3];
+       cmsHPROFILE      hProfile;
+       GthICCProfile   *icc_profile;
+
+       if (! cmsWhitePointFromTemp (&WhitePoint, 6500))
+               return NULL;
+
+       Gamma[0] = Gamma[1] = Gamma[2] = cmsBuildGamma (NULL, gamma);
+       if (Gamma[0] == NULL)
+               return NULL;
+
+       hProfile = cmsCreateRGBProfile (&WhitePoint, &Rec709Primaries, Gamma);
+       cmsFreeToneCurve (Gamma[0]);
+       if (hProfile == NULL)
+               return NULL;
+
+       icc_profile = gth_icc_profile_new (NULL, (GthCMSProfile) hProfile);
+       icc_profile->priv->description = g_strdup_printf ("RGB Gamma=1/%.1f", gamma);
+
+       return icc_profile;
+
+#else
+
+       return NULL;
+
+#endif
+}
+
+
 const char *
 gth_icc_profile_get_id (GthICCProfile *self)
 {
@@ -213,6 +252,9 @@ gth_icc_profile_get_id (GthICCProfile *self)
 char *
 gth_icc_profile_get_description        (GthICCProfile *self)
 {
+       if (self->priv->description != NULL)
+               return g_strdup (self->priv->description);
+
 #ifdef HAVE_LCMS2
 
        GString         *color_profile;
diff --git a/gthumb/gth-icc-profile.h b/gthumb/gth-icc-profile.h
index bb78a190..ff55e195 100644
--- a/gthumb/gth-icc-profile.h
+++ b/gthumb/gth-icc-profile.h
@@ -80,6 +80,7 @@ GType                 gth_icc_profile_get_type        (void);
 GthICCProfile *                gth_icc_profile_new             (const char      *id,
                                                         GthCMSProfile    profile);
 GthICCProfile *                gth_icc_profile_new_srgb        (void);
+GthICCProfile *        gth_icc_profile_new_rgb_with_gamma      (double gamma);
 const char *           gth_icc_profile_get_id          (GthICCProfile   *icc_profile);
 char *                  gth_icc_profile_get_description        (GthICCProfile   *icc_profile);
 gboolean                gth_icc_profile_id_is_unknown   (const char      *id);


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