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



commit 26251695b0542803d06e0d85b6d096ff116c95c8
Author: Michael Natterer <mitch gimp org>
Date:   Sun May 22 23:28:31 2016 +0200

    Bug 748749 - picked colors don't match image colors...
    
    ...when a color profile is active
    
    Add GimpPickable::pixel_to_srgb() which puts a picked raw image
    pixel into a GimpRGB. Default to gimp_rgba_set_pixel() but implement
    pixel_to_srgb() in GimpLayer, GimpProjection and GimpImage and
    run the pixel through gimp_image_color_profile_pixel_to_srgb().

 app/core/gimpimage.c      |   15 +++++++++++++++
 app/core/gimplayer.c      |   16 ++++++++++++++++
 app/core/gimppickable.c   |   35 +++++++++++++++++++++++++++++++----
 app/core/gimppickable.h   |    8 ++++++++
 app/core/gimpprojection.c |   20 ++++++++++++++++++++
 5 files changed, 90 insertions(+), 4 deletions(-)
---
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index 0383f9d..10b4975 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -204,6 +204,10 @@ static gboolean     gimp_image_get_pixel_at      (GimpPickable      *pickable,
 static gdouble      gimp_image_get_opacity_at    (GimpPickable      *pickable,
                                                   gint               x,
                                                   gint               y);
+static void         gimp_image_pixel_to_srgb     (GimpPickable      *pickable,
+                                                  const Babl        *format,
+                                                  gpointer           pixel,
+                                                  GimpRGB           *color);
 
 static void     gimp_image_mask_update           (GimpDrawable      *drawable,
                                                   gint               x,
@@ -668,6 +672,7 @@ gimp_pickable_iface_init (GimpPickableInterface *iface)
   iface->get_buffer            = gimp_image_get_buffer;
   iface->get_pixel_at          = gimp_image_get_pixel_at;
   iface->get_opacity_at        = gimp_image_get_opacity_at;
+  iface->pixel_to_srgb         = gimp_image_pixel_to_srgb;
 }
 
 static void
@@ -1572,6 +1577,16 @@ gimp_image_get_opacity_at (GimpPickable *pickable,
                                        x, y);
 }
 
