[gtk/matthiasc/color-profile-rebased: 19/43] memoryformat: Do some gdk_memory_convert() massaging
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/color-profile-rebased: 19/43] memoryformat: Do some gdk_memory_convert() massaging
- Date: Sun, 8 May 2022 19:01:16 +0000 (UTC)
commit b514e0b4bd6e8cfedb1586a03e6d4ebb29e4a218
Author: Benjamin Otte <otte redhat com>
Date: Sun May 8 09:45:58 2022 -0400
memoryformat: Do some gdk_memory_convert() massaging
* Add name support to the formats
* Add profiler mark to gdk_memory_convert()
* Split up the different branches of conversion
* Use memcpy for straight copies
gdk/gdkmemoryformat.c | 175 +++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 145 insertions(+), 30 deletions(-)
---
diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c
index 27eedd4bc7..433ec363b3 100644
--- a/gdk/gdkmemoryformat.c
+++ b/gdk/gdkmemoryformat.c
@@ -22,6 +22,7 @@
#include "gdkmemoryformatprivate.h"
#include "gdkcolorprofileprivate.h"
+#include "gdkprofilerprivate.h"
#include "gsk/gl/fp16private.h"
#include <epoxy/gl.h>
@@ -217,6 +218,7 @@ ADD_ALPHA_FUNC(r8g8b8_to_a8b8g8r8, 0, 1, 2, 3, 2, 1, 0)
struct _GdkMemoryFormatDescription
{
+ const char *name;
GdkMemoryAlpha alpha;
gsize bytes_per_pixel;
gsize alignment;
@@ -242,6 +244,7 @@ struct _GdkMemoryFormatDescription
static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = {
+ "B8G8R8A8_PREMULTIPLIED",
GDK_MEMORY_ALPHA_PREMULTIPLIED,
4,
G_ALIGNOF (guchar),
@@ -252,6 +255,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
b8g8r8a8_premultiplied_from_float,
},
[GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = {
+ "A8R8G8B8_PREMULTIPLIED",
GDK_MEMORY_ALPHA_PREMULTIPLIED,
4,
G_ALIGNOF (guchar),
@@ -262,6 +266,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
a8r8g8b8_premultiplied_from_float,
},
[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = {
+ "R8G8B8A8_PREMULTIPLIED",
GDK_MEMORY_ALPHA_PREMULTIPLIED,
4,
G_ALIGNOF (guchar),
@@ -272,6 +277,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
r8g8b8a8_premultiplied_from_float,
},
[GDK_MEMORY_B8G8R8A8] = {
+ "B8G8R8A8",
GDK_MEMORY_ALPHA_STRAIGHT,
4,
G_ALIGNOF (guchar),
@@ -282,6 +288,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
b8g8r8a8_from_float,
},
[GDK_MEMORY_A8R8G8B8] = {
+ "A8R8G8B8",
GDK_MEMORY_ALPHA_STRAIGHT,
4,
G_ALIGNOF (guchar),
@@ -292,6 +299,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
a8r8g8b8_from_float,
},
[GDK_MEMORY_R8G8B8A8] = {
+ "R8G8B8A8",
GDK_MEMORY_ALPHA_STRAIGHT,
4,
G_ALIGNOF (guchar),
@@ -302,6 +310,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
r8g8b8a8_from_float,
},
[GDK_MEMORY_A8B8G8R8] = {
+ "A8B8G8R8",
GDK_MEMORY_ALPHA_STRAIGHT,
4,
G_ALIGNOF (guchar),
@@ -312,6 +321,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
a8b8g8r8_from_float,
},
[GDK_MEMORY_R8G8B8] = {
+ "R8G8B8",
GDK_MEMORY_ALPHA_OPAQUE,
3,
G_ALIGNOF (guchar),
@@ -322,6 +332,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
r8g8b8_from_float,
},
[GDK_MEMORY_B8G8R8] = {
+ "B8G8R8",
GDK_MEMORY_ALPHA_OPAQUE,
3,
G_ALIGNOF (guchar),
@@ -332,6 +343,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
b8g8r8_from_float,
},
[GDK_MEMORY_R16G16B16] = {
+ "R16G16B16",
GDK_MEMORY_ALPHA_OPAQUE,
6,
G_ALIGNOF (guint16),
@@ -342,6 +354,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
r16g16b16_from_float,
},
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = {
+ "R16G16B16A16_PREMULTIPLIED",
GDK_MEMORY_ALPHA_PREMULTIPLIED,
8,
G_ALIGNOF (guint16),
@@ -352,6 +365,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
r16g16b16a16_from_float,
},
[GDK_MEMORY_R16G16B16A16] = {
+ "R16G16B16A16",
GDK_MEMORY_ALPHA_STRAIGHT,
8,
G_ALIGNOF (guint16),
@@ -362,6 +376,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
r16g16b16a16_from_float,
},
[GDK_MEMORY_R16G16B16_FLOAT] = {
+ "R16G16B16_FLOAT",
GDK_MEMORY_ALPHA_OPAQUE,
6,
G_ALIGNOF (guint16),
@@ -372,6 +387,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
r16g16b16_float_from_float,
},
[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] = {
+ "R16G16B16A16_FLOAT_PREMULTIPLIED",
GDK_MEMORY_ALPHA_PREMULTIPLIED,
8,
G_ALIGNOF (guint16),
@@ -382,6 +398,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
r16g16b16a16_float_from_float,
},
[GDK_MEMORY_R16G16B16A16_FLOAT] = {
+ "R16G16B16A16_FLOAT",
GDK_MEMORY_ALPHA_STRAIGHT,
8,
G_ALIGNOF (guint16),
@@ -392,6 +409,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
r16g16b16a16_float_from_float,
},
[GDK_MEMORY_R32G32B32_FLOAT] = {
+ "R32G32B32_FLOAT",
GDK_MEMORY_ALPHA_OPAQUE,
12,
G_ALIGNOF (float),
@@ -402,6 +420,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
r32g32b32_float_from_float,
},
[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] = {
+ "R32G32B32A32_FLOAT_PREMULTIPLIED",
GDK_MEMORY_ALPHA_PREMULTIPLIED,
16,
G_ALIGNOF (float),
@@ -412,6 +431,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
r32g32b32a32_float_from_float,
},
[GDK_MEMORY_R32G32B32A32_FLOAT] = {
+ "R32G32B32A32_FLOAT",
GDK_MEMORY_ALPHA_STRAIGHT,
16,
G_ALIGNOF (float),
@@ -510,6 +530,113 @@ unpremultiply (float *rgba,
}
}
+static void
+gdk_memory_convert_same_format (guchar *dest_data,
+ gsize dest_stride,
+ const guchar *src_data,
+ gsize src_stride,
+ gsize width,
+ gsize height,
+ GdkMemoryFormat format)
+{
+ const GdkMemoryFormatDescription *desc = &memory_formats[format];
+ gsize y, stride;
+
+ stride = desc->bytes_per_pixel * width;
+ if (stride == src_stride && stride == dest_stride)
+ {
+ memcpy (dest_data, src_data, stride * height);
+ }
+ else
+ {
+ for (y = 0; y < height; y++)
+ {
+ memcpy (dest_data + y * dest_stride,
+ src_data + y * src_stride,
+ stride);
+ }
+ }
+}
+
+static void
+gdk_memory_convert_no_transform (guchar *dest_data,
+ gsize dest_stride,
+ GdkMemoryFormat dest_format,
+ const guchar *src_data,
+ gsize src_stride,
+ GdkMemoryFormat src_format,
+ gsize width,
+ gsize height)
+{
+ if (dest_format == src_format)
+ {
+ gdk_memory_convert_same_format (dest_data, dest_stride,
+ src_data, src_stride,
+ width, height,
+ dest_format);
+ }
+ else
+ {
+ const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
+ const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
+ float *tmp;
+ gsize y;
+
+ tmp = g_new (float, width * 4);
+
+ 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);
+ dest_desc->from_float (dest_data, tmp, width);
+ src_data += src_stride;
+ dest_data += dest_stride;
+ }
+
+ g_free (tmp);
+ }
+}
+
+static void
+gdk_memory_convert_transform (guchar *dest_data,
+ gsize dest_stride,
+ GdkMemoryFormat dest_format,
+ const guchar *src_data,
+ gsize src_stride,
+ GdkMemoryFormat src_format,
+ gsize width,
+ gsize height,
+ cmsHTRANSFORM transform)
+{
+ const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
+ const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
+ float *tmp;
+ gsize y;
+
+ tmp = g_new (float, width * 4);
+
+ for (y = 0; y < height; y++)
+ {
+ src_desc->to_float (tmp, src_data, width);
+ 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);
+ dest_desc->from_float (dest_data, tmp, width);
+ src_data += src_stride;
+ dest_data += dest_stride;
+ }
+
+ g_free (tmp);
+}
+
void
gdk_memory_convert (guchar *dest_data,
gsize dest_stride,
@@ -522,10 +649,8 @@ gdk_memory_convert (guchar *dest_data,
gsize width,
gsize height)
{
- const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format];
- const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format];
+ G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
cmsHTRANSFORM transform;
- float *tmp;
gsize y;
void (*func) (guchar *, const guchar *, gsize) = NULL;
@@ -580,8 +705,6 @@ gdk_memory_convert (guchar *dest_data,
return;
}
- tmp = g_new (float, width * 4);
-
if (gdk_color_profile_equal (src_profile, dest_profile))
{
transform = NULL;
@@ -596,32 +719,24 @@ gdk_memory_convert (guchar *dest_data,
cmsFLAGS_COPY_ALPHA);
}
- for (y = 0; y < height; y++)
+ if (transform)
{
- src_desc->to_float (tmp, src_data, 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;
+ gdk_memory_convert_transform (dest_data, dest_stride, dest_format,
+ src_data, src_stride, src_format,
+ width, height,
+ transform);
+ cmsDeleteTransform (transform);
+ }
+ else
+ {
+ gdk_memory_convert_no_transform (dest_data, dest_stride, dest_format,
+ src_data, src_stride, src_format,
+ width, height);
}
- g_free (tmp);
- g_clear_pointer (&transform, cmsDeleteTransform);
+ gdk_profiler_end_markf (start_time, "memory convert", "%zu pixels %s => %s%s",
+ width * height,
+ memory_formats[src_format].name,
+ memory_formats[dest_format].name,
+ transform ? " transformed" : "");
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]