[gtk/wip/otte/color-profiles: 7/30] memoryformat: Take a color profile when converting
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/color-profiles: 7/30] memoryformat: Take a color profile when converting
- Date: Sun, 26 Sep 2021 14:54:27 +0000 (UTC)
commit 89b5c30f9b4ab82c1cfbb6d3ac346635e855c4ac
Author: Benjamin Otte <otte redhat com>
Date: Wed Sep 22 05:38:07 2021 +0200
memoryformat: Take a color profile when converting
gdk/gdkglcontext.c | 6 ++++-
gdk/gdkglcontextprivate.h | 1 +
gdk/gdkmemoryformat.c | 55 ++++++++++++++++++++++++++++++++++++--------
gdk/gdkmemoryformatprivate.h | 2 ++
gdk/gdkmemorytexture.c | 5 ++++
gsk/ngl/gsknglcommandqueue.c | 4 +++-
gsk/ngl/gsknglglyphlibrary.c | 2 ++
gsk/ngl/gskngliconlibrary.c | 5 +++-
8 files changed, 68 insertions(+), 12 deletions(-)
---
diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c
index 3c9b337cf9..afeb3b5358 100644
--- a/gdk/gdkglcontext.c
+++ b/gdk/gdkglcontext.c
@@ -227,6 +227,7 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
int height,
int stride,
GdkMemoryFormat data_format,
+ GdkColorProfile *color_profile,
guint texture_target)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
@@ -297,7 +298,10 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
copy = g_malloc (width * height * 4);
gdk_memory_convert (copy, width * 4,
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
- data, stride, data_format,
+ gdk_color_profile_get_srgb (),
+ data, stride,
+ data_format,
+ color_profile,
width, height);
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
stride = width * 4;
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index 050e757608..abe8ae43b9 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -111,6 +111,7 @@ void gdk_gl_context_upload_texture (GdkGLContext
int height,
int stride,
GdkMemoryFormat data_format,
+ GdkColorProfile *color_profile,
guint texture_target);
GdkGLContextPaintData * gdk_gl_context_get_paint_data (GdkGLContext *context);
gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext *context);
diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c
index 7db5d3f56a..e78851e5e8 100644
--- a/gdk/gdkmemoryformat.c
+++ b/gdk/gdkmemoryformat.c
@@ -21,6 +21,7 @@
#include "gdkmemoryformatprivate.h"
+#include "gdkcolorprofileprivate.h"
#include "gsk/ngl/fp16private.h"
typedef struct _GdkMemoryFormatDescription GdkMemoryFormatDescription;
@@ -44,6 +45,7 @@ name ## _to_float (float *dest, \
dest[1] = (float) src[G] / scale; \
dest[2] = (float) src[B] / scale; \
if (A >= 0) dest[3] = (float) src[A] / scale; else dest[3] = 1.0; \
+ dest += 4; \
} \
} \
\
@@ -59,6 +61,7 @@ name ## _from_float (guchar *dest_data, \
dest[G] = CLAMP (src[1] * (scale + 1), 0, scale); \
dest[B] = CLAMP (src[2] * (scale + 1), 0, scale); \
if (A >= 0) dest[A] = CLAMP (src[3] * (scale + 1), 0, scale); \
+ src += 4; \
} \
}
@@ -318,11 +321,13 @@ unpremultiply (float *rgba,
{
for (gsize i = 0; i < n; i++)
{
- if (rgba[3] <= 1/255.0)
- continue;
- rgba[0] /= rgba[3];
- rgba[1] /= rgba[3];
- rgba[2] /= rgba[3];
+ if (rgba[3] > 1/255.0)
+ {
+ rgba[0] /= rgba[3];
+ rgba[1] /= rgba[3];
+ rgba[2] /= rgba[3];
+ }
+ rgba += 4;
}
}
@@ -330,14 +335,17 @@ void
gdk_memory_convert (guchar *dest_data,
gsize dest_stride,
GdkMemoryFormat dest_format,
+ GdkColorProfile *dest_profile,
const guchar *src_data,
gsize src_stride,
GdkMemoryFormat src_format,
+ GdkColorProfile *src_profile,
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;
@@ -346,17 +354,46 @@ gdk_memory_convert (guchar *dest_data,
tmp = g_new (float, width * 4);
+ if (gdk_color_profile_equal (src_profile, dest_profile))
+ {
+ transform = NULL;
+ }
+ else
+ {
+ transform = cmsCreateTransform (gdk_color_profile_get_lcms_profile (src_profile),
+ TYPE_RGBA_FLT,
+ gdk_color_profile_get_lcms_profile (dest_profile),
+ 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 0de89f0756..ca0e4c2c1b 100644
--- a/gdk/gdkmemoryformatprivate.h
+++ b/gdk/gdkmemoryformatprivate.h
@@ -30,9 +30,11 @@ gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat
void gdk_memory_convert (guchar *dest_data,
gsize dest_stride,
GdkMemoryFormat dest_format,
+ GdkColorProfile *dest_profile,
const guchar *src_data,
gsize src_stride,
GdkMemoryFormat src_format,
+ GdkColorProfile *src_profile,
gsize width,
gsize height);
diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c
index 33ba90fe5c..61ac5d31fc 100644
--- a/gdk/gdkmemorytexture.c
+++ b/gdk/gdkmemorytexture.c
@@ -21,6 +21,7 @@
#include "gdkmemorytextureprivate.h"
+#include "gdkcolorprofile.h"
#include "gdkmemoryformatprivate.h"
#include "gsk/ngl/fp16private.h"
@@ -72,9 +73,11 @@ gdk_memory_texture_download (GdkTexture *texture,
gdk_memory_convert (data, stride,
GDK_MEMORY_DEFAULT,
+ gdk_color_profile_get_srgb (),
(guchar *) g_bytes_get_data (self->bytes, NULL),
self->stride,
self->format,
+ gdk_texture_get_color_profile (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture));
}
@@ -89,9 +92,11 @@ gdk_memory_texture_download_float (GdkTexture *texture,
gdk_memory_convert ((guchar *) data,
stride * sizeof (float),
GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED,
+ gdk_color_profile_get_srgb (),
(guchar *) g_bytes_get_data (self->bytes, NULL),
self->stride,
self->format,
+ gdk_texture_get_color_profile (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture));
}
diff --git a/gsk/ngl/gsknglcommandqueue.c b/gsk/ngl/gsknglcommandqueue.c
index b2a474cf59..e8c44243aa 100644
--- a/gsk/ngl/gsknglcommandqueue.c
+++ b/gsk/ngl/gsknglcommandqueue.c
@@ -1386,7 +1386,9 @@ gsk_ngl_command_queue_upload_texture (GskNglCommandQueue *self,
gdk_gl_context_upload_texture (gdk_gl_context_get_current (),
data + x_offset * bpp + y_offset * data_stride,
width, height, data_stride,
- data_format, GL_TEXTURE_2D);
+ data_format,
+ gdk_color_profile_get_srgb (),
+ GL_TEXTURE_2D);
/* Restore previous texture state if any */
if (self->attachments->textures[0].id > 0)
diff --git a/gsk/ngl/gsknglglyphlibrary.c b/gsk/ngl/gsknglglyphlibrary.c
index ede4f19105..df477b05f1 100644
--- a/gsk/ngl/gsknglglyphlibrary.c
+++ b/gsk/ngl/gsknglglyphlibrary.c
@@ -238,9 +238,11 @@ gsk_ngl_glyph_library_upload_glyph (GskNglGlyphLibrary *self,
gdk_memory_convert (pixel_data,
width * 4,
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+ gdk_color_profile_get_srgb (),
cairo_image_surface_get_data (surface),
width * 4,
GDK_MEMORY_DEFAULT,
+ gdk_color_profile_get_srgb (),
width, height);
gl_format = GL_RGBA;
gl_type = GL_UNSIGNED_BYTE;
diff --git a/gsk/ngl/gskngliconlibrary.c b/gsk/ngl/gskngliconlibrary.c
index cfc662a9e6..815ab0acd5 100644
--- a/gsk/ngl/gskngliconlibrary.c
+++ b/gsk/ngl/gskngliconlibrary.c
@@ -116,8 +116,11 @@ gsk_ngl_icon_library_add (GskNglIconLibrary *self,
pixel_data = free_data = g_malloc (width * height * 4);
gdk_memory_convert (pixel_data, width * 4,
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+ gdk_color_profile_get_srgb (),
surface_data, cairo_image_surface_get_stride (surface),
- GDK_MEMORY_DEFAULT, width, height);
+ GDK_MEMORY_DEFAULT,
+ gdk_color_profile_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]