[gimp] Bug 647957 - GimpColorFrame's CMYK mode is not color managed



commit f9170b667e5e6579f08d1b9662dd27987d7f3c17
Author: Michael Natterer <mitch gimp org>
Date:   Tue Oct 18 22:48:04 2016 +0200

    Bug 647957 - GimpColorFrame's CMYK mode is not color managed
    
    Convert GimpRGB to CMYK using a color transform to the configured CMYK
    profile instead of the naive gimp_rgb_to_cmyk().
    
    Add gimp_color_frame_set_color_config() and call it on all color
    frames in the GUI (color picker tool, cursor info, sample point view).
    Keep a GimpColorTransform around that does the conversion.
    
    Also color manages the frame's color area now (visible in the sample
    point view), which was forgotten earlier. Addresses bug #467930.

 app/display/gimpcursorview.c        |   24 ++++--
 app/display/gimpcursorview.h        |    2 +-
 app/tools/gimpcolorpickertool.c     |    4 +
 app/widgets/gimpcolorframe.c        |  154 +++++++++++++++++++++++++++++++----
 app/widgets/gimpcolorframe.h        |   10 ++-
 app/widgets/gimpsamplepointeditor.c |   31 +++++--
 app/widgets/gimpsamplepointeditor.h |    2 +-
 7 files changed, 192 insertions(+), 35 deletions(-)
---
diff --git a/app/display/gimpcursorview.c b/app/display/gimpcursorview.c
index 263f109..89c4590 100644
--- a/app/display/gimpcursorview.c
+++ b/app/display/gimpcursorview.c
@@ -2,7 +2,7 @@
  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  *
  * gimpcursorview.c
- * Copyright (C) 2005 Michael Natterer <mitch gimp org>
+ * Copyright (C) 2005-2016 Michael Natterer <mitch gimp org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,6 +32,9 @@
 
 #include "display-types.h"
 
+#include "config/gimpcoreconfig.h"
+
+#include "core/gimp.h"
 #include "core/gimpcontext.h"
 #include "core/gimpimage.h"
 #include "core/gimpimage-pick-color.h"
@@ -368,7 +371,8 @@ gimp_cursor_view_set_property (GObject      *object,
     case PROP_SAMPLE_MERGED:
       view->priv->sample_merged = g_value_get_boolean (value);
       break;
-   default:
+
+    default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
     }
@@ -387,7 +391,8 @@ gimp_cursor_view_get_property (GObject    *object,
     case PROP_SAMPLE_MERGED:
       g_value_set_boolean (value, view->priv->sample_merged);
       break;
-   default:
+
+    default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
     }
@@ -518,9 +523,10 @@ static void
 gimp_cursor_view_set_context (GimpDocked  *docked,
                               GimpContext *context)
 {
-  GimpCursorView *view    = GIMP_CURSOR_VIEW (docked);
-  GimpDisplay    *display = NULL;
-  GimpImage      *image   = NULL;
+  GimpCursorView  *view    = GIMP_CURSOR_VIEW (docked);
+  GimpColorConfig *config  = NULL;
+  GimpDisplay     *display = NULL;
+  GimpImage       *image   = NULL;
 
   if (context == view->priv->context)
     return;
@@ -551,10 +557,16 @@ gimp_cursor_view_set_context (GimpDocked  *docked,
                                 G_CALLBACK (gimp_cursor_view_image_changed),
                                 view);
 
+      config  = context->gimp->config->color_management;
       display = gimp_context_get_display (context);
       image   = gimp_context_get_image (context);
     }
 
+  gimp_color_frame_set_color_config (GIMP_COLOR_FRAME (view->priv->color_frame_1),
+                                     config);
+  gimp_color_frame_set_color_config (GIMP_COLOR_FRAME (view->priv->color_frame_2),
+                                     config);
+
   gimp_cursor_view_diplay_changed (view, display, view->priv->context);
   gimp_cursor_view_image_changed (view, image, view->priv->context);
 }
