[gimp] app: make all GimpViewRenderers color manage themselves



commit a35276ed9145f99982af68a4824582b6ef9d8e6f
Author: Michael Natterer <mitch gimp org>
Date:   Fri May 27 23:54:46 2016 +0200

    app: make all GimpViewRenderers color manage themselves
    
    Automatically connect to the global GimpColorConfig unless a different
    one is set manually (like for previews that belong to a
    GimpDisplayShell and should follow its color management settings.  Add
    public API for subclasses to get to the renderer's color
    transform. Automatically color manage rendered pixbufs, just as we
    already manage temp_bufs.

 app/widgets/gimpviewrenderer.c |  230 +++++++++++++++++++++++++++++-----------
 app/widgets/gimpviewrenderer.h |    5 +
 2 files changed, 171 insertions(+), 64 deletions(-)
---
diff --git a/app/widgets/gimpviewrenderer.c b/app/widgets/gimpviewrenderer.c
index ce920c9..c871c02 100644
--- a/app/widgets/gimpviewrenderer.c
+++ b/app/widgets/gimpviewrenderer.c
@@ -93,6 +93,9 @@ static void      gimp_view_renderer_size_changed      (GimpViewRenderer   *rende
                                                        GimpViewable       *viewable);
 static void      gimp_view_renderer_profile_changed   (GimpViewRenderer   *renderer,
                                                        GimpViewable       *viewable);
+static void      gimp_view_renderer_config_notify     (GObject            *config,
+                                                       const GParamSpec   *pspec,
+                                                       GimpViewRenderer   *renderer);
 
 static void      gimp_view_render_temp_buf_to_surface (GimpViewRenderer   *renderer,
                                                        GtkWidget          *widget,
@@ -110,10 +113,6 @@ static cairo_pattern_t *
                  gimp_view_renderer_create_background (GimpViewRenderer   *renderer,
                                                        GtkWidget          *widget);
 
-static void      gimp_view_renderer_transform_create  (GimpViewRenderer   *renderer,
-                                                       GtkWidget          *widget,
-                                                       GeglBuffer         *src_buffer,
-                                                       GeglBuffer         *dest_buffer);
 static void      gimp_view_renderer_transform_free    (GimpViewRenderer   *renderer);
 
 
@@ -577,15 +576,27 @@ gimp_view_renderer_set_color_config (GimpViewRenderer *renderer,
   if (color_config != renderer->priv->color_config)
     {
       if (renderer->priv->color_config)
-        g_object_unref (renderer->priv->color_config);
+        {
+          g_signal_handlers_disconnect_by_func (renderer->priv->color_config,
+                                                gimp_view_renderer_config_notify,
+                                                renderer);
+
+          g_object_unref (renderer->priv->color_config);
+        }
 
       renderer->priv->color_config = color_config;
 
       if (renderer->priv->color_config)
-        g_object_ref (renderer->priv->color_config);
+        {
+          g_object_ref (renderer->priv->color_config);
 
-      if (renderer->viewable)
-        gimp_view_renderer_profile_changed (renderer, renderer->viewable);
+          g_signal_connect (renderer->priv->color_config, "notify",
+                            G_CALLBACK (gimp_view_renderer_config_notify),
+                            renderer);
+        }
+
+      gimp_view_renderer_config_notify (G_OBJECT (renderer->priv->color_config),
+                                        NULL, renderer);
     }
 }
 
@@ -729,12 +740,28 @@ gimp_view_renderer_real_set_context (GimpViewRenderer *renderer,
                                      GimpContext      *context)
 {
   if (renderer->context)
-    g_object_unref (renderer->context);
+    {
+      if (renderer->priv->color_config ==
+          renderer->context->gimp->config->color_management)
+        {
+          gimp_view_renderer_set_color_config (renderer, NULL);
+        }
+
+      g_object_unref (renderer->context);
+    }
 
   renderer->context = context;
 
   if (renderer->context)
-    g_object_ref (renderer->context);
+    {
+      g_object_ref (renderer->context);
+
+      if (renderer->priv->color_config == NULL)
+        {
+          gimp_view_renderer_set_color_config (renderer,
+                                               renderer->context->gimp->config->color_management);
+        }
+    }
 }
 
 static void
@@ -864,6 +891,15 @@ gimp_view_renderer_profile_changed (GimpViewRenderer *renderer,
   gimp_view_renderer_invalidate (renderer);
 }
 
+static void
+gimp_view_renderer_config_notify (GObject          *config,
+                                  const GParamSpec *pspec,
+                                  GimpViewRenderer *renderer)
+{
+  gimp_view_renderer_transform_free (renderer);
+  gimp_view_renderer_invalidate (renderer);
+}
+
 
 /*  protected functions  */
 
@@ -936,18 +972,64 @@ gimp_view_renderer_render_pixbuf (GimpViewRenderer *renderer,
                                   GtkWidget        *widget,
                                   GdkPixbuf        *pixbuf)
 {
+  GimpColorTransform *transform;
+  const Babl         *format;
+
   if (renderer->surface)
     {
       cairo_surface_destroy (renderer->surface);
       renderer->surface = NULL;
     }
 
-  g_object_ref (pixbuf);
+  format = gimp_pixbuf_get_format (pixbuf);
 
-  if (renderer->priv->pixbuf)
-    g_object_unref (renderer->priv->pixbuf);
+  transform =
+    gimp_view_renderer_get_color_transform (renderer, widget,
+                                            format, format);
+
+  if (transform)
+    {
+      GdkPixbuf *new;
+      gint       width       = gdk_pixbuf_get_width  (pixbuf);
+      gint       height      = gdk_pixbuf_get_height (pixbuf);
+      gsize      src_stride  = gdk_pixbuf_get_rowstride (pixbuf);
+      guchar    *src         = gdk_pixbuf_get_pixels (pixbuf);
+      gsize      dest_stride;
+      guchar    *dest;
+      gint       i;
+
+      new = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+                            gdk_pixbuf_get_has_alpha (pixbuf),
+                            8, width, height);
+
+      dest_stride = gdk_pixbuf_get_rowstride (new);
+      dest        = gdk_pixbuf_get_pixels (new);
+
+      for (i = 0; i < height; i++)
+        {
+          gimp_color_transform_process_pixels (transform,
+                                               format, src,
+                                               format, dest,
+                                               width);
+
+          src  += src_stride;
+          dest += dest_stride;
+        }
 
-  renderer->priv->pixbuf = pixbuf;
+      if (renderer->priv->pixbuf)
+        g_object_unref (renderer->priv->pixbuf);
+
+      renderer->priv->pixbuf = new;
+    }
+  else
+    {
+      g_object_ref (pixbuf);
+
+      if (renderer->priv->pixbuf)
+        g_object_unref (renderer->priv->pixbuf);
+
+      renderer->priv->pixbuf = pixbuf;
+    }
 }
 
 void
@@ -1003,6 +1085,57 @@ gimp_view_renderer_render_icon (GimpViewRenderer *renderer,
     }
 }
 
