[gimp/blend-tool-fun: 147/163] Bug 751553 - Linear precision doesn't display the image correctly



commit 8832a19f49067171e6642058f6c33c2746799f9f
Author: Michael Natterer <mitch gimp org>
Date:   Tue Oct 20 23:53:47 2015 +0200

    Bug 751553 - Linear precision doesn't display the image correctly
    
    When converting and image with a color profileimage between linear and
    gamma, create a new profile using the new API in GimpColorProfile,
    convert the layers to that profile and tag the image with the new
    profile.
    
    If creating a new profile fails, convert to the right builtin profile
    (linear rgb or sRGB from GimpColorProfile), but that code should be
    considered a fallback that will be prevented from happening in the
    convert dialog (at least the user will be informed).

 app/core/gimpimage-convert-precision.c |   51 +++++++++++++++++++++++++---
 app/core/gimplayer.c                   |   57 +++++++++++++++++++++++++++++--
 2 files changed, 98 insertions(+), 10 deletions(-)
---
diff --git a/app/core/gimpimage-convert-precision.c b/app/core/gimpimage-convert-precision.c
index a3ed0c8..e2c67b8 100644
--- a/app/core/gimpimage-convert-precision.c
+++ b/app/core/gimpimage-convert-precision.c
@@ -20,15 +20,19 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
+#include "libgimpcolor/gimpcolor.h"
+
 #include "core-types.h"
 
-#include "gegl/gimp-gegl-utils.h"
+#include "gegl/gimp-babl.h"
 
 #include "gimpdrawable.h"
 #include "gimpimage.h"
+#include "gimpimage-color-profile.h"
 #include "gimpimage-convert-precision.h"
 #include "gimpimage-undo.h"
 #include "gimpimage-undo-push.h"
@@ -47,10 +51,13 @@ gimp_image_convert_precision (GimpImage     *image,
                               gint           mask_dither_type,
                               GimpProgress  *progress)
 {
-  GList       *all_drawables;
-  GList       *list;
-  const gchar *undo_desc = NULL;
-  gint         nth_drawable, n_drawables;
+  GimpColorProfile *old_profile;
+  const Babl       *old_format;
+  const Babl       *new_format;
+  GList            *all_drawables;
+  GList            *list;
+  const gchar      *undo_desc = NULL;
+  gint              nth_drawable, n_drawables;
 
   g_return_if_fail (GIMP_IS_IMAGE (image));
   g_return_if_fail (precision != gimp_image_get_precision (image));
@@ -114,9 +121,14 @@ gimp_image_convert_precision (GimpImage     *image,
   /*  Push the image precision to the stack  */
   gimp_image_undo_push_image_precision (image, NULL);
 
+  old_profile = gimp_image_get_color_profile (image);
+  old_format  = gimp_image_get_layer_format (image, FALSE);
+
   /*  Set the new precision  */
   g_object_set (image, "precision", precision, NULL);
 
+  new_format = gimp_image_get_layer_format (image, FALSE);
+
   for (list = all_drawables, nth_drawable = 0;
        list;
        list = g_list_next (list), nth_drawable++)
@@ -134,15 +146,42 @@ gimp_image_convert_precision (GimpImage     *image,
                                   precision,
                                   dither_type,
                                   mask_dither_type,
-                                  FALSE,
+                                  old_profile != NULL,
                                   TRUE);
 
       if (progress)
         gimp_progress_set_value (progress,
                                  (gdouble) nth_drawable / (gdouble) n_drawables);
     }
+
   g_list_free (all_drawables);
 
+  if (old_profile &&
+      gimp_babl_format_get_linear (old_format) !=
+      gimp_babl_format_get_linear (new_format))
+    {
+      GimpColorProfile *new_profile;
+
+      /* the comments in gimp_layer_convert_type() explain the logic
+       * here
+       */
+      if (gimp_babl_format_get_linear (new_format))
+        {
+          new_profile =
+            gimp_color_profile_new_linear_rgb_from_color_profile (old_profile);
+        }
+      else
+        {
+          new_profile =
+            gimp_color_profile_new_srgb_gamma_from_color_profile (old_profile);
+        }
+
+      gimp_image_set_color_profile (image, new_profile, NULL);
+
+      if (new_profile)
+        g_object_unref (new_profile);
+    }
+
   /*  convert the selection mask  */
   {
     GimpChannel *mask = gimp_image_get_mask (image);
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index bf75049..3e30dae 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -33,6 +33,7 @@
 
 #include "config/gimpcoreconfig.h" /* FIXME profile convert config */
 
+#include "gegl/gimp-babl.h"
 #include "gegl/gimp-gegl-apply-operation.h"
 #include "gegl/gimp-gegl-loops.h"
 #include "gegl/gimp-gegl-nodes.h"
@@ -46,6 +47,7 @@
 #include "gimpimage-undo-push.h"
 #include "gimpimage-undo.h"
 #include "gimpimage.h"
+#include "gimpimage-color-profile.h"
 #include "gimplayer-floating-sel.h"
 #include "gimplayer.h"
 #include "gimplayermask.h"
@@ -1103,11 +1105,55 @@ gimp_layer_convert_type (GimpDrawable      *drawable,
 
   if (convert_profile)
     {
-      src_profile =
-        gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer));
+      GimpImage *src_image = gimp_item_get_image (GIMP_ITEM (layer));
 
-      dest_profile =
-        gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (dest_image));
+      if (src_image != dest_image)
+        {
+          src_profile =
+            gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer));
+
+          dest_profile =
+            gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (dest_image));
+          g_object_ref (dest_profile);
+        }
+      else if (gimp_image_get_color_profile (src_image))
+        {
+          const Babl *src_format = gimp_drawable_get_format (drawable);
+
+          /* when converting between linear and gamma, we create a new
+           * profile using the original profile's chromacities and
+           * whitepoint, but a linear/sRGB-gamma TRC.
+           * gimp_image_convert_precision() will use the same profile.
+           */
+          if (gimp_babl_format_get_linear (src_format) !=
+              gimp_babl_format_get_linear (new_format))
+            {
+              src_profile =
+                gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer));
+
+              if (gimp_babl_format_get_linear (new_format))
+                {
+                  dest_profile =
+                    gimp_color_profile_new_linear_rgb_from_color_profile (src_profile);
+                }
+              else
+                {
+                  dest_profile =
+                    gimp_color_profile_new_srgb_gamma_from_color_profile (src_profile);
+                }
+
+              /* if a new profile cannot be be generated, convert to the
+               * builtin profile, which is better than leaving the user
+               * with broken colors
+               */
+              if (! dest_profile)
+                {
+                  dest_profile =
+                    gimp_image_get_builtin_color_profile (dest_image);
+                  g_object_ref (dest_profile);
+                }
+            }
+        }
     }
 
   if (src_profile && dest_profile)
@@ -1122,6 +1168,9 @@ gimp_layer_convert_type (GimpDrawable      *drawable,
       gegl_buffer_copy (src_buffer, NULL, GEGL_ABYSS_NONE, dest_buffer, NULL);
     }
 
+  if (dest_profile)
+    g_object_unref (dest_profile);
+
   gimp_drawable_set_buffer (drawable, push_undo, NULL, dest_buffer);
 
   g_object_unref (src_buffer);


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