diff --git a/app/display/gimpcursorview.h b/app/display/gimpcursorview.h
index 6955518..3071687 100644
--- a/app/display/gimpcursorview.h
+++ b/app/display/gimpcursorview.h
@@ -2,7 +2,7 @@
  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  *
  * gimpcursorview.h
- * Copyright (C) 2005 Michael Natterer <mitch gimp org>
+ * Copyright (C) 2005-2016 Michael Natterer <mitch gimp org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/app/tools/gimpcolorpickertool.c b/app/tools/gimpcolorpickertool.c
index c9b0c07..70e3a09 100644
--- a/app/tools/gimpcolorpickertool.c
+++ b/app/tools/gimpcolorpickertool.c
@@ -364,6 +364,8 @@ gimp_color_picker_tool_info_create (GimpColorPickerTool *picker_tool)
   gtk_widget_show (hbox);
 
   picker_tool->color_frame1 = gimp_color_frame_new ();
+  gimp_color_frame_set_color_config (GIMP_COLOR_FRAME (picker_tool->color_frame1),
+                                     context->gimp->config->color_management);
   gimp_color_frame_set_mode (GIMP_COLOR_FRAME (picker_tool->color_frame1),
                              GIMP_COLOR_FRAME_MODE_PIXEL);
   gtk_box_pack_start (GTK_BOX (hbox), picker_tool->color_frame1,
@@ -371,6 +373,8 @@ gimp_color_picker_tool_info_create (GimpColorPickerTool *picker_tool)
   gtk_widget_show (picker_tool->color_frame1);
 
   picker_tool->color_frame2 = gimp_color_frame_new ();
+  gimp_color_frame_set_color_config (GIMP_COLOR_FRAME (picker_tool->color_frame2),
+                                     context->gimp->config->color_management);
   gimp_color_frame_set_mode (GIMP_COLOR_FRAME (picker_tool->color_frame2),
                              GIMP_COLOR_FRAME_MODE_RGB);
   gtk_box_pack_start (GTK_BOX (hbox), picker_tool->color_frame2,
diff --git a/app/widgets/gimpcolorframe.c b/app/widgets/gimpcolorframe.c
index 6dc425e..9513d8f 100644
--- a/app/widgets/gimpcolorframe.c
+++ b/app/widgets/gimpcolorframe.c
@@ -22,6 +22,7 @@
 
 #include "libgimpmath/gimpmath.h"
 #include "libgimpcolor/gimpcolor.h"
+#include "libgimpconfig/gimpconfig.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
 #include "widgets-types.h"
@@ -47,24 +48,28 @@ enum
 
 /*  local function prototypes  */
 
-static void       gimp_color_frame_finalize      (GObject        *object);
-static void       gimp_color_frame_get_property  (GObject        *object,
-                                                  guint           property_id,
-                                                  GValue         *value,
-                                                  GParamSpec     *pspec);
-static void       gimp_color_frame_set_property  (GObject        *object,
-                                                  guint           property_id,
-                                                  const GValue   *value,
-                                                  GParamSpec     *pspec);
+static void       gimp_color_frame_dispose           (GObject        *object);
+static void       gimp_color_frame_finalize          (GObject        *object);
+static void       gimp_color_frame_get_property      (GObject        *object,
+                                                      guint           property_id,
+                                                      GValue         *value,
+                                                      GParamSpec     *pspec);
+static void       gimp_color_frame_set_property      (GObject        *object,
+                                                      guint           property_id,
+                                                      const GValue   *value,
+                                                      GParamSpec     *pspec);
 
-static void       gimp_color_frame_style_set     (GtkWidget      *widget,
-                                                  GtkStyle       *prev_style);
-static gboolean   gimp_color_frame_expose        (GtkWidget      *widget,
-                                                  GdkEventExpose *eevent);
+static void       gimp_color_frame_style_set         (GtkWidget      *widget,
+                                                      GtkStyle       *prev_style);
+static gboolean   gimp_color_frame_expose            (GtkWidget      *widget,
+                                                      GdkEventExpose *eevent);
 
-static void       gimp_color_frame_menu_callback (GtkWidget      *widget,
-                                                  GimpColorFrame *frame);
-static void       gimp_color_frame_update        (GimpColorFrame *frame);
+static void       gimp_color_frame_menu_callback     (GtkWidget      *widget,
+                                                      GimpColorFrame *frame);
+static void       gimp_color_frame_update            (GimpColorFrame *frame);
+
+static void       gimp_color_frame_create_transform  (GimpColorFrame *frame);
+static void       gimp_color_frame_destroy_transform (GimpColorFrame *frame);
 
 
 G_DEFINE_TYPE (GimpColorFrame, gimp_color_frame, GIMP_TYPE_FRAME)
@@ -78,6 +83,7 @@ gimp_color_frame_class_init (GimpColorFrameClass *klass)
   GObjectClass   *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
+  object_class->dispose      = gimp_color_frame_dispose;
   object_class->finalize     = gimp_color_frame_finalize;
   object_class->get_property = gimp_color_frame_get_property;
   object_class->set_property = gimp_color_frame_set_property;
@@ -174,6 +180,16 @@ gimp_color_frame_init (GimpColorFrame *frame)
 }
 
 static void
+gimp_color_frame_dispose (GObject *object)
+{
+  GimpColorFrame *frame = GIMP_COLOR_FRAME (object);
+
+  gimp_color_frame_set_color_config (frame, NULL);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
 gimp_color_frame_finalize (GObject *object)
 {
   GimpColorFrame *frame = GIMP_COLOR_FRAME (object);
@@ -472,6 +488,41 @@ gimp_color_frame_set_invalid (GimpColorFrame *frame)
   gimp_color_frame_update (frame);
 }
 
+void
+gimp_color_frame_set_color_config (GimpColorFrame  *frame,
+                                   GimpColorConfig *config)
+{
+  g_return_if_fail (GIMP_IS_COLOR_FRAME (frame));
+  g_return_if_fail (config == NULL || GIMP_IS_COLOR_CONFIG (config));
+
+  if (config != frame->config)
+    {
+      if (frame->config)
+        {
+          g_signal_handlers_disconnect_by_func (frame->config,
+                                                gimp_color_frame_destroy_transform,
+                                                frame);
+          g_object_unref (frame->config);
+
+          gimp_color_frame_destroy_transform (frame);
+        }
+
+      frame->config = config;
+
+      if (frame->config)
+        {
+          g_object_ref (frame->config);
+
+          g_signal_connect_swapped (frame->config, "notify",
+                                    G_CALLBACK (gimp_color_frame_destroy_transform),
+                                    frame);
+        }
+
+      gimp_color_area_set_color_config (GIMP_COLOR_AREA (frame->color_area),
+                                        config);
+    }
+}
+
 
 /*  private functions  */
 
@@ -676,7 +727,35 @@ gimp_color_frame_update (GimpColorFrame *frame)
         {
           GimpCMYK cmyk;
 
-          gimp_rgb_to_cmyk (&frame->color, 1.0, &cmyk);
+          if (! frame->transform)
+            gimp_color_frame_create_transform (frame);
+
+          if (frame->transform)
+            {
+              gdouble rgb_values[3];
+              gdouble cmyk_values[4];
+
+              rgb_values[0] = frame->color.r;
+              rgb_values[1] = frame->color.g;
+              rgb_values[2] = frame->color.b;
+
+              gimp_color_transform_process_pixels (frame->transform,
+                                                   babl_format ("R'G'B' double"),
+                                                   rgb_values,
+                                                   babl_format ("CMYK double"),
+                                                   cmyk_values,
+                                                   1);
+
+              cmyk.c = cmyk_values[0] / 100.0;
+              cmyk.m = cmyk_values[1] / 100.0;
+              cmyk.y = cmyk_values[2] / 100.0;
+              cmyk.k = cmyk_values[3] / 100.0;
+            }
+          else
+            {
+              gimp_rgb_to_cmyk (&frame->color, 1.0, &cmyk);
+            }
+
           cmyk.a = frame->color.a;
 
           values = g_new0 (gchar *, 6);
@@ -710,3 +789,44 @@ gimp_color_frame_update (GimpColorFrame *frame)
 
   g_strfreev (values);
 }
+
+static void
+gimp_color_frame_create_transform (GimpColorFrame *frame)
+{
+  if (frame->config)
+    {
+      GimpColorProfile *cmyk_profile;
+
+      cmyk_profile = gimp_color_config_get_cmyk_color_profile (frame->config,
+                                                               NULL);
+
+      if (cmyk_profile)
+        {
+          static GimpColorProfile *rgb_profile = NULL;
+
+          if (G_UNLIKELY (! rgb_profile))
+            rgb_profile = gimp_color_profile_new_rgb_srgb ();
+
+          frame->transform =
+            gimp_color_transform_new (rgb_profile,
+                                      babl_format ("R'G'B' double"),
+                                      cmyk_profile,
+                                      babl_format ("CMYK double"),
+                                      GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
+                                      GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE |
+                                      GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION);
+        }
+    }
+}
+
+static void
+gimp_color_frame_destroy_transform (GimpColorFrame *frame)
+{
+  if (frame->transform)
+    {
+      g_object_unref (frame->transform);
+      frame->transform = NULL;
+    }
+
+  gimp_color_frame_update (frame);
+}
diff --git a/app/widgets/gimpcolorframe.h b/app/widgets/gimpcolorframe.h
index b9131f1..86f0dd5 100644
--- a/app/widgets/gimpcolorframe.h
+++ b/app/widgets/gimpcolorframe.h
@@ -55,6 +55,9 @@ struct _GimpColorFrame
   GtkWidget          *value_labels[GIMP_COLOR_FRAME_ROWS];
 
   PangoLayout        *number_layout;
+
+  GimpColorConfig    *config;
+  GimpColorTransform *transform;
 };
 
 struct _GimpColorFrameClass
@@ -63,9 +66,9 @@ struct _GimpColorFrameClass
 };
 
 
