[gtk/wip/otte/memoryformat: 1/7] Add memory formats used by libpng




commit 1e7fb52b21236ef3c3404c15b642de28a723be60
Author: Benjamin Otte <otte redhat com>
Date:   Sun Sep 26 16:47:34 2021 +0200

    Add memory formats used by libpng
    
    Add unpremultiplied high-depth formats. They are used in the real world,
    so let's support them.

 gdk/gdkmemoryformat.c         | 30 ++++++++++++++++++++++++++++++
 gdk/gdkmemorytexture.h        |  9 +++++++++
 gdk/loaders/gdkpng.c          | 32 ++++----------------------------
 testsuite/gdk/memorytexture.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 85 insertions(+), 28 deletions(-)
---
diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c
index 6c746f75df..940e9cea17 100644
--- a/gdk/gdkmemoryformat.c
+++ b/gdk/gdkmemoryformat.c
@@ -308,6 +308,16 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     r16g16b16a16_to_float,
     r16g16b16a16_from_float,
   },
+  [GDK_MEMORY_R16G16B16A16] = {
+    GDK_MEMORY_ALPHA_STRAIGHT,
+    8,
+    G_ALIGNOF (guint16),
+    TRUE,
+    TRUE,
+    { GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
+    r16g16b16a16_to_float,
+    r16g16b16a16_from_float,
+  },
   [GDK_MEMORY_R16G16B16_FLOAT] = {
     GDK_MEMORY_ALPHA_OPAQUE,
     6,
@@ -328,6 +338,16 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     r16g16b16a16_float_to_float,
     r16g16b16a16_float_from_float,
   },
+  [GDK_MEMORY_R16G16B16A16_FLOAT] = {
+    GDK_MEMORY_ALPHA_STRAIGHT,
+    8,
+    G_ALIGNOF (guint16),
+    TRUE,
+    TRUE,
+    { GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
+    r16g16b16a16_float_to_float,
+    r16g16b16a16_float_from_float,
+  },
   [GDK_MEMORY_R32G32B32_FLOAT] = {
     GDK_MEMORY_ALPHA_OPAQUE,
     12,
@@ -347,6 +367,16 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
     { GL_RGBA32F, GL_RGBA, GL_FLOAT },
     r32g32b32a32_float_to_float,
     r32g32b32a32_float_from_float,
+  },
+  [GDK_MEMORY_R32G32B32A32_FLOAT] = {
+    GDK_MEMORY_ALPHA_STRAIGHT,
+    16,
+    G_ALIGNOF (float),
+    TRUE,
+    TRUE,
+    { GL_RGBA32F, GL_RGBA, GL_FLOAT },
+    r32g32b32a32_float_to_float,
+    r32g32b32a32_float_from_float,
   }
 };
 
diff --git a/gdk/gdkmemorytexture.h b/gdk/gdkmemorytexture.h
index 114922153e..0c574d7add 100644
--- a/gdk/gdkmemorytexture.h
+++ b/gdk/gdkmemorytexture.h
@@ -46,16 +46,22 @@ G_BEGIN_DECLS
  * @GDK_MEMORY_R16G16B16A16_PREMULTIPLIED: 4 guint16 values; for red, green,
  *   blue, alpha. The color values are premultiplied with the alpha value.
  *   Since 4.6
+ * @GDK_MEMORY_R16G16B16A16: 4 guint16 values; for red, green, blue, alpha.
+ *   Since 4.6
  * @GDK_MEMORY_R16G16B16_FLOAT: 3 half-float values; for red, green, blue.
  *   The data is opaque. Since 4.6
  * @GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED: 4 half-float values; for
  *   red, green, blue and alpha. The color values are premultiplied with
  *   the alpha value. Since 4.6
+ * @GDK_MEMORY_R16G16B16A16_FLOAT: 4 half-float values; for red, green,
+ *   blue and alpha. Since 4.6
  * @GDK_MEMORY_B32G32R32_FLOAT: 3 float values; for blue, green, red.
  *   The data is opaque. Since 4.6
  * @GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED: 4 float values; for
  *   red, green, blue and alpha. The color values are premultiplied with
  *   the alpha value. Since 4.6
+ * @GDK_MEMORY_R32G32B32A32_FLOAT: 4 float values; for red, green, blue and
+ *   alpha. Since 4.6
  * @GDK_MEMORY_N_FORMATS: The number of formats. This value will change as
  *   more formats get added, so do not rely on its concrete integer.
  *
@@ -83,10 +89,13 @@ typedef enum {
   GDK_MEMORY_B8G8R8,
   GDK_MEMORY_R16G16B16,
   GDK_MEMORY_R16G16B16A16_PREMULTIPLIED,
+  GDK_MEMORY_R16G16B16A16,
   GDK_MEMORY_R16G16B16_FLOAT,
   GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED,
+  GDK_MEMORY_R16G16B16A16_FLOAT,
   GDK_MEMORY_R32G32B32_FLOAT,
   GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED,
+  GDK_MEMORY_R32G32B32A32_FLOAT,
 
   GDK_MEMORY_N_FORMATS
 } GdkMemoryFormat;
diff --git a/gdk/loaders/gdkpng.c b/gdk/loaders/gdkpng.c
index 2103ae68f9..526c6fa50f 100644
--- a/gdk/loaders/gdkpng.c
+++ b/gdk/loaders/gdkpng.c
@@ -206,30 +206,6 @@ unpremultiply_float_to_16bit (guchar *data,
     }
 }
 
