[gtk/wip/otte/color-profiles: 17/40] memorytexture: Add gdk_memory_texture_convert()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/color-profiles: 17/40] memorytexture: Add gdk_memory_texture_convert()
- Date: Thu, 30 Sep 2021 23:20:39 +0000 (UTC)
commit 61f1dde5fe1b9f4ba496d03a50f8aeed02e9f1de
Author: Benjamin Otte <otte redhat com>
Date: Sat Sep 25 21:15:18 2021 +0200
memorytexture: Add gdk_memory_texture_convert()
Converts a memory texture to a new one with a specific format and color
profile. You can even pass a rectangle to restrict the result to a given
region.
The code is well optimized, so it avoids copies if things match and will
in fact return the texture itself if the same colorspace and format and
no/the full rectangle are passed, so it can be used without fear of
performance implications.
In fact, the following code should be used - without any additional
checks - to turn any texture into a desired color profile and format
(say for saving with gdk-pixbuf):
memtex = gdk_texture_download (texture);
memtex = gdk_memory_texture_convert (memory_texture,
GDK_MEMORY_R8G8B8A8,
gdk_color_profile_get_srgb(),
NULL);
pixbuf = gdk_pixbuf_new_from_data (gdk_memory_texture_get_data (memtex),
GDK_COLOR_SPACE_RGB,
TRUE,
8
gdk_texture_get_width (memtex),
gdk_texture_get_height (memtex),
gdk_memory_texture_get_stride (memtex),
g_object_unref_wrapper,
memtex);
gdk/gdkmemorytexture.c | 76 +++++++++++++++++++++++++++++++++++++++++++
gdk/gdkmemorytextureprivate.h | 12 +++++--
2 files changed, 85 insertions(+), 3 deletions(-)
---
diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c
index 3f64b423f3..2da8380aa2 100644
--- a/gdk/gdkmemorytexture.c
+++ b/gdk/gdkmemorytexture.c
@@ -235,12 +235,88 @@ gdk_memory_texture_new_with_color_profile (int width,
return GDK_TEXTURE (self);
}
+GdkMemoryTexture *
+gdk_memory_texture_convert (GdkMemoryTexture *source,
+ GdkMemoryFormat to_format,
+ GdkColorProfile *to_profile,
+ const GdkRectangle *rect_or_null)
+{
+ GdkTexture *texture = GDK_TEXTURE (source);
+ GdkTexture *result;
+ GBytes *to_bytes;
+ int width, height;
+ gsize offset, stride;
+
+ width = texture->width;
+ height = texture->height;
+ if (rect_or_null)
+ {
+ g_assert (rect_or_null->x + rect_or_null->width <= width);
+ g_assert (rect_or_null->y + rect_or_null->height <= height);
+
+ offset = rect_or_null->y * source->stride +
+ rect_or_null->x * gdk_memory_format_bytes_per_pixel (source->format);
+ width = rect_or_null->width;
+ height = rect_or_null->height;
+ }
+ else
+ offset = 0;
+
+ if (to_format == source->format &&
+ gdk_color_profile_equal (texture->color_profile, to_profile))
+ {
+ if (offset == 0 && width == texture->width && height == texture->height)
+ return source;
+
+ to_bytes = g_bytes_new_from_bytes (source->bytes,
+ offset,
+ source->stride * height);
+ stride = source->stride;
+ }
+ else
+ {
+ guchar *data;
+
+ stride = gdk_memory_format_bytes_per_pixel (to_format) * width;
+ data = g_malloc_n (stride, height);
+ gdk_memory_convert (data,
+ stride,
+ to_format,
+ to_profile,
+ (guchar *) g_bytes_get_data (source->bytes, NULL) + offset,
+ source->stride,
+ source->format,
+ texture->color_profile,
+ width,
+ height);
+ to_bytes = g_bytes_new_take (data, stride * height);
+ }
+
+ result = gdk_memory_texture_new_with_color_profile (width,
+ height,
+ to_format,
+ to_profile,
+ to_bytes,
+ stride);
+
+ g_bytes_unref (to_bytes);
+ g_object_unref (source);
+
+ return GDK_MEMORY_TEXTURE (result);
+}
+
GdkMemoryFormat
gdk_memory_texture_get_format (GdkMemoryTexture *self)
{
return self->format;
}
+GBytes *
+gdk_memory_texture_get_bytes (GdkMemoryTexture *self)
+{
+ return self->bytes;
+}
+
const guchar *
gdk_memory_texture_get_data (GdkMemoryTexture *self)
{
diff --git a/gdk/gdkmemorytextureprivate.h b/gdk/gdkmemorytextureprivate.h
index f61cccb9ef..8966decb24 100644
--- a/gdk/gdkmemorytextureprivate.h
+++ b/gdk/gdkmemorytextureprivate.h
@@ -29,9 +29,15 @@ G_BEGIN_DECLS
#define GDK_MEMORY_GDK_PIXBUF_OPAQUE GDK_MEMORY_R8G8B8
#define GDK_MEMORY_GDK_PIXBUF_ALPHA GDK_MEMORY_R8G8B8A8
-GdkMemoryFormat gdk_memory_texture_get_format (GdkMemoryTexture *self);
-const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
-gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
+GdkMemoryTexture * gdk_memory_texture_convert (GdkMemoryTexture *source,
+ GdkMemoryFormat to_format,
+ GdkColorProfile *to_profile,
+ const GdkRectangle *rect_or_null);
+
+GdkMemoryFormat gdk_memory_texture_get_format (GdkMemoryTexture *self);
+GBytes * gdk_memory_texture_get_bytes (GdkMemoryTexture *self);
+const guchar * gdk_memory_texture_get_data (GdkMemoryTexture *self);
+gsize gdk_memory_texture_get_stride (GdkMemoryTexture *self);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]