-GType       gimp_color_frame_get_type    (void) G_GNUC_CONST;
+GType       gimp_color_frame_get_type           (void) G_GNUC_CONST;
 
-GtkWidget * gimp_color_frame_new         (void);
+GtkWidget * gimp_color_frame_new                (void);
 
 void        gimp_color_frame_set_mode           (GimpColorFrame     *frame,
                                                  GimpColorFrameMode  mode);
@@ -85,5 +88,8 @@ void        gimp_color_frame_set_color          (GimpColorFrame     *frame,
                                                  const GimpRGB      *color);
 void        gimp_color_frame_set_invalid        (GimpColorFrame     *frame);
 
+void        gimp_color_frame_set_color_config   (GimpColorFrame     *frame,
+                                                 GimpColorConfig    *config);
+
 
 #endif  /*  __GIMP_COLOR_FRAME_H__  */
diff --git a/app/widgets/gimpsamplepointeditor.c b/app/widgets/gimpsamplepointeditor.c
index 330c165..8e55be1 100644
--- a/app/widgets/gimpsamplepointeditor.c
+++ b/app/widgets/gimpsamplepointeditor.c
@@ -2,7 +2,7 @@
  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  *
  * gimpsamplepointeditor.c
- * Copyright (C) 2005 Michael Natterer <mitch gimp org>
+ * Copyright (C) 2005-2016 Michael Natterer <mitch gimp org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,6 +27,8 @@
 
 #include "widgets-types.h"
 
