Add limited_swizzle_u32_interleaved_from_reader
diff --git a/internal/cgen/base/image-private.h b/internal/cgen/base/image-private.h
index 2a4808f..7c12b22 100644
--- a/internal/cgen/base/image-private.h
+++ b/internal/cgen/base/image-private.h
@@ -17,6 +17,15 @@
// ---------------- Images
WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
+ const wuffs_base__pixel_swizzler* p,
+ uint32_t up_to_num_pixels,
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ const uint8_t** ptr_iop_r,
+ const uint8_t* io2_r);
+
+WUFFS_BASE__MAYBE_STATIC uint64_t //
wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
const wuffs_base__pixel_swizzler* p,
wuffs_base__slice_u8 dst,
diff --git a/internal/cgen/base/pixconv-submodule.c b/internal/cgen/base/pixconv-submodule.c
index 2089e78..39be01d 100644
--- a/internal/cgen/base/pixconv-submodule.c
+++ b/internal/cgen/base/pixconv-submodule.c
@@ -2114,6 +2114,28 @@
}
WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
+ const wuffs_base__pixel_swizzler* p,
+ uint32_t up_to_num_pixels,
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ const uint8_t** ptr_iop_r,
+ const uint8_t* io2_r) {
+ if (p && p->private_impl.func) {
+ const uint8_t* iop_r = *ptr_iop_r;
+ uint64_t src_len = wuffs_base__u64__min(
+ ((uint64_t)up_to_num_pixels) *
+ ((uint64_t)p->private_impl.src_pixfmt_bytes_per_pixel),
+ ((uint64_t)(io2_r - iop_r)));
+ uint64_t n = (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
+ dst_palette.len, iop_r, src_len);
+ *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
+ return n;
+ }
+ return 0;
+}
+
+WUFFS_BASE__MAYBE_STATIC uint64_t //
wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
const wuffs_base__pixel_swizzler* p,
wuffs_base__slice_u8 dst,
@@ -2122,9 +2144,9 @@
const uint8_t* io2_r) {
if (p && p->private_impl.func) {
const uint8_t* iop_r = *ptr_iop_r;
+ uint64_t src_len = ((uint64_t)(io2_r - iop_r));
uint64_t n = (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
- dst_palette.len, iop_r,
- (size_t)(io2_r - iop_r));
+ dst_palette.len, iop_r, src_len);
*ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
return n;
}
diff --git a/internal/cgen/builtin.go b/internal/cgen/builtin.go
index 1163cd0..6e24158 100644
--- a/internal/cgen/builtin.go
+++ b/internal/cgen/builtin.go
@@ -103,8 +103,14 @@
return g.writeBuiltinIOWriter(b, recv, method.Ident(), n.Args(), depth)
case t.IDPixelSwizzler:
switch method.Ident() {
- case t.IDSwizzleInterleavedFromReader:
- b.writes("wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(\n&")
+ case t.IDLimitedSwizzleU32InterleavedFromReader, t.IDSwizzleInterleavedFromReader:
+ b.writes("wuffs_base__pixel_swizzler__")
+ if method.Ident() == t.IDLimitedSwizzleU32InterleavedFromReader {
+ b.writes("limited_swizzle_u32_interleaved_from_reader")
+ } else {
+ b.writes("swizzle_interleaved_from_reader")
+ }
+ b.writes("(\n&")
if err := g.writeExpr(b, recv, depth); err != nil {
return err
}
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index 3084730..c77b9c1 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -109,7 +109,7 @@
""
const BaseImagePrivateH = "" +
- "// ---------------- Images\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n const uint8_t** ptr_iop_r,\n const uint8_t* io2_r);\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n uint64_t num_pixels);\n\n" +
+ "// ---------------- Images\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(\n const wuffs_base__pixel_swizzler* p,\n uint32_t up_to_num_pixels,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n const uint8_t** ptr_iop_r,\n const uint8_t* io2_r);\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n const uint8_t** ptr_iop_r,\n const uint8_t* io2_r);\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n uint64_t num_pixels);\n\n" +
"" +
"// ---------------- Images (Utility)\n\n#define wuffs_base__utility__make_pixel_format wuffs_base__make_pixel_format\n" +
""
@@ -605,8 +605,9 @@
"// --------\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__status //\nwuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,\n wuffs_base__pixel_format dst_pixfmt,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__pixel_format src_pixfmt,\n wuffs_base__slice_u8 src_palette,\n wuffs_base__pixel_blend blend) {\n if (!p) {\n return wuffs_base__make_status(wuffs_base__error__bad_receiver);\n }\n p->private_impl.func = NULL;\n p->private_impl.transparent_black_func = NULL;\n p->private_impl.dst_pixfmt_bytes_per_pixel = 0;\n p->private_impl.src_pixfmt_bytes_per_pixel = 0;\n\n wuffs_base__pixel_swizzler__func func = NULL;\n wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func =\n NULL;\n\n uint32_t dst_pixfmt_bits_per_pixel =\n wuffs_base__pixel_format__bits_per_pixel(&dst_pixfmt);\n if ((dst_pixfmt_bits_per_pixel == " +
"0) ||\n ((dst_pixfmt_bits_per_pixel & 7) != 0)) {\n return wuffs_base__make_status(\n wuffs_base__error__unsupported_pixel_swizzler_option);\n }\n\n uint32_t src_pixfmt_bits_per_pixel =\n wuffs_base__pixel_format__bits_per_pixel(&src_pixfmt);\n if ((src_pixfmt_bits_per_pixel == 0) ||\n ((src_pixfmt_bits_per_pixel & 7) != 0)) {\n return wuffs_base__make_status(\n wuffs_base__error__unsupported_pixel_swizzler_option);\n }\n\n // TODO: support many more formats.\n\n switch (blend) {\n case WUFFS_BASE__PIXEL_BLEND__SRC:\n transparent_black_func =\n wuffs_base__pixel_swizzler__transparent_black_src;\n break;\n\n case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:\n transparent_black_func =\n wuffs_base__pixel_swizzler__transparent_black_src_over;\n break;\n }\n\n switch (src_pixfmt.repr) {\n case WUFFS_BASE__PIXEL_FORMAT__Y:\n func = wuffs_base__pixel_swizzler__prepare__y(p, dst_pixfmt, dst_palette,\n src_palette" +
", blend);\n break;\n\n case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:\n func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(\n p, dst_pixfmt, dst_palette, src_palette, blend);\n break;\n\n case WUFFS_BASE__PIXEL_FORMAT__BGR:\n func = wuffs_base__pixel_swizzler__prepare__bgr(\n p, dst_pixfmt, dst_palette, src_palette, blend);\n break;\n\n case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:\n func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(\n p, dst_pixfmt, dst_palette, src_palette, blend);\n break;\n\n case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:\n func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(\n p, dst_pixfmt, dst_palette, src_palette, blend);\n break;\n\n case WUFFS_BASE__PIXEL_FORMAT__BGRX:\n func = wuffs_base__pixel_swizzler__prepare__bgrx(\n p, dst_pixfmt, dst_palette, src_palette, blend);\n break;\n }\n\n p->private_impl.func = func;\n p->private_impl.transparent_b" +
- "lack_func = transparent_black_func;\n p->private_impl.dst_pixfmt_bytes_per_pixel = dst_pixfmt_bits_per_pixel / 8;\n p->private_impl.src_pixfmt_bytes_per_pixel = src_pixfmt_bits_per_pixel / 8;\n return wuffs_base__make_status(\n func ? NULL : wuffs_base__error__unsupported_pixel_swizzler_option);\n}\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n const uint8_t** ptr_iop_r,\n const uint8_t* io2_r) {\n if (p && p->private_impl.func) {\n const uint8_t* iop_r = *ptr_iop_r;\n uint64_t n = (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,\n dst_palette.len, iop_r,\n (size_t)(io2_r - iop_r));\n *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;\n return n;\n }\n return 0;\n}\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__swizzl" +
- "e_interleaved_from_slice(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src) {\n if (p && p->private_impl.func) {\n return (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,\n dst_palette.len, src.ptr, src.len);\n }\n return 0;\n}\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n uint64_t num_pixels) {\n if (p && p->private_impl.transparent_black_func) {\n return (*p->private_impl.transparent_black_func)(\n dst.ptr, dst.len, dst_palette.ptr, dst_palette.len, num_pixels,\n p->private_impl.dst_pixfmt_bytes_per_pixel);\n }\n return 0;\n}\n" +
+ "lack_func = transparent_black_func;\n p->private_impl.dst_pixfmt_bytes_per_pixel = dst_pixfmt_bits_per_pixel / 8;\n p->private_impl.src_pixfmt_bytes_per_pixel = src_pixfmt_bits_per_pixel / 8;\n return wuffs_base__make_status(\n func ? NULL : wuffs_base__error__unsupported_pixel_swizzler_option);\n}\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(\n const wuffs_base__pixel_swizzler* p,\n uint32_t up_to_num_pixels,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n const uint8_t** ptr_iop_r,\n const uint8_t* io2_r) {\n if (p && p->private_impl.func) {\n const uint8_t* iop_r = *ptr_iop_r;\n uint64_t src_len = wuffs_base__u64__min(\n ((uint64_t)up_to_num_pixels) *\n ((uint64_t)p->private_impl.src_pixfmt_bytes_per_pixel),\n ((uint64_t)(io2_r - iop_r)));\n uint64_t n = (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,\n dst_palette.len, iop_r, src_l" +
+ "en);\n *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;\n return n;\n }\n return 0;\n}\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n const uint8_t** ptr_iop_r,\n const uint8_t* io2_r) {\n if (p && p->private_impl.func) {\n const uint8_t* iop_r = *ptr_iop_r;\n uint64_t src_len = ((uint64_t)(io2_r - iop_r));\n uint64_t n = (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,\n dst_palette.len, iop_r, src_len);\n *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;\n return n;\n }\n return 0;\n}\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src) {\n if (p && p->private_impl.func) {\n " +
+ " return (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,\n dst_palette.len, src.ptr, src.len);\n }\n return 0;\n}\n\nWUFFS_BASE__MAYBE_STATIC uint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n uint64_t num_pixels) {\n if (p && p->private_impl.transparent_black_func) {\n return (*p->private_impl.transparent_black_func)(\n dst.ptr, dst.len, dst_palette.ptr, dst_palette.len, num_pixels,\n p->private_impl.dst_pixfmt_bytes_per_pixel);\n }\n return 0;\n}\n" +
""
const BaseUTF8SubmoduleC = "" +
diff --git a/lang/builtin/builtin.go b/lang/builtin/builtin.go
index 8ae8a95..4a4387e 100644
--- a/lang/builtin/builtin.go
+++ b/lang/builtin/builtin.go
@@ -514,6 +514,9 @@
"pixel_swizzler.prepare!(" +
"dst_pixfmt: pixel_format, dst_palette: slice u8," +
"src_pixfmt: pixel_format, src_palette: slice u8, blend: pixel_blend) status",
+
+ "pixel_swizzler.limited_swizzle_u32_interleaved_from_reader!(" +
+ "up_to_num_pixels: u32, dst: slice u8, dst_palette: slice u8, src: io_reader) u64",
"pixel_swizzler.swizzle_interleaved_from_reader!(" +
"dst: slice u8, dst_palette: slice u8, src: io_reader) u64",
"pixel_swizzler.swizzle_interleaved_from_slice!(" +
diff --git a/lang/token/list.go b/lang/token/list.go
index 72a60ec..976b030 100644
--- a/lang/token/list.go
+++ b/lang/token/list.go
@@ -663,7 +663,8 @@
IDValidUTF8Length = ID(0x249)
IDWidth = ID(0x24A)
- IDSwizzleInterleavedFromReader = ID(0x280)
+ IDLimitedSwizzleU32InterleavedFromReader = ID(0x280)
+ IDSwizzleInterleavedFromReader = ID(0x281)
)
var builtInsByID = [nBuiltInIDs]string{
@@ -1026,7 +1027,8 @@
IDValidUTF8Length: "valid_utf_8_length",
IDWidth: "width",
- IDSwizzleInterleavedFromReader: "swizzle_interleaved_from_reader",
+ IDLimitedSwizzleU32InterleavedFromReader: "limited_swizzle_u32_interleaved_from_reader",
+ IDSwizzleInterleavedFromReader: "swizzle_interleaved_from_reader",
}
var builtInsByName = map[string]ID{}
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 28ab222..e87e854 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -9228,6 +9228,15 @@
// ---------------- Images
WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
+ const wuffs_base__pixel_swizzler* p,
+ uint32_t up_to_num_pixels,
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ const uint8_t** ptr_iop_r,
+ const uint8_t* io2_r);
+
+WUFFS_BASE__MAYBE_STATIC uint64_t //
wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
const wuffs_base__pixel_swizzler* p,
wuffs_base__slice_u8 dst,
@@ -15620,6 +15629,28 @@
}
WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
+ const wuffs_base__pixel_swizzler* p,
+ uint32_t up_to_num_pixels,
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ const uint8_t** ptr_iop_r,
+ const uint8_t* io2_r) {
+ if (p && p->private_impl.func) {
+ const uint8_t* iop_r = *ptr_iop_r;
+ uint64_t src_len = wuffs_base__u64__min(
+ ((uint64_t)up_to_num_pixels) *
+ ((uint64_t)p->private_impl.src_pixfmt_bytes_per_pixel),
+ ((uint64_t)(io2_r - iop_r)));
+ uint64_t n = (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
+ dst_palette.len, iop_r, src_len);
+ *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
+ return n;
+ }
+ return 0;
+}
+
+WUFFS_BASE__MAYBE_STATIC uint64_t //
wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
const wuffs_base__pixel_swizzler* p,
wuffs_base__slice_u8 dst,
@@ -15628,9 +15659,9 @@
const uint8_t* io2_r) {
if (p && p->private_impl.func) {
const uint8_t* iop_r = *ptr_iop_r;
+ uint64_t src_len = ((uint64_t)(io2_r - iop_r));
uint64_t n = (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
- dst_palette.len, iop_r,
- (size_t)(io2_r - iop_r));
+ dst_palette.len, iop_r, src_len);
*ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
return n;
}
@@ -17411,12 +17442,9 @@
v_rle_state = 3;
goto label__inner__continue;
} else if (v_rle_state == 3) {
- v_n = (v_dst_bytes_per_pixel * ((uint64_t)(self->private_impl.f_rle_length)));
- if (v_n < ((uint64_t)(v_dst.len))) {
- v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_n);
- }
- v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
+ v_n = wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
&self->private_impl.f_swizzler,
+ self->private_impl.f_rle_length,
v_dst,
v_dst_palette,
&iop_a_src,
diff --git a/std/bmp/decode_bmp.wuffs b/std/bmp/decode_bmp.wuffs
index 323ea1e..942fde5 100644
--- a/std/bmp/decode_bmp.wuffs
+++ b/std/bmp/decode_bmp.wuffs
@@ -572,11 +572,8 @@
continue.inner
} else if rle_state == RLE_STATE_LITERAL {
- n = dst_bytes_per_pixel * (this.rle_length as base.u64)
- if n < dst.length() {
- dst = dst[.. n]
- }
- n = this.swizzler.swizzle_interleaved_from_reader!(
+ n = this.swizzler.limited_swizzle_u32_interleaved_from_reader!(
+ up_to_num_pixels: this.rle_length,
dst: dst,
dst_palette: dst_palette,
src: args.src)