+GimpColorTransform *
+gimp_view_renderer_get_color_transform (GimpViewRenderer *renderer,
+                                        GtkWidget        *widget,
+                                        const Babl       *src_format,
+                                        const Babl       *dest_format)
+{
+  GimpColorProfile *profile;
+
+  g_return_val_if_fail (GIMP_IS_VIEW_RENDERER (renderer), NULL);
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+  g_return_val_if_fail (src_format != NULL, NULL);
+  g_return_val_if_fail (dest_format != NULL, NULL);
+
+  if (renderer->priv->profile_transform)
+    return renderer->priv->profile_transform;
+
+  if (! renderer->priv->color_config)
+    {
+      g_printerr ("EEK\n");
+      return NULL;
+    }
+
+  if (GIMP_IS_COLOR_MANAGED (renderer->viewable))
+    {
+      GimpColorManaged *managed = GIMP_COLOR_MANAGED (renderer->viewable);
+
+      profile = gimp_color_managed_get_color_profile (managed);
+    }
+  else
+    {
+      static GimpColorProfile *srgb_profile = NULL;
+
+      if (G_UNLIKELY (! srgb_profile))
+        srgb_profile = gimp_color_profile_new_rgb_srgb ();
+
+      profile = srgb_profile;
+    }
+
+  renderer->priv->profile_transform =
+    gimp_widget_get_color_transform (widget,
+                                     renderer->priv->color_config,
+                                     profile,
+                                     src_format,
+                                     dest_format);
+
+  return renderer->priv->profile_transform;
+}
+
+
+/*  private functions  */
+
 static void
 gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
                                       GtkWidget        *widget,
@@ -1099,9 +1232,10 @@ gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
 
   if (babl_format_has_alpha (temp_buf_format) && channel == -1)
     {
-      GeglBuffer      *src_buffer;
-      GeglBuffer      *dest_buffer;
-      cairo_surface_t *alpha_surface;
+      GimpColorTransform *transform;
+      GeglBuffer         *src_buffer;
+      GeglBuffer         *dest_buffer;
+      cairo_surface_t    *alpha_surface;
 
       alpha_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                                   width, height);
