diff options
-rw-r--r-- | README.md | 4 | ||||
-rwxr-xr-x | check-size.sh | 4 | ||||
-rw-r--r-- | src/lib.rs | 24 | ||||
-rw-r--r-- | test/tiny-1bpp-gray.png | bin | 0 -> 327 bytes | |||
-rw-r--r-- | test/tiny-2bpp.png | bin | 0 -> 95 bytes | |||
-rw-r--r-- | test/tinyplte-8bpp.png | bin | 0 -> 158 bytes |
6 files changed, 23 insertions, 9 deletions
@@ -4,7 +4,7 @@ Tiny Rust PNG decoder. This decoder can be used without `std` or `alloc` by disabling the `std` feature (enabled by default). -Also it has tiny code size (e.g. 5x smaller `.wasm.gz` size compared to the `png` crate — see `check-size.sh`). +Also it has tiny code size (e.g. >8x smaller `.wasm.gz` size compared to the `png` crate — see `check-size.sh`). ## Goals @@ -18,7 +18,7 @@ Also it has tiny code size (e.g. 5x smaller `.wasm.gz` size compared to the `png ## Non-goals - Adam7 interlacing (increases code complexity and interlaced PNGs are rare anyways) -- Significantly sacrificing code size for speed (except maybe with a feature enabled) +- Significantly sacrificing code size/complexity for speed - Checking block CRCs (increases code complexity and there’s already Adler32 checksums for IDAT chunks) diff --git a/check-size.sh b/check-size.sh index 6f12db0..618eb5b 100755 --- a/check-size.sh +++ b/check-size.sh @@ -1,6 +1,6 @@ #!/bin/sh -cd examples/wasm-tiny-png && cargo b --release && cd ../.. && wasm-opt -Oz examples/wasm-tiny-png/target/wasm32-unknown-unknown/release/wasm_tiny_png.wasm -o target/tiny_png.wasm && gzip -f target/tiny_png.wasm || exit 1 -cd examples/wasm-png && cargo b --release && cd ../.. && wasm-opt -Oz examples/wasm-png/target/wasm32-unknown-unknown/release/wasm_png.wasm -o target/png.wasm && gzip -f target/png.wasm || exit 1 +cd examples/wasm-tiny-png && cargo b --release && cd ../.. && wasm-opt --strip-debug -Oz examples/wasm-tiny-png/target/wasm32-unknown-unknown/release/wasm_tiny_png.wasm -o target/tiny_png.wasm && gzip -k -f target/tiny_png.wasm || exit 1 +cd examples/wasm-png && cargo b --release && cd ../.. && wasm-opt --strip-debug -Oz examples/wasm-png/target/wasm32-unknown-unknown/release/wasm_png.wasm -o target/png.wasm && gzip -k -f target/png.wasm || exit 1 wc -c target/png.wasm.gz target/tiny_png.wasm.gz | head -n2 @@ -772,7 +772,7 @@ impl ImageData<'_> { let mut dest = 4 * area; let mut src = area; for _ in 0..area { - let index: usize = buffer[src].into(); + let index: usize = buffer[src - 1].into(); buffer[dest - 4..dest].copy_from_slice(&palette[index]); dest -= 4; src -= 1; @@ -794,8 +794,10 @@ impl ImageData<'_> { src_bit = 8; } src_bit -= bit_depth; - let index: usize = - ((buffer[src] >> src_bit) & ((1 << bit_depth) - 1)).into(); + // NOTE: PNG uses most-significant-bit first, unlike everyone else in the world. + let index: usize = ((buffer[src] >> (8 - bit_depth - src_bit)) + & ((1 << bit_depth) - 1)) + .into(); buffer[dest - 4..dest].copy_from_slice(&palette[index]); dest -= 4; } @@ -1265,7 +1267,7 @@ fn read_non_idat_chunks<R: Read>( } // checksum reader.skip_bytes(4)?; - } else if chunk_type[0].is_ascii_lowercase() || &chunk_type == b"PLTE" { + } else if (chunk_type[0] & 0x20) != 0 || &chunk_type == b"PLTE" { // non-essential chunk reader.skip_bytes(chunk_len + 4)?; } else { @@ -1296,7 +1298,7 @@ pub fn read_png<'a, R: Read>( return Err(Error::BufferTooSmall); } let mut writer = DecompressedDataWriter::from(buf); - let mut palette = [[0, 0, 0, 0]; 256]; + let mut palette = [[0, 0, 0, 255]; 256]; let Some(idat_len) = read_non_idat_chunks(reader, &header, &mut palette)? else { return Err(Error::NoIdat); }; @@ -1420,6 +1422,18 @@ mod tests { test_both!("test/small_rgb.png"); } #[test] + fn test_tiny1bpp_gray() { + test_both!("test/tiny-1bpp-gray.png"); + } + #[test] + fn test_tiny2bpp() { + test_both!("test/tiny-2bpp.png"); + } + #[test] + fn test_tiny_plte8bpp() { + test_both!("test/tinyplte-8bpp.png"); + } + #[test] fn test_gray_alpha() { test_both!("test/gray_alpha.png"); } diff --git a/test/tiny-1bpp-gray.png b/test/tiny-1bpp-gray.png Binary files differnew file mode 100644 index 0000000..bcbe525 --- /dev/null +++ b/test/tiny-1bpp-gray.png diff --git a/test/tiny-2bpp.png b/test/tiny-2bpp.png Binary files differnew file mode 100644 index 0000000..9e3a49b --- /dev/null +++ b/test/tiny-2bpp.png diff --git a/test/tinyplte-8bpp.png b/test/tinyplte-8bpp.png Binary files differnew file mode 100644 index 0000000..1fcd988 --- /dev/null +++ b/test/tinyplte-8bpp.png |