+#include "config/gimpcoreconfig.h"
+
 #include "core/gimp.h"
 #include "core/gimpimage.h"
 #include "core/gimpimage-pick-color.h"
@@ -41,6 +43,9 @@
 #include "gimp-intl.h"
 
 
+#define N_POINTS 4
+
+
 enum
 {
   PROP_0,
@@ -136,7 +141,7 @@ gimp_sample_point_editor_init (GimpSamplePointEditor *editor)
   gtk_box_pack_start (GTK_BOX (editor), editor->table, FALSE, FALSE, 0);
   gtk_widget_show (editor->table);
 
-  for (i = 0; i < 4; i++)
+  for (i = 0; i < N_POINTS; i++)
     {
       GtkWidget *frame;
 
@@ -246,6 +251,8 @@ gimp_sample_point_editor_set_image (GimpImageEditor *image_editor,
                                     GimpImage       *image)
 {
   GimpSamplePointEditor *editor = GIMP_SAMPLE_POINT_EDITOR (image_editor);
+  GimpColorConfig       *config = NULL;
+  gint                   i;
 
   if (image_editor->image)
     {
@@ -281,6 +288,14 @@ gimp_sample_point_editor_set_image (GimpImageEditor *image_editor,
       g_signal_connect (gimp_image_get_projection (image), "update",
                         G_CALLBACK (gimp_sample_point_editor_proj_update),
                         editor);
+
+      config = image->gimp->config->color_management;
+    }
+
+  for (i = 0; i < N_POINTS; i++)
+    {
+      gimp_color_frame_set_color_config (GIMP_COLOR_FRAME (editor->color_frames[i]),
+                                         config);
     }
 
   gimp_sample_point_editor_points_changed (editor);
@@ -315,7 +330,7 @@ gimp_sample_point_editor_set_sample_merged (GimpSamplePointEditor *editor,
 
       editor->sample_merged = sample_merged;
 
-      for (i = 0; i < 4; i++)
+      for (i = 0; i < N_POINTS; i++)
         editor->dirty[i] = TRUE;
 
       gimp_sample_point_editor_dirty (editor, -1);
@@ -357,7 +372,7 @@ gimp_sample_point_editor_point_moved (GimpImage             *image,
 {
   gint i = g_list_index (gimp_image_get_sample_points (image), sample_point);
 
-  if (i < 4)
+  if (i < N_POINTS)
     gimp_sample_point_editor_dirty (editor, i);
 }
 
@@ -378,7 +393,7 @@ gimp_sample_point_editor_proj_update (GimpImage             *image,
 
   sample_points = gimp_image_get_sample_points (image_editor->image);
 
-  n_points = MIN (4, g_list_length (sample_points));
+  n_points = MIN (N_POINTS, g_list_length (sample_points));
 
   for (i = 0, list = sample_points;
        i < n_points;
@@ -409,7 +424,7 @@ gimp_sample_point_editor_points_changed (GimpSamplePointEditor *editor)
   if (image_editor->image)
     {
       sample_points = gimp_image_get_sample_points (image_editor->image);
-      n_points = MIN (4, g_list_length (sample_points));
+      n_points = MIN (N_POINTS, g_list_length (sample_points));
     }
 
   for (i = 0; i < n_points; i++)
@@ -418,7 +433,7 @@ gimp_sample_point_editor_points_changed (GimpSamplePointEditor *editor)
       editor->dirty[i] = TRUE;
     }
 
-  for (i = n_points; i < 4; i++)
+  for (i = n_points; i < N_POINTS; i++)
     {
       gtk_widget_set_sensitive (editor->color_frames[i], FALSE);
       gimp_color_frame_set_invalid (GIMP_COLOR_FRAME (editor->color_frames[i]));
@@ -460,7 +475,7 @@ gimp_sample_point_editor_update (GimpSamplePointEditor *editor)
 
   sample_points = gimp_image_get_sample_points (image_editor->image);
 
-  n_points = MIN (4, g_list_length (sample_points));
+  n_points = MIN (N_POINTS, g_list_length (sample_points));
 
   for (i = 0, list = sample_points;
        i < n_points;
diff --git a/app/widgets/gimpsamplepointeditor.h b/app/widgets/gimpsamplepointeditor.h
index f7ac4d7..e4b1cf3 100644
--- a/app/widgets/gimpsamplepointeditor.h
+++ b/app/widgets/gimpsamplepointeditor.h
@@ -2,7 +2,7 @@
  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  *
  * gimpsamplepointeditor.h
- * Copyright (C) 2005 Michael Natterer <mitch gimp org>
+ * Copyright (C) 2005-2016 Michael Natterer <mitch gimp org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by


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