[gtk/matthiasc/color-profile-rebased: 14/47] memoryformat: Take a color space when converting




commit 1e026f316bdffb5fea39f55f6276fc5e0bfdc14b
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun May 8 07:59:50 2022 -0400

    memoryformat: Take a color space when converting

 gdk/gdkgltexture.c           |  7 ++++++-
 gdk/gdkmemoryformat.c        | 38 ++++++++++++++++++++++++++++++++++----
 gdk/gdkmemoryformatprivate.h |  3 +++
 gdk/gdkmemorytexture.c       |  5 ++++-
 gdk/gdktexture.c             |  5 ++++-
 gdk/gdktextureprivate.h      |  2 ++
 gsk/gl/gskglglyphlibrary.c   |  2 ++
 gsk/gl/gskgliconlibrary.c    |  5 ++++-
 8 files changed, 59 insertions(+), 8 deletions(-)
---
diff --git a/gdk/gdkgltexture.c b/gdk/gdkgltexture.c
index 4cc070a5c1..f59673f415 100644
--- a/gdk/gdkgltexture.c
+++ b/gdk/gdkgltexture.c
@@ -116,6 +116,7 @@ typedef struct _Download Download;
 struct _Download
 {
   GdkMemoryFormat format;
+  GdkColorSpace *color_space;
   guchar *data;
   gsize stride;
 };
