[gtk/gamma-shenanigans: 7/8] Allow conversion to hdr formats




commit ceb3b7adc6bc7b26c8fdea5fad4f389c7e638d68
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Sep 8 09:38:34 2021 -0400

    Allow conversion to hdr formats
    
    Add conversion functions that produce
    GDK_MEMORY_R32G32B32A32_PREMULTIPLIED data,
    since we want to allow downloading textures
    in that format. We make use of the new chaining
    abilities here to cut down on the number of
    conversion functions.

 gdk/gdkmemorytexture.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 167 insertions(+), 1 deletion(-)
---
diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c
index 2c67f5686e..28279b52fb 100644
--- a/gdk/gdkmemorytexture.c
+++ b/gdk/gdkmemorytexture.c
@@ -693,11 +693,177 @@ static ConversionFunc converters_to_rgba[GDK_MEMORY_N_FORMATS] =
   convert_float_swizzle_3012
 };
 
+static void
+convert_rgba_to_hdr (guchar       *dest_data,
+                     gsize         dest_stride,
+                     GdkMemoryFormat  dest_format,
+                     const guchar *src_data,
+                     gsize         src_stride,
+                     GdkMemoryFormat  src_format,
+                     gsize         width,
+                     gsize         height)
+{
+  gsize x, y;
+
+  for (y = 0; y < height; y++)
+    {
+      guint16 *src = (guint16 *)src_data;
+      float *dest = (float *)dest_data;
+      for (x = 0; x < width; x++)
+        {
+          dest[4 * (y * width + x) + 0] = src[3 * (y * width + x) + 0] / 255.f;
+          dest[4 * (y * width + x) + 1] = src[3 * (y * width + x) + 1] / 255.f;
+          dest[4 * (y * width + x) + 2] = src[3 * (y * width + x) + 2] / 255.f;
+          dest[4 * (y * width + x) + 3] = src[3 * (y * width + x) + 3] / 255.f;
+        }
+      dest_data += dest_stride;
+      src_data += src_stride;
+    }
+}
+
+static void
+convert_8bit_to_hdr (guchar       *dest_data,
+                     gsize         dest_stride,
+                     GdkMemoryFormat  dest_format,
+                     const guchar *src_data,
+                     gsize         src_stride,
+                     GdkMemoryFormat  src_format,
+                     gsize         width,
+                     gsize         height)
+{
+  guchar *data;
+
+  /* TODO: this could perhaps be done in-place */
+  data = g_malloc (width * height * 4);
+
+  gdk_memory_convert (data, 4 * width, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+                      src_data, src_stride, src_format,
+                      width, height);
+  convert_rgba_to_hdr (dest_data, dest_stride, dest_format,
+                       data, 4 * width, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+                       width, height);
+
+  g_free (data);
+}
+
+static void
+convert_16bit_to_hdr (guchar       *dest_data,
+                      gsize         dest_stride,
+                      GdkMemoryFormat  dest_format,
+                      const guchar *src_data,
+                      gsize         src_stride,
+                      GdkMemoryFormat  src_format,
+                      gsize         width,
+                      gsize         height)
+{
+  gsize x, y;
+
+  for (y = 0; y < height; y++)
+    {
+      guint16 *src = (guint16 *)src_data;
+      float *dest = (float *)dest_data;
+      for (x = 0; x < width; x++)
+        {
+          dest[4 * (y * width + x) + 0] = src[3 * (y * width + x) + 0] / 65535.f;
+          dest[4 * (y * width + x) + 1] = src[3 * (y * width + x) + 1] / 65535.f;
+          dest[4 * (y * width + x) + 2] = src[3 * (y * width + x) + 2] / 65535.f;
+          dest[4 * (y * width + x) + 3] = src[3 * (y * width + x) + 3] / 65535.f;
+        }
+      dest_data += dest_stride;
+      src_data += src_stride;
+    }
+}
+
+static void
+convert_fp16_to_hdr (guchar       *dest_data,
+                     gsize         dest_stride,
+                     GdkMemoryFormat  dest_format,
+                     const guchar *src_data,
+                     gsize         src_stride,
+                     GdkMemoryFormat  src_format,
+                     gsize         width,
+                     gsize         height)
+{
+  gsize x, y;
+  int src_bpp;
+
+  if (src_format == GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED)
+    src_bpp = 4;
+  else
+    src_bpp = 3;
+
+  for (y = 0; y < height; y++)
+    {
+      guint16 *src = (guint16 *)src_data;
+      float *dest = (float *)dest_data;
+      for (x = 0; x < width; x++)
+        {
+          guint16 h[4];
+
+          h[0] = src[src_bpp * (y * width + x)];
+          h[1] = src[src_bpp * (y * width + x) + 1];
+          h[2] = src[src_bpp * (y * width + x) + 2];
+          if (src_bpp == 4)
+            h[3] = src[src_bpp * (y * width + x) + 3];
+          else
+            h[3] = FP16_ONE;
+          half_to_float4 (h, &dest[4 * (y * width + x)]);
+        }
+      dest_data += dest_stride;
+      src_data += src_stride;
+    }
+}
+
+static void
+convert_float_to_hdr (guchar       *dest_data,
+                      gsize         dest_stride,
+                      GdkMemoryFormat  dest_format,
+                      const guchar *src_data,
+                      gsize         src_stride,
+                      GdkMemoryFormat  src_format,
+                      gsize         width,
+                      gsize         height)
+{
+  gsize x, y;
+
+  for (y = 0; y < height; y++)
+    {
+      float *src = (float *)src_data;
+      float *dest = (float *)dest_data;
+      for (x = 0; x < width; x++)
+        {
+          dest[4 * (y * width + x) + 0] = src[3 * (y * width + x) + 0];
+          dest[4 * (y * width + x) + 1] = src[3 * (y * width + x) + 1];
+          dest[4 * (y * width + x) + 2] = src[3 * (y * width + x) + 2];
+          dest[4 * (y * width + x) + 3] = 1.0;
+        }
+      dest_data += dest_stride;
+      src_data += src_stride;
+    }
+}
+
+static ConversionFunc converters_to_hdr[GDK_MEMORY_N_FORMATS] =
+{
+  convert_8bit_to_hdr,
+  convert_8bit_to_hdr,
+  convert_rgba_to_hdr,
+  convert_8bit_to_hdr,
+  convert_8bit_to_hdr,
+  convert_8bit_to_hdr,
+  convert_8bit_to_hdr,
+  convert_8bit_to_hdr,
+  convert_8bit_to_hdr,
+  convert_16bit_to_hdr,
+  convert_fp16_to_hdr,
+  convert_fp16_to_hdr,
+  convert_float_to_hdr,
+  convert_memcpy
+};
 static ConversionFunc* converters[GDK_MEMORY_N_FORMATS] = {
   converters_to_bgra, converters_to_argb, converters_to_rgba,
   NULL, NULL, NULL, NULL, NULL, NULL,
   NULL, NULL, NULL, NULL,
-  NULL
+  converters_to_hdr
 };
 
 void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]