[gtk/wip/otte/color-profiles: 25/40] memoryformat: Do some gdk_memory_convert() massaging
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/color-profiles: 25/40] memoryformat: Do some gdk_memory_convert() massaging
- Date: Thu, 30 Sep 2021 23:20:41 +0000 (UTC)
commit bc850287e90af365b27677785e5fc55d21c71048
Author: Benjamin Otte <otte redhat com>
Date: Sun Sep 26 06:06:48 2021 +0200
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 | 173 +++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 142 insertions(+), 31 deletions(-)
---
diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c
index df3df7d0a2..f7d0c97978 100644
--- a/gdk/gdkmemoryformat.c
+++ b/gdk/gdkmemoryformat.c
@@ -22,6 +22,7 @@
#include "gdkmemoryformatprivate.h"
#include "gdkcolorprofileprivate.h"
+#include "gdkprofilerprivate.h"
#include "gsk/ngl/fp16private.h"
#include <epoxy/gl.h>
@@ -169,6 +170,7 @@ r32g32b32a32_float_from_float (guchar *dest,
struct _GdkMemoryFormatDescription
{
+ const char *name;
GdkMemoryAlpha alpha;
gsize bytes_per_pixel;
gsize alignment;
@@ -193,6 +195,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),
@@ -202,6 +205,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),
@@ -211,6 +215,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),
@@ -220,6 +225,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),
@@ -229,6 +235,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),
@@ -238,6 +245,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),
@@ -247,6 +255,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),
@@ -256,6 +265,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),
@@ -265,6 +275,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),
@@ -274,6 +285,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),
@@ -283,6 +295,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),
@@ -292,6 +305,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),
@@ -301,6 +315,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),
@@ -310,6 +325,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),
@@ -319,6 +335,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),
@@ -396,6 +413,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,
@@ -408,17 +532,12 @@ 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;
g_assert (dest_format < GDK_MEMORY_N_FORMATS);
g_assert (src_format < GDK_MEMORY_N_FORMATS);
- tmp = g_new (float, width * 4);
-
if (gdk_color_profile_equal (src_profile, dest_profile))
{
transform = NULL;
@@ -433,32 +552,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]