Employ libwebp's alpha premultiplication

It seems to perform roughly equally in optimized builds.
This commit is contained in:
Přemysl Eric Janouch 2021-12-15 03:24:05 +01:00
parent ea2d159773
commit 7297c40f93
Signed by: p
GPG Key ID: A0420B94F92B9493

View File

@ -162,6 +162,9 @@ try_append_page(cairo_surface_t *surface, cairo_surface_t **result,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// From libwebp, verified to exactly match [x * a / 255].
#define PREMULTIPLY8(a, x) (((uint32_t) (x) * (uint32_t) (a) * 32897U) >> 23)
static bool static bool
pull_passthrough(const wuffs_base__more_information *minfo, pull_passthrough(const wuffs_base__more_information *minfo,
wuffs_base__io_buffer *src, wuffs_base__io_buffer *dst, GError **error) wuffs_base__io_buffer *src, wuffs_base__io_buffer *dst, GError **error)
@ -1375,12 +1378,11 @@ load_libheif_image(struct heif_image_handle *handle, GError **error)
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
uint32_t *dstp = (uint32_t *) (dst + dst_stride * y); uint32_t *dstp = (uint32_t *) (dst + dst_stride * y);
for (int x = 0; x < w; x++) { for (int x = 0; x < w; x++) {
uint32_t pixel = dstp[x], a = pixel >> 24; uint32_t argb = dstp[x], a = argb >> 24;
uint8_t r = pixel >> 16;
uint8_t g = pixel >> 8;
uint8_t b = pixel;
dstp[x] = a << 24 | dstp[x] = a << 24 |
(r * a / 255) << 16 | (g * a / 255) << 8 | (b * a / 255); PREMULTIPLY8(a, 0xFF & (argb >> 16)) << 16 |
PREMULTIPLY8(a, 0xFF & (argb >> 8)) << 8 |
PREMULTIPLY8(a, 0xFF & argb);
} }
} }
} }
@ -2361,9 +2363,9 @@ read_spng_thumbnail(
for (size_t i = size / sizeof *data; i--; ) { for (size_t i = size / sizeof *data; i--; ) {
const uint8_t *unit = (const uint8_t *) &data[i]; const uint8_t *unit = (const uint8_t *) &data[i];
uint32_t a = unit[3], uint32_t a = unit[3],
b = unit[2] * a / 255, b = PREMULTIPLY8(a, unit[2]),
g = unit[1] * a / 255, g = PREMULTIPLY8(a, unit[1]),
r = unit[0] * a / 255; r = PREMULTIPLY8(a, unit[0]);
data[i] = a << 24 | r << 16 | g << 8 | b; data[i] = a << 24 | r << 16 | g << 8 | b;
} }
} else { } else {