We need them for mask-only textures.
For tiffs, we convert the formats to RGBA (the idea that tiff can save
everything needs to be buried I guess) as tiffs can't do alpha-only.
GDK_MEMORY_G16 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_A8 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_A16 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
+ GDK_MEMORY_A16_FLOAT GDK_AVAILABLE_ENUMERATOR_IN_4_12,
+ GDK_MEMORY_A32_FLOAT GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_N_FORMATS
} GdkMemoryFormat;
float_to_half (src, (guint16 *) dest, 4 * n);
}
+static void
+a16_float_to_float (float *dest,
+ const guchar *src_data,
+ gsize n)
+{
+ const guint16 *src = (const guint16 *) src_data;
+ for (gsize i = 0; i < n; i++)
+ {
+ half_to_float (src, dest, 1);
+ dest[1] = dest[0];
+ dest[2] = dest[0];
+ dest[3] = dest[0];
+ src++;
+ dest += 4;
+ }
+}
+
+static void
+a16_float_from_float (guchar *dest_data,
+ const float *src,
+ gsize n)
+{
+ guint16 *dest = (guint16 *) dest_data;
+ for (gsize i = 0; i < n; i++)
+ {
+ float_to_half (&src[3], dest, 1);
+ dest ++;
+ src += 4;
+ }
+}
+
static void
r32g32b32_float_to_float (float *dest,
const guchar *src_data,
memcpy (dest, src, sizeof (float) * n * 4);
}
+static void
+a32_float_to_float (float *dest,
+ const guchar *src_data,
+ gsize n)
+{
+ const float *src = (const float *) src_data;
+ for (gsize i = 0; i < n; i++)
+ {
+ dest[0] = src[0];
+ dest[1] = src[0];
+ dest[2] = src[0];
+ dest[3] = src[0];
+ src++;
+ dest += 4;
+ }
+}
+
+static void
+a32_float_from_float (guchar *dest_data,
+ const float *src,
+ gsize n)
+{
+ float *dest = (float *) dest_data;
+ for (gsize i = 0; i < n; i++)
+ {
+ dest[0] = src[3];
+ dest ++;
+ src += 4;
+ }
+}
+
#define PREMULTIPLY_FUNC(name, R1, G1, B1, A1, R2, G2, B2, A2) \
static void \
name (guchar *dest, \
{ GL_R16, GL_RED, GL_UNSIGNED_SHORT, { GL_ONE, GL_ONE, GL_ONE, GL_RED } },
a16_to_float,
a16_from_float,
+ },
+ [GDK_MEMORY_A16_FLOAT] = {
+ GDK_MEMORY_ALPHA_PREMULTIPLIED,
+ 2,
+ G_ALIGNOF (guint16),
+ GDK_MEMORY_FLOAT16,
+ { 0, 0, 3, 0 },
+ { GL_R16F, GL_RED, GL_HALF_FLOAT, { GL_RED, GL_RED, GL_RED, GL_RED } },
+ a16_float_to_float,
+ a16_float_from_float,
+ },
+ [GDK_MEMORY_A32_FLOAT] = {
+ GDK_MEMORY_ALPHA_PREMULTIPLIED,
+ 4,
+ G_ALIGNOF (float),
+ GDK_MEMORY_FLOAT32,
+ { 0, 0, 3, 0 },
+ { GL_R32F, GL_RED, GL_FLOAT, { GL_RED, GL_RED, GL_RED, GL_RED } },
+ a32_float_to_float,
+ a32_float_from_float,
}
};
case GDK_MEMORY_G16A16_PREMULTIPLIED:
case GDK_MEMORY_G16A16:
case GDK_MEMORY_A16:
+ case GDK_MEMORY_A16_FLOAT:
+ case GDK_MEMORY_A32_FLOAT:
format = GDK_MEMORY_G16A16;
png_format = PNG_COLOR_TYPE_GRAY_ALPHA;
depth = 16;
[GDK_MEMORY_G16] = { GDK_MEMORY_G16, 16, 1, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_MINISBLACK },
[GDK_MEMORY_A8] = { GDK_MEMORY_G8A8, 8, 2, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
[GDK_MEMORY_A16] = { GDK_MEMORY_G16A16, 16, 2, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_MINISBLACK },
+ [GDK_MEMORY_A16_FLOAT] = { GDK_MEMORY_R16G16B16A16_FLOAT, 16, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
+ [GDK_MEMORY_A32_FLOAT] = { GDK_MEMORY_R32G32B32A32_FLOAT, 32, 4, SAMPLEFORMAT_IEEEFP, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
};
/* if this fails, somebody forgot to add formats above */
case GDK_MEMORY_R16G16B16_FLOAT:
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16_FLOAT:
+ case GDK_MEMORY_A16_FLOAT:
case GDK_MEMORY_R32G32B32_FLOAT:
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_R32G32B32A32_FLOAT:
+ case GDK_MEMORY_A32_FLOAT:
bytes = gdk_texture_save_to_tiff_bytes (texture);
g_string_append (p->str, "url(\"data:image/tiff;base64,");
break;
return info;
}
+ case GDK_MEMORY_A16_FLOAT:
+ {
+ static const GskMemoryFormatInfo info[] = {
+ { VK_FORMAT_R16_SFLOAT, SWIZZLE (R, R, R, R), 0 },
+ { VK_FORMAT_UNDEFINED }
+ };
+ return info;
+ }
+
+ case GDK_MEMORY_A32_FLOAT:
+ {
+ static const GskMemoryFormatInfo info[] = {
+ { VK_FORMAT_R32_SFLOAT, SWIZZLE (R, R, R, R), 0 },
+ { VK_FORMAT_UNDEFINED }
+ };
+ return info;
+ }
+
case GDK_MEMORY_N_FORMATS:
default:
g_assert_not_reached ();
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_A16:
return GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
+ case GDK_MEMORY_A16_FLOAT:
+ return GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
+ case GDK_MEMORY_A32_FLOAT:
+ return GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
case GDK_MEMORY_N_FORMATS:
default:
case GDK_MEMORY_G8A8:
case GDK_MEMORY_G16:
case GDK_MEMORY_A16:
+ case GDK_MEMORY_A16_FLOAT:
return 2;
case GDK_MEMORY_R8G8B8:
case GDK_MEMORY_A8B8G8R8:
case GDK_MEMORY_G16A16_PREMULTIPLIED:
case GDK_MEMORY_G16A16:
+ case GDK_MEMORY_A32_FLOAT:
return 4;
case GDK_MEMORY_R16G16B16:
case GDK_MEMORY_R16G16B16_FLOAT:
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16_FLOAT:
+ case GDK_MEMORY_A16_FLOAT:
return CHANNEL_FLOAT_16;
case GDK_MEMORY_R32G32B32_FLOAT:
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_R32G32B32A32_FLOAT:
+ case GDK_MEMORY_A32_FLOAT:
return CHANNEL_FLOAT_32;
case GDK_MEMORY_N_FORMATS:
case GDK_MEMORY_A8:
case GDK_MEMORY_A16:
+ case GDK_MEMORY_A16_FLOAT:
+ case GDK_MEMORY_A32_FLOAT:
return 0;
case GDK_MEMORY_N_FORMATS:
case GDK_MEMORY_G16A16:
case GDK_MEMORY_A8:
case GDK_MEMORY_A16:
+ case GDK_MEMORY_A16_FLOAT:
+ case GDK_MEMORY_A32_FLOAT:
return TRUE;
case GDK_MEMORY_N_FORMATS:
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_G8A8_PREMULTIPLIED:
case GDK_MEMORY_G16A16_PREMULTIPLIED:
+ case GDK_MEMORY_A16_FLOAT:
+ case GDK_MEMORY_A32_FLOAT:
return TRUE;
case GDK_MEMORY_R8G8B8:
case GDK_MEMORY_G16:
case GDK_MEMORY_G16A16:
case GDK_MEMORY_A16:
+ case GDK_MEMORY_A16_FLOAT:
+ case GDK_MEMORY_A32_FLOAT:
return TRUE;
case GDK_MEMORY_N_FORMATS:
case GDK_MEMORY_R16G16B16_FLOAT:
case GDK_MEMORY_R16G16B16A16_FLOAT:
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
+ case GDK_MEMORY_A16_FLOAT:
{
guint i;
for (i = 0; i < gdk_memory_format_bytes_per_pixel (format) / sizeof (guint16); i++)
case GDK_MEMORY_R32G32B32_FLOAT:
case GDK_MEMORY_R32G32B32A32_FLOAT:
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
+ case GDK_MEMORY_A32_FLOAT:
{
const float *f1 = (const float *) pixel1;
const float *f2 = (const float *) pixel2;
memcpy (data, &pixel, sizeof (guint16));
}
break;
+ case GDK_MEMORY_A16_FLOAT:
+ {
+ guint16 pixel = float_to_half (color->alpha);
+ memcpy (data, &pixel, sizeof (guint16));
+ }
+ break;
+ case GDK_MEMORY_A32_FLOAT:
+ {
+ memcpy (data, &color->alpha, sizeof (float));
+ }
+ break;
case GDK_MEMORY_N_FORMATS:
default:
g_assert_not_reached ();