@@ -213,9 +214,11 @@ gdk_gl_texture_do_download (gpointer texture_,
           gdk_memory_convert (download->data,
                               download->stride,
                               download->format,
+                              download->color_space,
                               pixels,
                               texture->width * actual_bpp,
                               actual_format,
+                              gdk_color_space_get_srgb (),
                               texture->width,
                               texture->height);
 
@@ -229,6 +232,7 @@ gdk_gl_texture_do_download (gpointer texture_,
 static void
 gdk_gl_texture_download (GdkTexture      *texture,
                          GdkMemoryFormat  format,
+                         GdkColorSpace   *color_space,
                          guchar          *data,
                          gsize            stride)
 {
@@ -237,11 +241,12 @@ gdk_gl_texture_download (GdkTexture      *texture,
 
   if (self->saved)
     {
-      gdk_texture_do_download (self->saved, format, data, stride);
+      gdk_texture_do_download (self->saved, format, color_space, data, stride);
       return;
     }
 
   download.format = format;
+  download.color_space = color_space;
   download.data = data;
   download.stride = stride;
 
diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c
index 5bd7b228d4..ca202fb36e 100644
--- a/gdk/gdkmemoryformat.c
+++ b/gdk/gdkmemoryformat.c
@@ -21,6 +21,7 @@
 
 #include "gdkmemoryformatprivate.h"
 
+#include "gdklcmscolorspaceprivate.h"
 #include "gsk/gl/fp16private.h"
 
 #include <epoxy/gl.h>
@@ -513,14 +514,17 @@ void
 gdk_memory_convert (guchar              *dest_data,
                     gsize                dest_stride,
                     GdkMemoryFormat      dest_format,
+                    GdkColorSpace       *dest_color_space,
                     const guchar        *src_data,
                     gsize                src_stride,
                     GdkMemoryFormat      src_format,
+                    GdkColorSpace       *src_color_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;
   void (*func) (guchar *, const guchar *, gsize) = NULL;
@@ -578,17 +582,43 @@ gdk_memory_convert (guchar              *dest_data,
 
   tmp = g_new (float, width * 4);
 
+  if (gdk_color_space_equal (src_color_space, dest_color_space))
+    {
+      transform = NULL;
+    }
+  else
+    {
+      transform = cmsCreateTransform (gdk_lcms_color_space_get_lcms_profile (src_color_space),
+                                      TYPE_RGBA_FLT,
+                                      gdk_lcms_color_space_get_lcms_profile (dest_color_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 3618852f02..d916091368 100644
--- a/gdk/gdkmemoryformatprivate.h
+++ b/gdk/gdkmemoryformatprivate.h
@@ -21,6 +21,7 @@
 #define __GDK_MEMORY_CONVERT_PRIVATE_H__
 
 #include "gdkenums.h"
+#include "gdkcolorspace.h"
 
 G_BEGIN_DECLS
 
@@ -43,9 +44,11 @@ gboolean                gdk_memory_format_gl_format         (GdkMemoryFormat
 void                    gdk_memory_convert                  (guchar                     *dest_data,
                                                              gsize                       dest_stride,
                                                              GdkMemoryFormat             dest_format,
+                                                             GdkColorSpace              *dest_color_space,
                                                              const guchar               *src_data,
                                                              gsize                       src_stride,
                                                              GdkMemoryFormat             src_format,
+                                                             GdkColorSpace              *src_color_space,
                                                              gsize                       width,
                                                              gsize                       height);
 
diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c
index 6d06ba971c..3dc7faca9a 100644
--- a/gdk/gdkmemorytexture.c
+++ b/gdk/gdkmemorytexture.c
@@ -60,6 +60,7 @@ gdk_memory_texture_dispose (GObject *object)
 static void
 gdk_memory_texture_download (GdkTexture      *texture,
                              GdkMemoryFormat  format,
+                             GdkColorSpace   *color_space,
                              guchar          *data,
                              gsize            stride)
 {
@@ -67,9 +68,11 @@ gdk_memory_texture_download (GdkTexture      *texture,
 
   gdk_memory_convert (data, stride,
                       format,
+                      color_space,
                       (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));
 }
@@ -266,7 +269,7 @@ gdk_memory_texture_from_texture (GdkTexture      *texture,
   stride = texture->width * gdk_memory_format_bytes_per_pixel (format);
   data = g_malloc_n (stride, texture->height);
 
-  gdk_texture_do_download (texture, format, data, stride);
+  gdk_texture_do_download (texture, format, gdk_color_space_get_srgb (), data, stride);
   bytes = g_bytes_new_take (data, stride);
   result = gdk_memory_texture_new (texture->width,
                                    texture->height,
diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c
index bc1dc0cf57..d36d3ac883 100644
--- a/gdk/gdktexture.c
+++ b/gdk/gdktexture.c
@@ -226,6 +226,7 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GdkTexture, gdk_texture, G_TYPE_OBJECT,
 static void
 gdk_texture_default_download (GdkTexture      *texture,
                               GdkMemoryFormat  format,
+                              GdkColorSpace   *color_space,
                               guchar          *data,
                               gsize            stride)
 {
@@ -712,10 +713,11 @@ gdk_texture_get_color_space (GdkTexture *texture)
 void
 gdk_texture_do_download (GdkTexture      *texture,
                          GdkMemoryFormat  format,
+                         GdkColorSpace   *color_space,
                          guchar          *data,
                          gsize            stride)
 {
-  GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, data, stride);
+  GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, color_space, data, stride);
 }
 
 cairo_surface_t *
@@ -778,6 +780,7 @@ gdk_texture_download (GdkTexture *texture,
 
   gdk_texture_do_download (texture,
                            GDK_MEMORY_DEFAULT,
+                           gdk_color_space_get_srgb (),
                            data,
                            stride);
 }
diff --git a/gdk/gdktextureprivate.h b/gdk/gdktextureprivate.h
index 7102cecac2..9d852ab2c7 100644
--- a/gdk/gdktextureprivate.h
+++ b/gdk/gdktextureprivate.h
@@ -31,6 +31,7 @@ struct _GdkTextureClass {
   /* mandatory: Download in the given format into data */
   void                  (* download)                    (GdkTexture             *texture,
                                                          GdkMemoryFormat         format,
+                                                         GdkColorSpace          *color_space,
                                                          guchar                 *data,
                                                          gsize                   stride);
 };
@@ -42,6 +43,7 @@ cairo_surface_t *       gdk_texture_download_surface    (GdkTexture
 
 void                    gdk_texture_do_download         (GdkTexture             *texture,
                                                          GdkMemoryFormat         format,
+                                                         GdkColorSpace          *color_space,
                                                          guchar                 *data,
                                                          gsize                   stride);
 GdkMemoryFormat         gdk_texture_get_format          (GdkTexture             *self);
diff --git a/gsk/gl/gskglglyphlibrary.c b/gsk/gl/gskglglyphlibrary.c
index 58e34bc938..11c269eb92 100644
--- a/gsk/gl/gskglglyphlibrary.c
+++ b/gsk/gl/gskglglyphlibrary.c
@@ -284,9 +284,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..4d7d50734f 100644
--- a/gsk/gl/gskgliconlibrary.c
+++ b/gsk/gl/gskgliconlibrary.c
@@ -116,8 +116,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]