@@ -1109,13 +1243,14 @@ gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
       src_buffer  = gimp_temp_buf_create_buffer (temp_buf);
       dest_buffer = gimp_cairo_surface_create_buffer (alpha_surface);
 
-      if (! renderer->priv->profile_transform)
-        gimp_view_renderer_transform_create (renderer, widget,
-                                             src_buffer, dest_buffer);
+      transform =
+        gimp_view_renderer_get_color_transform (renderer, widget,
+                                                gegl_buffer_get_format (src_buffer),
+                                                gegl_buffer_get_format (dest_buffer));
 
-      if (renderer->priv->profile_transform)
+      if (transform)
         {
-          gimp_color_transform_process_buffer (renderer->priv->profile_transform,
+          gimp_color_transform_process_buffer (transform,
                                                src_buffer,
                                                GEGL_RECTANGLE (x - temp_buf_x,
                                                                y - temp_buf_y,
@@ -1148,21 +1283,23 @@ gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
     }
   else if (channel == -1)
     {
-      GeglBuffer *src_buffer;
-      GeglBuffer *dest_buffer;
+      GimpColorTransform *transform;
+      GeglBuffer         *src_buffer;
+      GeglBuffer         *dest_buffer;
 
       cairo_surface_flush (surface);
 
       src_buffer  = gimp_temp_buf_create_buffer (temp_buf);
       dest_buffer = gimp_cairo_surface_create_buffer (surface);
 
-      if (! renderer->priv->profile_transform)
-        gimp_view_renderer_transform_create (renderer, widget,
-                                             src_buffer, dest_buffer);
+      transform =
+        gimp_view_renderer_get_color_transform (renderer, widget,
+                                                gegl_buffer_get_format (src_buffer),
+                                                gegl_buffer_get_format (dest_buffer));
 
-      if (renderer->priv->profile_transform)
+      if (transform)
         {
-          gimp_color_transform_process_buffer (renderer->priv->profile_transform,
+          gimp_color_transform_process_buffer (transform,
                                                src_buffer,
                                                GEGL_RECTANGLE (x - temp_buf_x,
                                                                y - temp_buf_y,
@@ -1278,41 +1415,6 @@ gimp_view_renderer_create_background (GimpViewRenderer *renderer,
 }
 
 static void
-gimp_view_renderer_transform_create (GimpViewRenderer *renderer,
-                                     GtkWidget        *widget,
-                                     GeglBuffer       *src_buffer,
-                                     GeglBuffer       *dest_buffer)
-{
-  if (GIMP_IS_COLOR_MANAGED (renderer->viewable))
-    {
-      GimpColorManaged *managed = GIMP_COLOR_MANAGED (renderer->viewable);
-      GimpColorProfile *profile;
-
-      if (G_UNLIKELY (renderer->context == NULL))
-        {
-          g_warning ("%s: renderer->context is NULL", G_STRFUNC);
-          return;
-        }
-
-      profile = gimp_color_managed_get_color_profile (managed);
-
-      if (profile)
-        {
-          GimpColorConfig *config = renderer->priv->color_config;
-
-          if (! config)
-            config = renderer->context->gimp->config->color_management;
-
-          renderer->priv->profile_transform =
-            gimp_widget_get_color_transform (widget, config,
-                                             profile,
-                                             gegl_buffer_get_format (src_buffer),
-                                             gegl_buffer_get_format (dest_buffer));
-        }
-    }
-}
-
-static void
 gimp_view_renderer_transform_free (GimpViewRenderer *renderer)
 {
   if (renderer->priv->profile_transform)
diff --git a/app/widgets/gimpviewrenderer.h b/app/widgets/gimpviewrenderer.h
index 90554df..c5237eb 100644
--- a/app/widgets/gimpviewrenderer.h
+++ b/app/widgets/gimpviewrenderer.h
@@ -156,6 +156,11 @@ void   gimp_view_renderer_render_pixbuf          (GimpViewRenderer *renderer,
 void   gimp_view_renderer_render_icon            (GimpViewRenderer *renderer,
                                                   GtkWidget        *widget,
                                                   const gchar      *icon_name);
+GimpColorTransform *
+       gimp_view_renderer_get_color_transform    (GimpViewRenderer *renderer,
+                                                  GtkWidget        *widget,
+                                                  const Babl       *src_format,
+                                                  const Babl       *dest_format);
 
 
 


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