[gimp] Bug 748749 - picked colors don't match image colors...



commit 9550fbff3cdfbd6ee037f880e0ec711be5b49275
Author: Michael Natterer <mitch gimp org>
Date:   Sun Sep 20 21:17:54 2015 +0200

    Bug 748749 - picked colors don't match image colors...
    
    ...when a color profile is active
    
    This commit adds more (still unused) infrastructure to fix this bug:
    
    Ee now keep around color transforms from layer pixels to "R'G'B'A
    double" (which is GimpRGB's format) and back. Also add utility
    function gimp_image_color_profile_pixel_to_srgb() which converts a
    picked pixel to GimpRGB, using the cached color transform.

 app/core/gimpimage-color-profile.c |  106 +++++++++++++++++++++++++++++++++++-
 app/core/gimpimage-color-profile.h |    9 +++-
 app/core/gimpimage-private.h       |    5 ++
 app/core/gimpimage.c               |    5 +--
 4 files changed, 118 insertions(+), 7 deletions(-)
---
diff --git a/app/core/gimpimage-color-profile.c b/app/core/gimpimage-color-profile.c
index 0bfaa43..3510d94 100644
--- a/app/core/gimpimage-color-profile.c
+++ b/app/core/gimpimage-color-profile.c
@@ -604,12 +604,49 @@ gimp_image_convert_profile_indexed (GimpImage                *image,
   g_free (cmap);
 }
 
+void
+gimp_image_color_profile_pixel_to_srgb (GimpImage  *image,
+                                        const Babl *pixel_format,
+                                        gpointer    pixel,
+                                        GimpRGB    *color)
+{
+  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
+
+  if (private->transform_to_srgb)
+    {
+      guchar srgb_pixel[32];
+
+      /* for the alpha channel */
+      gimp_rgba_set_pixel (color, pixel_format, pixel);
+
+      if (pixel_format == private->transform_layer_format)
+        {
+          cmsDoTransform (private->transform_to_srgb, pixel, srgb_pixel, 1);
+        }
+      else
+        {
+          guchar src_pixel[32];
+
+          babl_process (babl_fish (pixel_format,
+                                   private->transform_layer_format),
+                        pixel, src_pixel, 1);
+
+          cmsDoTransform (private->transform_to_srgb, src_pixel, srgb_pixel, 1);
+        }
+
+      gimp_rgb_set_pixel (color, private->transform_srgb_format, srgb_pixel);
+    }
+  else
+    {
+      gimp_rgba_set_pixel (color, pixel_format, pixel);
+    }
+}
+
 
 /*  internal API  */
 
 void
