summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-09-05 13:15:32 -0400
committerpommicket <pommicket@gmail.com>2023-09-05 13:59:13 -0400
commit19f2fdc726c531d5bbc05fbd0ea1445f61208ffb (patch)
treeffe53e8d024e1d7eb3e8451cf16816cd00125875
parent037d3dd675eba2ebee9fce7a79eaebc7c7442d73 (diff)
fix conversion bugs
-rw-r--r--README.md4
-rwxr-xr-xcheck-size.sh4
-rw-r--r--src/lib.rs24
-rw-r--r--test/tiny-1bpp-gray.pngbin0 -> 327 bytes
-rw-r--r--test/tiny-2bpp.pngbin0 -> 95 bytes
-rw-r--r--test/tinyplte-8bpp.pngbin0 -> 158 bytes
6 files changed, 23 insertions, 9 deletions
diff --git a/README.md b/README.md
index c3e7e62..5011829 100644
--- a/README.md
+++ b/README.md
@@ -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. &gt;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
diff --git a/src/lib.rs b/src/lib.rs
index 5c5121e..eb41034 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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
new file mode 100644
index 0000000..bcbe525
--- /dev/null
+++ b/test/tiny-1bpp-gray.png
Binary files differ
diff --git a/test/tiny-2bpp.png b/test/tiny-2bpp.png
new file mode 100644
index 0000000..9e3a49b
--- /dev/null
+++ b/test/tiny-2bpp.png
Binary files differ
diff --git a/test/tinyplte-8bpp.png b/test/tinyplte-8bpp.png
new file mode 100644
index 0000000..1fcd988
--- /dev/null
+++ b/test/tinyplte-8bpp.png
Binary files differ