-static void
-premultiply_16bit (guchar *data,
-                   int     width,
-                   int     height,
-                   int     stride)
-{
-  gsize x, y;
-  guint16 *src;
-
-  for (y = 0; y < height; y++)
-    {
-      src = (guint16 *)data;
-      for (x = 0; x < width; x++)
-        {
-          float alpha = src[x * 4 + 3] / 65535.f;
-          src[x * 4    ] = (guint16) CLAMP (src[x * 4    ] * alpha, 0.f, 65535.f);
-          src[x * 4 + 1] = (guint16) CLAMP (src[x * 4 + 1] * alpha, 0.f, 65535.f);
-          src[x * 4 + 2] = (guint16) CLAMP (src[x * 4 + 2] * alpha, 0.f, 65535.f);
-        }
-
-      data += stride;
-    }
-}
-
 /* }}} */
 /* {{{ Public API */ 
 
@@ -333,7 +309,7 @@ gdk_load_png (GBytes  *bytes,
         }
       else
         {
-          format = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
+          format = GDK_MEMORY_R16G16B16A16;
         }
       break;
     case PNG_COLOR_TYPE_RGB:
@@ -383,9 +359,6 @@ gdk_load_png (GBytes  *bytes,
   png_read_image (png, row_pointers);
   png_read_end (png, info);
 
-  if (format == GDK_MEMORY_R16G16B16A16_PREMULTIPLIED)
-    premultiply_16bit (buffer, width, height, stride);
-
   out_bytes = g_bytes_new_take (buffer, height * stride);
   texture = gdk_memory_texture_new (width, height, format, out_bytes, stride);
   g_bytes_unref (out_bytes);
@@ -445,10 +418,13 @@ gdk_save_png (GdkTexture *texture)
       break;
 
     case GDK_MEMORY_R16G16B16:
+    case GDK_MEMORY_R16G16B16A16:
     case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
     case GDK_MEMORY_R16G16B16_FLOAT:
+    case GDK_MEMORY_R16G16B16A16_FLOAT:
     case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
     case GDK_MEMORY_R32G32B32_FLOAT:
+    case GDK_MEMORY_R32G32B32A32_FLOAT:
     case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
       data = g_malloc_n (width * 16, height);
       gdk_texture_download_float (mtexture, (float *)data, width * 4);
diff --git a/testsuite/gdk/memorytexture.c b/testsuite/gdk/memorytexture.c
index 60b88465c1..806f7f1d0a 100644
--- a/testsuite/gdk/memorytexture.c
+++ b/testsuite/gdk/memorytexture.c
@@ -49,14 +49,17 @@ gdk_memory_format_precsion (GdkMemoryFormat format)
 
     case GDK_MEMORY_R16G16B16:
     case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
+    case GDK_MEMORY_R16G16B16A16:
       return 1/65536.f;
 
     case GDK_MEMORY_R16G16B16_FLOAT:
     case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
+    case GDK_MEMORY_R16G16B16A16_FLOAT:
       return 0.0009765625f;
 
     case GDK_MEMORY_R32G32B32_FLOAT:
     case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
+    case GDK_MEMORY_R32G32B32A32_FLOAT:
       return FLT_EPSILON;
 
     case GDK_MEMORY_N_FORMATS:
@@ -89,13 +92,16 @@ gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
       return 6;
 
     case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
+    case GDK_MEMORY_R16G16B16A16:
     case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
+    case GDK_MEMORY_R16G16B16A16_FLOAT:
       return 8;
 
     case GDK_MEMORY_R32G32B32_FLOAT:
       return 12;
 
     case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
+    case GDK_MEMORY_R32G32B32A32_FLOAT:
       return 16;
 
     case GDK_MEMORY_N_FORMATS:
@@ -125,8 +131,11 @@ gdk_memory_format_has_alpha (GdkMemoryFormat format)
     case GDK_MEMORY_R8G8B8A8:
     case GDK_MEMORY_A8B8G8R8:
     case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
+    case GDK_MEMORY_R16G16B16A16:
     case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
+    case GDK_MEMORY_R16G16B16A16_FLOAT:
     case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
+    case GDK_MEMORY_R32G32B32A32_FLOAT:
       return TRUE;
 
     case GDK_MEMORY_N_FORMATS:
@@ -296,6 +305,17 @@ texture_builder_set_pixel (TextureBuilder  *builder,
         memcpy (data, pixels, 4 * sizeof (guint16));
       }
       break;
+    case GDK_MEMORY_R16G16B16A16:
+      {
+        guint16 pixels[4] = {
+          CLAMP (color->red * 65536.f, 0, 65535.f),
+          CLAMP (color->green * 65536.f, 0, 65535.f),
+          CLAMP (color->blue * 65536.f, 0, 65535.f),
+          CLAMP (color->alpha * 65536.f, 0, 65535.f),
+        };
+        memcpy (data, pixels, 4 * sizeof (guint16));
+      }
+      break;
     case GDK_MEMORY_R16G16B16_FLOAT:
       {
         guint16 pixels[3] = {
@@ -317,6 +337,17 @@ texture_builder_set_pixel (TextureBuilder  *builder,
         memcpy (data, pixels, 4 * sizeof (guint16));
       }
       break;
+    case GDK_MEMORY_R16G16B16A16_FLOAT:
+      {
+        guint16 pixels[4] = {
+          float_to_half (color->red),
+          float_to_half (color->green),
+          float_to_half (color->blue),
+          float_to_half (color->alpha)
+        };
+        memcpy (data, pixels, 4 * sizeof (guint16));
+      }
+      break;
     case GDK_MEMORY_R32G32B32_FLOAT:
       {
         float pixels[3] = {
@@ -338,6 +369,17 @@ texture_builder_set_pixel (TextureBuilder  *builder,
         memcpy (data, pixels, 4 * sizeof (float));
       }
       break;
+    case GDK_MEMORY_R32G32B32A32_FLOAT:
+      {
+        float pixels[4] = {
+          color->red,
+          color->green,
+          color->blue,
+          color->alpha
+        };
+        memcpy (data, pixels, 4 * sizeof (float));
+      }
+      break;
     case GDK_MEMORY_N_FORMATS:
     default:
       g_assert_not_reached ();


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