-_gimp_image_update_color_profile (GimpImage          *image,
-                                  const GimpParasite *icc_parasite)
+_gimp_image_free_color_profile (GimpImage *image)
 {
   GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
 
@@ -619,12 +656,77 @@ _gimp_image_update_color_profile (GimpImage          *image,
       private->color_profile = NULL;
     }
 
+  if (private->transform_to_srgb)
+    {
+      cmsDeleteTransform (private->transform_to_srgb);
+      private->transform_to_srgb = NULL;
+    }
+
+  if (private->transform_from_srgb)
+    {
+      cmsDeleteTransform (private->transform_from_srgb);
+      private->transform_from_srgb = NULL;
+    }
+}
+
+void
+_gimp_image_update_color_profile (GimpImage          *image,
+                                  const GimpParasite *icc_parasite)
+{
+  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
+
+  _gimp_image_free_color_profile (image);
+
   if (icc_parasite)
     {
       private->color_profile =
         gimp_color_profile_new_from_icc_profile (gimp_parasite_data (icc_parasite),
                                                  gimp_parasite_data_size (icc_parasite),
                                                  NULL);
+
+      if (private->color_profile)
+        {
+          GimpColorProfile *srgb_profile;
+          cmsHPROFILE       image_lcms;
+          cmsHPROFILE       srgb_lcms;
+          cmsUInt32Number   image_lcms_format;
+          cmsUInt32Number   srgb_lcms_format;
+          cmsUInt32Number   flags;
+
+          srgb_profile = gimp_color_profile_new_srgb ();
+
+          image_lcms = gimp_color_profile_get_lcms_profile (private->color_profile);
+          srgb_lcms  = gimp_color_profile_get_lcms_profile (srgb_profile);
+
+          private->transform_layer_format = gimp_image_get_layer_format (image,
+                                                                         TRUE);
+          private->transform_srgb_format  = babl_format ("R'G'B'A double");
+
+          private->transform_layer_format =
+            gimp_color_profile_get_format (private->transform_layer_format,
+                                           &image_lcms_format);
+
+          private->transform_srgb_format =
+            gimp_color_profile_get_format (private->transform_srgb_format,
+                                           &srgb_lcms_format);
+
+          flags = cmsFLAGS_NOOPTIMIZE;
+          flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
+
+          private->transform_to_srgb =
+            cmsCreateTransform (image_lcms, image_lcms_format,
+                                srgb_lcms,  srgb_lcms_format,
+                                GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
+                                flags);
+
+          private->transform_from_srgb =
+            cmsCreateTransform (srgb_lcms,  srgb_lcms_format,
+                                image_lcms, image_lcms_format,
+                                GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
+                                flags);
+
+          g_object_unref (srgb_profile);
+        }
     }
 
   gimp_color_managed_profile_changed (GIMP_COLOR_MANAGED (image));
diff --git a/app/core/gimpimage-color-profile.h b/app/core/gimpimage-color-profile.h
index 1ee41c0..818f0c8 100644
--- a/app/core/gimpimage-color-profile.h
+++ b/app/core/gimpimage-color-profile.h
@@ -69,9 +69,16 @@ void                 gimp_image_import_color_profile   (GimpImage           *ima
                                                         GimpProgress        *progress,
                                                         gboolean             interactive);
 
+void                 gimp_image_color_profile_pixel_to_srgb
+                                                       (GimpImage           *image,
+                                                        const Babl          *pixel_format,
+                                                        gpointer             pixel,
+                                                        GimpRGB             *color);
 
-/*  internal API, to be called only from the icc-profile parasite setters  */
 
+/*  internal API, to be called only from gimpimage.c  */
+
+void                 _gimp_image_free_color_profile    (GimpImage           *image);
 void                 _gimp_image_update_color_profile  (GimpImage           *image,
                                                         const GimpParasite  *icc_parasite);
 
diff --git a/app/core/gimpimage-private.h b/app/core/gimpimage-private.h
index bfc85d1..f2a9dfa 100644
--- a/app/core/gimpimage-private.h
+++ b/app/core/gimpimage-private.h
@@ -55,7 +55,12 @@ struct _GimpImagePrivate
   GimpPalette       *palette;               /*  palette of colormap          */
   const Babl        *babl_palette_rgb;      /*  palette's RGB Babl format    */
   const Babl        *babl_palette_rgba;     /*  palette's RGBA Babl format   */
+
   GimpColorProfile  *color_profile;         /*  image's color profile        */
+  GimpColorTransform transform_to_srgb;     /*  from layer pixels to sRGB    */
+  GimpColorTransform transform_from_srgb;   /*  from sRGB to layer pixels    */
+  const Babl        *transform_layer_format;/*  layer format for transforms  */
+  const Babl        *transform_srgb_format; /*  sRGB format for transforms   */
 
   GimpMetadata      *metadata;              /*  image's metadata             */
 
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index 7b4adc1..206e7f6 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -974,10 +974,7 @@ gimp_image_finalize (GObject *object)
     gimp_image_colormap_free (image);
 
   if (private->color_profile)
-    {
-      g_object_unref (private->color_profile);
-      private->color_profile = NULL;
-    }
+    _gimp_image_free_color_profile (image);
 
   if (private->metadata)
     {


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