[gtk/wip/otte/colorspace: 11/19] memoryformat: Take a color profile when converting




commit 717a25d1cbac940db7262f55456a58c04acb18db
Author: Benjamin Otte <otte redhat com>
Date:   Wed Sep 22 05:38:07 2021 +0200

    memoryformat: Take a color profile when converting

 gdk/gdkcolorspace.c            |  4 ++--
 gdk/gdkgltexture.c             |  3 +++
 gdk/gdklcmscolorspace.c        |  5 +++++
 gdk/gdklcmscolorspaceprivate.h |  2 ++
 gdk/gdkmemoryformat.c          | 43 ++++++++++++++++++++++++++++++++++++++----
 gdk/gdkmemoryformatprivate.h   |  2 ++
 gdk/gdkmemorytexture.c         |  3 +++
 gsk/gl/gskglglyphlibrary.c     |  2 ++
 gsk/gl/gskgliconlibrary.c      |  6 +++++-
 9 files changed, 63 insertions(+), 7 deletions(-)
---
diff --git a/gdk/gdkcolorspace.c b/gdk/gdkcolorspace.c
index e6aa692fc1..bafcd296e9 100644
--- a/gdk/gdkcolorspace.c
+++ b/gdk/gdkcolorspace.c
@@ -34,6 +34,7 @@
 #include "gdkcolorspaceprivate.h"
 
 #include "gdkintl.h"
+#include "gdklcmscolorspaceprivate.h"
 
 enum {
   PROP_0,
@@ -141,8 +142,7 @@ gdk_color_space_get_srgb (void)
     {
       GdkColorSpace *new_profile;
 
-      new_profile = NULL; //gdk_color_space_new_from_lcms_profile (cmsCreate_sRGBProfile (), NULL);
-      g_assert (new_profile);
+      new_profile = gdk_lcms_color_space_new_from_lcms_profile (cmsCreate_sRGBProfile ());
 
       g_once_init_leave (&srgb_profile, new_profile);
     }
diff --git a/gdk/gdkgltexture.c b/gdk/gdkgltexture.c
index 867fd538cd..ed5977ca41 100644
--- a/gdk/gdkgltexture.c
+++ b/gdk/gdkgltexture.c
@@ -20,6 +20,7 @@
 
 #include "gdkgltextureprivate.h"
 
+#include "gdkcolorspace.h"
 #include "gdkdisplayprivate.h"
 #include "gdkmemoryformatprivate.h"
 #include "gdkmemorytextureprivate.h"
@@ -202,9 +203,11 @@ gdk_gl_texture_do_download (gpointer texture_,
           gdk_memory_convert (download->data,
                               download->stride,
                               download->format,
+                              gdk_color_space_get_srgb (),
                               pixels,
                               texture->width * actual_bpp,
                               actual_format,
+                              texture->color_space,
                               texture->width,
                               texture->height);
 
diff --git a/gdk/gdklcmscolorspace.c b/gdk/gdklcmscolorspace.c
index e91eb9eeed..c2f33e846c 100644
--- a/gdk/gdklcmscolorspace.c
+++ b/gdk/gdklcmscolorspace.c
@@ -146,3 +146,8 @@ gdk_color_space_new_from_icc_profile (GBytes  *icc_profile,
   return gdk_lcms_color_space_new_from_lcms_profile (lcms_profile);
 }
 
+cmsHPROFILE
+gdk_lcms_color_space_get_lcms_profile (GdkLcmsColorSpace *self)
+{
+  return self->lcms_profile;
+}
diff --git a/gdk/gdklcmscolorspaceprivate.h b/gdk/gdklcmscolorspaceprivate.h
index 92f48c5e72..bf5c9f727a 100644
--- a/gdk/gdklcmscolorspaceprivate.h
+++ b/gdk/gdklcmscolorspaceprivate.h
@@ -42,6 +42,8 @@ GType                   gdk_lcms_color_space_get_type                   (void) G
 
 GdkColorSpace *         gdk_lcms_color_space_new_from_lcms_profile      (cmsHPROFILE             
lcms_profile);
 
+cmsHPROFILE             gdk_lcms_color_space_get_lcms_profile           (GdkLcmsColorSpace      *self);
+
 G_END_DECLS
 
 #endif /* __GDK_LCMS_COLOR_SPACE_PRIVATE_H__ */
diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c
index 60c3317bc8..fbd409ad06 100644
--- a/gdk/gdkmemoryformat.c
+++ b/gdk/gdkmemoryformat.c
@@ -21,6 +21,9 @@
 
 #include "gdkmemoryformatprivate.h"
 
+#include "gdkcolorspaceprivate.h"
+#include "gdklcmscolorspaceprivate.h"
+
 #include "gsk/gl/fp16private.h"
 
 #include <epoxy/gl.h>
@@ -465,14 +468,17 @@ void
 gdk_memory_convert (guchar              *dest_data,
                     gsize                dest_stride,
                     GdkMemoryFormat      dest_format,
+                    GdkColorSpace       *dest_space,
                     const guchar        *src_data,
                     gsize                src_stride,
                     GdkMemoryFormat      src_format,
+                    GdkColorSpace       *src_space,
                     gsize                width,
                     gsize                height)
 {
   const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
   const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
+  cmsHTRANSFORM transform;
   float *tmp;
   gsize y;
 
@@ -481,17 +487,46 @@ gdk_memory_convert (guchar              *dest_data,
 
   tmp = g_new (float, width * 4);
 
+  if (gdk_color_space_equal (src_space, dest_space))
+    {
+      transform = NULL;
+    }
+  else
+    {
+      transform = cmsCreateTransform (gdk_lcms_color_space_get_lcms_profile (GDK_LCMS_COLOR_SPACE 
(src_space)),
+                                      TYPE_RGBA_FLT,
+                                      gdk_lcms_color_space_get_lcms_profile (GDK_LCMS_COLOR_SPACE 
(dest_space)),
+                                      TYPE_RGBA_FLT,
+                                      INTENT_PERCEPTUAL,
+                                      cmsFLAGS_COPY_ALPHA);
+    }
+
   for (y = 0; y < height; y++)
     {
       src_desc->to_float (tmp, src_data, width);
-      if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED && dest_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT)
-        unpremultiply (tmp, width);
-      else if (src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT)
-        premultiply (tmp, width);
+      if (transform)
+        {
+          if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED)
+            unpremultiply (tmp, width);
+          cmsDoTransform (transform,
+                          tmp,
+                          tmp,
+                          width);
+          if (dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT)
+            premultiply (tmp, width);
+        }
+      else
+        {
+          if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED && dest_desc->alpha == 
GDK_MEMORY_ALPHA_STRAIGHT)
+            unpremultiply (tmp, width);
+          else if (src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != 
GDK_MEMORY_ALPHA_STRAIGHT)
+            premultiply (tmp, width);
+        }
       dest_desc->from_float (dest_data, tmp, width);
       src_data += src_stride;
       dest_data += dest_stride;
     }
 
   g_free (tmp);
+  g_clear_pointer (&transform, cmsDeleteTransform);
 }
