base: allow swizzling WebP Lossless to gray
diff --git a/internal/cgen/base/pixconv-submodule-regular.c b/internal/cgen/base/pixconv-submodule-regular.c index f8b5891..87dc56d 100644 --- a/internal/cgen/base/pixconv-submodule-regular.c +++ b/internal/cgen/base/pixconv-submodule-regular.c
@@ -4681,6 +4681,87 @@ // -------- static uint64_t // +wuffs_private_impl__swizzle_y__bgra_nonpremul__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t src_len4 = src_len / 4; + size_t len = (dst_len < src_len4) ? dst_len : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; + + while (n >= 1) { + uint32_t s0 = + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray(s0); + + s += 1 * 4; + d += 1 * 1; + n -= 1; + } + + return len; +} + +static uint64_t // +wuffs_private_impl__swizzle_y__bgra_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t src_len4 = src_len / 4; + size_t len = (dst_len < src_len4) ? dst_len : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; + + while (n >= 1) { + uint32_t d0 = 0xFF000000 | (0x00010101 * ((uint32_t)(d[0]))); + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); + d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray( + wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0)); + + s += 1 * 4; + d += 1 * 1; + n -= 1; + } + + return len; +} + +static uint64_t // +wuffs_private_impl__swizzle_y__bgrx(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t src_len4 = src_len / 4; + size_t len = (dst_len < src_len4) ? dst_len : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; + + while (n >= 1) { + uint32_t s0 = + 0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); + d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray(s0); + + s += 1 * 4; + d += 1 * 1; + n -= 1; + } + + return len; +} + +static uint64_t // wuffs_private_impl__swizzle_y__y_16be(uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, @@ -5332,6 +5413,15 @@ wuffs_base__slice_u8 src_palette, wuffs_base__pixel_blend blend) { switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__Y: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_y__bgra_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_y__bgra_nonpremul__src_over; + } + return NULL; + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: switch (blend) { case WUFFS_BASE__PIXEL_BLEND__SRC: @@ -5611,6 +5701,9 @@ wuffs_base__slice_u8 src_palette, wuffs_base__pixel_blend blend) { switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__Y: + return wuffs_private_impl__swizzle_y__bgrx; + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: return wuffs_private_impl__swizzle_bgr_565__bgrx;
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c index af4b9b1..da96b1d 100644 --- a/release/c/wuffs-unsupported-snapshot.c +++ b/release/c/wuffs-unsupported-snapshot.c
@@ -26302,6 +26302,87 @@ // -------- static uint64_t // +wuffs_private_impl__swizzle_y__bgra_nonpremul__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t src_len4 = src_len / 4; + size_t len = (dst_len < src_len4) ? dst_len : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; + + while (n >= 1) { + uint32_t s0 = + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray(s0); + + s += 1 * 4; + d += 1 * 1; + n -= 1; + } + + return len; +} + +static uint64_t // +wuffs_private_impl__swizzle_y__bgra_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t src_len4 = src_len / 4; + size_t len = (dst_len < src_len4) ? dst_len : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; + + while (n >= 1) { + uint32_t d0 = 0xFF000000 | (0x00010101 * ((uint32_t)(d[0]))); + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); + d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray( + wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0)); + + s += 1 * 4; + d += 1 * 1; + n -= 1; + } + + return len; +} + +static uint64_t // +wuffs_private_impl__swizzle_y__bgrx(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t src_len4 = src_len / 4; + size_t len = (dst_len < src_len4) ? dst_len : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; + + while (n >= 1) { + uint32_t s0 = + 0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); + d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray(s0); + + s += 1 * 4; + d += 1 * 1; + n -= 1; + } + + return len; +} + +static uint64_t // wuffs_private_impl__swizzle_y__y_16be(uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, @@ -26953,6 +27034,15 @@ wuffs_base__slice_u8 src_palette, wuffs_base__pixel_blend blend) { switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__Y: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_y__bgra_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_y__bgra_nonpremul__src_over; + } + return NULL; + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: switch (blend) { case WUFFS_BASE__PIXEL_BLEND__SRC: @@ -27232,6 +27322,9 @@ wuffs_base__slice_u8 src_palette, wuffs_base__pixel_blend blend) { switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__Y: + return wuffs_private_impl__swizzle_y__bgrx; + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: return wuffs_private_impl__swizzle_bgr_565__bgrx;
diff --git a/test/c/std/wbmp.c b/test/c/std/wbmp.c index 0e93f14..1570b6e 100644 --- a/test/c/std/wbmp.c +++ b/test/c/std/wbmp.c
@@ -374,6 +374,10 @@ // When updating this list, also consider updating the pixel formats that // fuzz/c/std/pixel_swizzler_fuzzer.c exercises and those that // wuffs_aux::DecodeImageCallbacks::SelectPixfmt accepts. + // + // SelectPixfmt excludes WUFFS_BASE__PIXEL_FORMAT__Y, even though we test + // it here, since it doesn't support every source pixel format in the + // srcs array. See "dst WUFFS_BASE__PIXEL_FORMAT__Y allow-list" below. { .color = 0xFF000010, .pixfmt_repr = WUFFS_BASE__PIXEL_FORMAT__BGR_565, @@ -406,6 +410,10 @@ .color = 0x33002233, .pixfmt_repr = WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL, }, + { + .color = 0xFF999999, + .pixfmt_repr = WUFFS_BASE__PIXEL_FORMAT__Y, + }, }; const wuffs_base__pixel_blend blends[] = { @@ -443,6 +451,19 @@ } for (size_t d = 0; d < WUFFS_TESTLIB_ARRAY_SIZE(dsts); d++) { + // See "dst WUFFS_BASE__PIXEL_FORMAT__Y allow-list" above. + if (dsts[d].pixfmt_repr == WUFFS_BASE__PIXEL_FORMAT__Y) { + switch (srcs[s].pixfmt_repr) { + case WUFFS_BASE__PIXEL_FORMAT__Y: + case WUFFS_BASE__PIXEL_FORMAT__Y_16BE: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + break; + default: + continue; + } + } + // Allocate the dst_pixbuf. wuffs_base__pixel_config dst_pixcfg = ((wuffs_base__pixel_config){}); wuffs_base__pixel_config__set(&dst_pixcfg, dsts[d].pixfmt_repr, @@ -502,6 +523,13 @@ if (dst_transparency == WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__OPAQUE) { want_dst_pixel |= 0xFF000000; } + if (dsts[d].pixfmt_repr == WUFFS_BASE__PIXEL_FORMAT__Y) { + want_dst_pixel = + 0xFF000000 | + (0x00010101 * + wuffs_base__color_u32_argb_premul__as__color_u8_gray( + want_dst_pixel)); + } wuffs_base__color_u32_argb_premul have_dst_pixel = wuffs_base__pixel_buffer__color_u32_at(&dst_pixbuf, width / 2, height / 2);