diff options
author | pommicket <pommicket@gmail.com> | 2023-09-04 13:54:53 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2023-09-04 14:01:49 -0400 |
commit | 7f7c4845e0ad01b229f30769708fad5fe7f72e1e (patch) | |
tree | ca784c3c45c1a61aa3276f76422e04e59095f95e | |
parent | 36cc87543dd8a90342aa9d922d9f9fef852df91c (diff) |
more tests
-rw-r--r-- | README.md | 46 | ||||
-rw-r--r-- | examples/alloc_correct.rs | 14 | ||||
-rw-r--r-- | examples/image.png | bin | 0 -> 465986 bytes | |||
-rw-r--r-- | examples/small.rs | 7 | ||||
-rw-r--r-- | examples/very_basic.rs | 12 | ||||
-rw-r--r-- | src/lib.rs | 87 | ||||
-rw-r--r-- | test/1QPS.png | bin | 0 -> 663162 bytes | |||
-rw-r--r-- | test/adam.png | bin | 0 -> 2146443 bytes | |||
-rw-r--r-- | test/basketball.png | bin | 0 -> 157426 bytes | |||
-rw-r--r-- | test/berry.png | bin | 0 -> 92029 bytes | |||
-rw-r--r-- | test/canada.png | bin | 0 -> 603471 bytes | |||
-rw-r--r-- | test/cavendish.png | bin | 0 -> 26622 bytes | |||
-rw-r--r-- | test/cheerios.png | bin | 0 -> 591837 bytes | |||
-rw-r--r-- | test/endsleigh.png | bin | 0 -> 513515 bytes | |||
-rw-r--r-- | test/gray_alpha.png | bin | 0 -> 7485 bytes | |||
-rw-r--r-- | test/iroquois.png | bin | 0 -> 73902 bytes | |||
-rw-r--r-- | test/nightingale.png | bin | 0 -> 162187 bytes | |||
-rw-r--r-- | test/ouroboros.png | bin | 0 -> 25519 bytes | |||
-rw-r--r-- | test/photograph.png | bin | 0 -> 308427 bytes | |||
-rw-r--r-- | test/rabbit.png | bin | 0 -> 115920 bytes | |||
-rw-r--r-- | test/ratatoskr.png | bin | 0 -> 465986 bytes | |||
-rw-r--r-- | test/small.png (renamed from examples/small.png) | bin | 233 -> 233 bytes | |||
-rw-r--r-- | test/triangle.png | bin | 0 -> 3083 bytes | |||
-rw-r--r-- | test/württemberg.png | bin | 0 -> 916327 bytes |
24 files changed, 149 insertions, 17 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..04e126a --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +## tiny-png + +Tiny Rust PNG decoder. + +This decoder can be used without `std` or even `alloc` by disabling the `std` feature (enabled by default). + +## Goals + +- Correctly decode all non-interlaced PNG files (if a non-interlaced PNG is decoded incorrectly, please report it as a bug) +- Small code size +- No panics (if any function panics, please report it as a bug). +- No unsafe code + +## Non-goals + +- Adam7 interlacing (interlaced PNGs are rare, and this would require additional code complexity + — but if you want to add it behind a feature gate, feel free to) +- Sacrificing code size for speed (except maybe with a feature enabled) + +## Example usage + +Very basic usage: + +```rust +let mut buffer = vec![0; 1 << 20]; // hope this is big enough! +let mut png = &include_bytes!("image.png")[..]; +let image = tiny_png::read_png(&mut png, None, &mut buffer).expect("bad PNG"); +println!("{}x{} image", image.width(), image.height()); +let pixels = image.pixels(); +println!("top-left pixel is #{:02x}{:02x}{:02x}", pixels[0], pixels[1], pixels[2]); +// (^ this only makes sense for RGB 8bpc images) +``` + +Allocate the right number of bytes: + +```rust +let mut png = &include_bytes!("image.png")[..]; +let header = tiny_png::read_png_header(&mut png).expect("bad PNG"); +println!("need {} bytes of memory", header.required_bytes()); +let mut buffer = vec![0; header.required_bytes()]; +let image = tiny_png::read_png(&mut png, Some(&header), &mut buffer).expect("bad PNG"); +println!("{}x{} image", image.width(), image.height()); +let pixels = image.pixels(); +println!("top-left pixel is #{:02x}{:02x}{:02x}", pixels[0], pixels[1], pixels[2]); +// (^ this only makes sense for RGB 8bpc images) +``` diff --git a/examples/alloc_correct.rs b/examples/alloc_correct.rs new file mode 100644 index 0000000..6711a1c --- /dev/null +++ b/examples/alloc_correct.rs @@ -0,0 +1,14 @@ +fn main() { + let mut png = &include_bytes!("image.png")[..]; + let header = tiny_png::read_png_header(&mut png).expect("bad PNG"); + println!("need {} bytes of memory", header.required_bytes()); + let mut buffer = vec![0; header.required_bytes()]; + let image = tiny_png::read_png(&mut png, Some(&header), &mut buffer).expect("bad PNG"); + println!("{}x{} image", image.width(), image.height()); + let pixels = image.pixels(); + println!( + "top-left pixel is #{:02x}{:02x}{:02x}", + pixels[0], pixels[1], pixels[2] + ); + // (^ this only makes sense for RGB 8bpc images) +} diff --git a/examples/image.png b/examples/image.png Binary files differnew file mode 100644 index 0000000..5452484 --- /dev/null +++ b/examples/image.png diff --git a/examples/small.rs b/examples/small.rs deleted file mode 100644 index e6af172..0000000 --- a/examples/small.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let mut data = &include_bytes!("small.png")[..]; - let header = tiny_png::read_png_header(&mut data).unwrap(); - let mut buf = vec![0; header.required_bytes()]; - let result = tiny_png::read_png(&mut data, Some(&header), &mut buf); - println!("{result:?}"); -} diff --git a/examples/very_basic.rs b/examples/very_basic.rs new file mode 100644 index 0000000..33043b6 --- /dev/null +++ b/examples/very_basic.rs @@ -0,0 +1,12 @@ +fn main() { + let mut my_buffer = vec![0; 1 << 20]; // hope this is big enough! + let mut png = &include_bytes!("image.png")[..]; + let image = tiny_png::read_png(&mut png, None, &mut my_buffer).expect("bad PNG"); + println!("{}x{} image", image.width(), image.height()); + let pixels = image.pixels(); + println!( + "top-left pixel is #{:02x}{:02x}{:02x}", + pixels[0], pixels[1], pixels[2] + ); + // (^ this only makes sense for RGB 8bpc images) +} @@ -786,13 +786,13 @@ fn apply_filters<I: IOError>(header: &ImageHeader, data: &mut [u8]) -> Result<() #[derive(Debug)] pub struct ImageData<'a> { header: ImageHeader, - pixels: &'a [u8], + buffer: &'a mut [u8], palette: [[u8; 4]; 256], } impl ImageData<'_> { pub fn pixels(&self) -> &[u8] { - self.pixels + &self.buffer[..self.header.data_size()] } pub fn palette(&self) -> &[[u8; 4]] { &self.palette[..] @@ -832,6 +832,7 @@ fn read_non_idat_chunks<R: Read>( chunk_header[7], ]; if &chunk_type == b"IEND" { + reader.skip_bytes(4)?; // CRC break; } else if &chunk_type == b"IDAT" { return Ok(Some(chunk_len)); @@ -895,7 +896,7 @@ pub fn read_png<'a, R: Read>( let buf = writer.slice; apply_filters(&header, buf)?; Ok(ImageData { - pixels: &buf[..header.data_size()], + buffer: buf, header, palette, }) @@ -917,9 +918,8 @@ mod tests { let mut r = std::io::BufReader::new(File::open(path).expect("file not found")); let tiny_header = read_png_header(&mut r).unwrap(); let mut tiny_buf = vec![0; tiny_header.required_bytes()]; - let tiny_bytes = read_png(&mut r, Some(&tiny_header), &mut tiny_buf) - .unwrap() - .pixels; + let image = read_png(&mut r, Some(&tiny_header), &mut tiny_buf).unwrap(); + let tiny_bytes = image.pixels(); assert_eq!(png_bytes.len(), tiny_bytes.len()); assert_eq!(png_bytes, tiny_bytes); @@ -935,9 +935,8 @@ mod tests { let tiny_header = read_png_header(&mut bytes).unwrap(); let mut tiny_buf = vec![0; tiny_header.required_bytes()]; - let tiny_bytes = read_png(&mut bytes, Some(&tiny_header), &mut tiny_buf) - .unwrap() - .pixels; + let image = read_png(&mut bytes, Some(&tiny_header), &mut tiny_buf).unwrap(); + let tiny_bytes = image.pixels(); assert_eq!(png_bytes.len(), tiny_bytes.len()); assert_eq!(png_bytes, tiny_bytes); @@ -952,7 +951,7 @@ mod tests { #[test] fn test_small() { - test_both!("examples/small.png"); + test_both!("test/small.png"); } #[test] fn test_small_rgb() { @@ -963,6 +962,10 @@ mod tests { test_both!("test/small_rgba.png"); } #[test] + fn test_gray_alpha() { + test_both!("test/gray_alpha.png"); + } + #[test] fn test_earth0() { test_both!("test/earth0.png"); } @@ -971,7 +974,71 @@ mod tests { test_both!("test/earth9.png"); } #[test] + fn test_photograph() { + test_both!("test/photograph.png"); + } + #[test] fn test_earth_palette() { test_both!("test/earth_palette.png"); } + #[test] + fn test_württemberg() { + test_both!("test/württemberg.png"); + } + #[test] + fn test_endsleigh() { + test_both!("test/endsleigh.png"); + } + #[test] + fn test_1qps() { + test_both!("test/1QPS.png"); + } + #[test] + fn test_rabbit() { + test_both!("test/rabbit.png"); + } + #[test] + fn test_basketball() { + test_both!("test/basketball.png"); + } + #[test] + fn test_triangle() { + test_both!("test/triangle.png"); + } + #[test] + fn test_iroquois() { + test_both!("test/iroquois.png"); + } + #[test] + fn test_canada() { + test_both!("test/canada.png"); + } + #[test] + fn test_berry() { + test_both!("test/berry.png"); + } + #[test] + fn test_adam() { + test_both!("test/adam.png"); + } + #[test] + fn test_nightingale() { + test_both!("test/nightingale.png"); + } + #[test] + fn test_ratatoskr() { + test_both!("test/ratatoskr.png"); + } + #[test] + fn test_cheerios() { + test_both!("test/cheerios.png"); + } + #[test] + fn test_cavendish() { + test_both!("test/cavendish.png"); + } + #[test] + fn test_ouroboros() { + test_both!("test/ouroboros.png"); + } } diff --git a/test/1QPS.png b/test/1QPS.png Binary files differnew file mode 100644 index 0000000..50836ca --- /dev/null +++ b/test/1QPS.png diff --git a/test/adam.png b/test/adam.png Binary files differnew file mode 100644 index 0000000..8661a2e --- /dev/null +++ b/test/adam.png diff --git a/test/basketball.png b/test/basketball.png Binary files differnew file mode 100644 index 0000000..bbcf32f --- /dev/null +++ b/test/basketball.png diff --git a/test/berry.png b/test/berry.png Binary files differnew file mode 100644 index 0000000..341564a --- /dev/null +++ b/test/berry.png diff --git a/test/canada.png b/test/canada.png Binary files differnew file mode 100644 index 0000000..41ea0db --- /dev/null +++ b/test/canada.png diff --git a/test/cavendish.png b/test/cavendish.png Binary files differnew file mode 100644 index 0000000..5bf99ff --- /dev/null +++ b/test/cavendish.png diff --git a/test/cheerios.png b/test/cheerios.png Binary files differnew file mode 100644 index 0000000..a53fd2c --- /dev/null +++ b/test/cheerios.png diff --git a/test/endsleigh.png b/test/endsleigh.png Binary files differnew file mode 100644 index 0000000..2dc6e65 --- /dev/null +++ b/test/endsleigh.png diff --git a/test/gray_alpha.png b/test/gray_alpha.png Binary files differnew file mode 100644 index 0000000..2857715 --- /dev/null +++ b/test/gray_alpha.png diff --git a/test/iroquois.png b/test/iroquois.png Binary files differnew file mode 100644 index 0000000..069cd4c --- /dev/null +++ b/test/iroquois.png diff --git a/test/nightingale.png b/test/nightingale.png Binary files differnew file mode 100644 index 0000000..617a7fc --- /dev/null +++ b/test/nightingale.png diff --git a/test/ouroboros.png b/test/ouroboros.png Binary files differnew file mode 100644 index 0000000..fd22ae8 --- /dev/null +++ b/test/ouroboros.png diff --git a/test/photograph.png b/test/photograph.png Binary files differnew file mode 100644 index 0000000..09a62b9 --- /dev/null +++ b/test/photograph.png diff --git a/test/rabbit.png b/test/rabbit.png Binary files differnew file mode 100644 index 0000000..c1f4928 --- /dev/null +++ b/test/rabbit.png diff --git a/test/ratatoskr.png b/test/ratatoskr.png Binary files differnew file mode 100644 index 0000000..5452484 --- /dev/null +++ b/test/ratatoskr.png diff --git a/examples/small.png b/test/small.png Binary files differindex 47226a2..47226a2 100644 --- a/examples/small.png +++ b/test/small.png diff --git a/test/triangle.png b/test/triangle.png Binary files differnew file mode 100644 index 0000000..893b4dd --- /dev/null +++ b/test/triangle.png diff --git a/test/württemberg.png b/test/württemberg.png Binary files differnew file mode 100644 index 0000000..1c02a68 --- /dev/null +++ b/test/württemberg.png |