diff --git a/gdk/gdkmemoryformatprivate.h b/gdk/gdkmemoryformatprivate.h
index bd75192dfe..bfe3cc0bbd 100644
--- a/gdk/gdkmemoryformatprivate.h
+++ b/gdk/gdkmemoryformatprivate.h
@@ -43,9 +43,11 @@ gboolean                gdk_memory_format_gl_format         (GdkMemoryFormat
 void                    gdk_memory_convert                  (guchar                     *dest_data,
                                                              gsize                       dest_stride,
                                                              GdkMemoryFormat             dest_format,
+                                                             GdkColorSpace              *dest_space,
                                                              const guchar               *src_data,
                                                              gsize                       src_stride,
                                                              GdkMemoryFormat             src_format,
+                                                             GdkColorSpace              *src_space,
                                                              gsize                       width,
                                                              gsize                       height);
 
diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c
index 71df887b0b..9827bf5cb0 100644
--- a/gdk/gdkmemorytexture.c
+++ b/gdk/gdkmemorytexture.c
@@ -21,6 +21,7 @@
 
 #include "gdkmemorytextureprivate.h"
 
+#include "gdkcolorspace.h"
 #include "gdkmemoryformatprivate.h"
 #include "gsk/gl/fp16private.h"
 
@@ -65,9 +66,11 @@ gdk_memory_texture_download (GdkTexture      *texture,
 
   gdk_memory_convert (data, stride,
                       format,
+                      gdk_color_space_get_srgb (),
                       (guchar *) g_bytes_get_data (self->bytes, NULL),
                       self->stride,
                       texture->format,
+                      gdk_texture_get_color_space (texture),
                       gdk_texture_get_width (texture),
                       gdk_texture_get_height (texture));
 }
diff --git a/gsk/gl/gskglglyphlibrary.c b/gsk/gl/gskglglyphlibrary.c
index fd4518d341..be6c787524 100644
--- a/gsk/gl/gskglglyphlibrary.c
+++ b/gsk/gl/gskglglyphlibrary.c
@@ -238,9 +238,11 @@ gsk_gl_glyph_library_upload_glyph (GskGLGlyphLibrary     *self,
       gdk_memory_convert (pixel_data,
                           width * 4,
                           GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+                          gdk_color_space_get_srgb (),
                           cairo_image_surface_get_data (surface),
                           width * 4,
                           GDK_MEMORY_DEFAULT,
+                          gdk_color_space_get_srgb (),
                           width, height);
       gl_format = GL_RGBA;
       gl_type = GL_UNSIGNED_BYTE;
diff --git a/gsk/gl/gskgliconlibrary.c b/gsk/gl/gskgliconlibrary.c
index f4686fd877..4ecfaf5bf7 100644
--- a/gsk/gl/gskgliconlibrary.c
+++ b/gsk/gl/gskgliconlibrary.c
@@ -20,6 +20,7 @@
 
 #include "config.h"
 
+#include <gdk/gdkcolorspace.h>
 #include <gdk/gdkglcontextprivate.h>
 #include <gdk/gdkmemoryformatprivate.h>
 #include <gdk/gdkprofilerprivate.h>
@@ -116,8 +117,11 @@ gsk_gl_icon_library_add (GskGLIconLibrary     *self,
       pixel_data = free_data = g_malloc (width * height * 4);
       gdk_memory_convert (pixel_data, width * 4,
                           GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+                          gdk_color_space_get_srgb (),
                           surface_data, cairo_image_surface_get_stride (surface),
-                          GDK_MEMORY_DEFAULT, width, height);
+                          GDK_MEMORY_DEFAULT,
+                          gdk_color_space_get_srgb (),
+                          width, height);
       gl_format = GL_RGBA;
       gl_type = GL_UNSIGNED_BYTE;
     }


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