+static void
+gimp_image_pixel_to_srgb (GimpPickable *pickable,
+                          const Babl   *format,
+                          gpointer      pixel,
+                          GimpRGB      *color)
+{
+  gimp_image_color_profile_pixel_to_srgb (GIMP_IMAGE (pickable),
+                                          format, pixel, color);
+}
+
 static GeglNode *
 gimp_image_get_graph (GimpProjectable *projectable)
 {
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index ce88a12..5abcbfa 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -192,6 +192,10 @@ static GimpColorProfile *
 static gdouble gimp_layer_get_opacity_at        (GimpPickable       *pickable,
                                                  gint                x,
                                                  gint                y);
+static void    gimp_layer_pixel_to_srgb         (GimpPickable       *pickable,
+                                                 const Babl         *format,
+                                                 gpointer            pixel,
+                                                 GimpRGB            *color);
 
 static void       gimp_layer_layer_mask_update  (GimpDrawable       *layer_mask,
                                                  gint                x,
@@ -408,6 +412,7 @@ static void
 gimp_pickable_iface_init (GimpPickableInterface *iface)
 {
   iface->get_opacity_at = gimp_layer_get_opacity_at;
+  iface->pixel_to_srgb  = gimp_layer_pixel_to_srgb;
 }
 
 static void
@@ -1251,6 +1256,17 @@ gimp_layer_get_opacity_at (GimpPickable *pickable,
 }
 
 static void
+gimp_layer_pixel_to_srgb (GimpPickable *pickable,
+                          const Babl   *format,
+                          gpointer      pixel,
+                          GimpRGB      *color)
+{
+  GimpImage *image = gimp_item_get_image (GIMP_ITEM (pickable));
+
+  gimp_pickable_pixel_to_srgb (GIMP_PICKABLE (image), format, pixel, color);
+}
+
+static void
 gimp_layer_layer_mask_update (GimpDrawable *drawable,
                               gint          x,
                               gint          y,
diff --git a/app/core/gimppickable.c b/app/core/gimppickable.c
index d264116..2ec722f 100644
--- a/app/core/gimppickable.c
+++ b/app/core/gimppickable.c
@@ -196,7 +196,7 @@ gimp_pickable_get_color_at (GimpPickable *pickable,
   if (! gimp_pickable_get_pixel_at (pickable, x, y, NULL, pixel))
     return FALSE;
 
-  gimp_rgba_set_pixel (color, gimp_pickable_get_format (pickable), pixel);
+  gimp_pickable_pixel_to_srgb (pickable, NULL, pixel, color);
 
   return TRUE;
 }
@@ -218,6 +218,33 @@ gimp_pickable_get_opacity_at (GimpPickable *pickable,
   return GIMP_OPACITY_TRANSPARENT;
 }
 
+void
+gimp_pickable_pixel_to_srgb (GimpPickable *pickable,
+                             const Babl   *format,
+                             gpointer      pixel,
+                             GimpRGB      *color)
+{
+  GimpPickableInterface *pickable_iface;
+
+  g_return_if_fail (GIMP_IS_PICKABLE (pickable));
+  g_return_if_fail (pixel != NULL);
+  g_return_if_fail (color != NULL);
+
+  if (! format)
+    format = gimp_pickable_get_format (pickable);
+
+  pickable_iface = GIMP_PICKABLE_GET_INTERFACE (pickable);
+
+  if (pickable_iface->pixel_to_srgb)
+    {
+      pickable_iface->pixel_to_srgb (pickable, format, pixel, color);
+    }
+  else
+    {
+      gimp_rgba_set_pixel (color, format, pixel);
+    }
+}
+
 gboolean
 gimp_pickable_pick_color (GimpPickable *pickable,
                           gint          x,
@@ -237,7 +264,7 @@ gimp_pickable_pick_color (GimpPickable *pickable,
   if (! gimp_pickable_get_pixel_at (pickable, x, y, format, sample))
     return FALSE;
 
-  gimp_rgba_set_pixel (color, format, sample);
+  gimp_pickable_pixel_to_srgb (pickable, format, sample, color);
 
   if (pixel)
     memcpy (pixel, sample, babl_format_get_bytes_per_pixel (format));
@@ -249,7 +276,7 @@ gimp_pickable_pick_color (GimpPickable *pickable,
       gint    radius       = (gint) average_radius;
       gint    i, j;
 
-      format = babl_format ("RGBA double");
+      format = babl_format ("RaGaBaA double");
 
       for (i = x - radius; i <= x + radius; i++)
         for (j = y - radius; j <= y + radius; j++)
@@ -268,7 +295,7 @@ gimp_pickable_pick_color (GimpPickable *pickable,
       sample[BLUE]  = color_avg[BLUE]  / count;
       sample[ALPHA] = color_avg[ALPHA] / count;
 
-      gimp_rgba_set_pixel (color, format, sample);
+      gimp_pickable_pixel_to_srgb (pickable, format, sample, color);
     }
 
   return TRUE;
diff --git a/app/core/gimppickable.h b/app/core/gimppickable.h
index 7308127..18f0587 100644
--- a/app/core/gimppickable.h
+++ b/app/core/gimppickable.h
@@ -48,6 +48,10 @@ struct _GimpPickableInterface
   gdouble         (* get_opacity_at)        (GimpPickable *pickable,
                                              gint          x,
                                              gint          y);
+  void            (* pixel_to_srgb)         (GimpPickable *pickable,
+                                             const Babl   *format,
+                                             gpointer      pixel,
+                                             GimpRGB      *color);
 };
 
 
@@ -70,6 +74,10 @@ gboolean        gimp_pickable_get_color_at          (GimpPickable *pickable,
 gdouble         gimp_pickable_get_opacity_at        (GimpPickable *pickable,
                                                      gint          x,
                                                      gint          y);
+void            gimp_pickable_pixel_to_srgb         (GimpPickable *pickable,
+                                                     const Babl   *format,
+                                                     gpointer      pixel,
+                                                     GimpRGB      *color);
 
 gboolean        gimp_pickable_pick_color            (GimpPickable *pickable,
                                                      gint          x,
diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c
index 45a62a8..9a91f9a 100644
--- a/app/core/gimpprojection.c
+++ b/app/core/gimpprojection.c
@@ -128,6 +128,10 @@ static gboolean    gimp_projection_get_pixel_at          (GimpPickable    *picka
 static gdouble     gimp_projection_get_opacity_at        (GimpPickable    *pickable,
                                                           gint             x,
                                                           gint             y);
+static void        gimp_projection_pixel_to_srgb         (GimpPickable    *pickable,
+                                                          const Babl      *format,
+                                                          gpointer         pixel,
+                                                          GimpRGB         *color);
 
 static void        gimp_projection_free_buffer           (GimpProjection  *proj);
 static void        gimp_projection_add_update_area       (GimpProjection  *proj,
@@ -240,6 +244,7 @@ gimp_projection_pickable_iface_init (GimpPickableInterface *iface)
   iface->get_buffer            = gimp_projection_get_buffer;
   iface->get_pixel_at          = gimp_projection_get_pixel_at;
   iface->get_opacity_at        = gimp_projection_get_opacity_at;
+  iface->pixel_to_srgb         = gimp_projection_pixel_to_srgb;
 }
 
 static void
@@ -443,6 +448,21 @@ gimp_projection_get_opacity_at (GimpPickable *pickable,
   return GIMP_OPACITY_OPAQUE;
 }
 
+static void
+gimp_projection_pixel_to_srgb (GimpPickable *pickable,
+                               const Babl   *format,
+                               gpointer      pixel,
+                               GimpRGB      *color)
+{
+  GimpProjection *proj  = GIMP_PROJECTION (pickable);
+  GimpImage      *image = gimp_projectable_get_image (proj->priv->projectable);
+
+  gimp_pickable_pixel_to_srgb (GIMP_PICKABLE (image), format, pixel, color);
+}
+
+
+/*  public functions  */
+
 GimpProjection *
 gimp_projection_new (GimpProjectable *projectable)
 {


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