From e70e93c1a4a5cd3618d0a9da82e63f7a42c6ac4b Mon Sep 17 00:00:00 2001 From: Lukasz Anforowicz Date: Tue, 31 Oct 2023 15:31:03 +0000 Subject: [PATCH] New PNG inputs for benchmarking non-compressed, non-filtered data. --- benches/decoder.rs | 4 +- tests/benches/128x128-noncompressed.png | Bin 0 -> 65772 bytes tests/benches/8x8-noncompressed.png | Bin 0 -> 332 bytes tests/benches/README.md | 28 ++++-- tests/benches/noncompressed/Cargo.toml | 11 +++ tests/benches/noncompressed/src/main.rs | 108 ++++++++++++++++++++++++ 6 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 tests/benches/128x128-noncompressed.png create mode 100644 tests/benches/8x8-noncompressed.png create mode 100644 tests/benches/noncompressed/Cargo.toml create mode 100644 tests/benches/noncompressed/src/main.rs diff --git a/benches/decoder.rs b/benches/decoder.rs index a078c9a0..60af0fac 100644 --- a/benches/decoder.rs +++ b/benches/decoder.rs @@ -20,7 +20,9 @@ criterion_main!(benches); fn bench_file(c: &mut Criterion, data: Vec, name: String) { let mut group = c.benchmark_group("decode"); - group.sample_size(20); + if data.len() > 100000 { + group.sample_size(20); + } let decoder = Decoder::new(&*data); let mut reader = decoder.read_info().unwrap(); diff --git a/tests/benches/128x128-noncompressed.png b/tests/benches/128x128-noncompressed.png new file mode 100644 index 0000000000000000000000000000000000000000..3ab7f461dff79437bf3bb21d8a4cdb5031c2b8e8 GIT binary patch literal 65772 zcmeI*hhNln9LMqBIS@~APeepSIQ9?`5s`5S=Rl^2h;ZyZ9k|KTvb~3ynVFdxS+5B2%6r`*1G zQUC9HY2Y`m8vIpn4gJEb;h*)<$WQue)W>cbeXgIzeAHiKKOCTO9}Lv^_Xo-Ey}|N- zcZdSt8LHs7hbi=};R=6qgeJT(QWIZy*QA4^H2F0TO?h>+roQ5-X)lja!b@ICdSR@R zpYvAAGvj1?%11Mw7_Zrn`)bZ^KV`IAl(oxWIXeTCyCYC}+k=$9Em#FxLsYmWRQAnb zD%ljSvW*d{xO0N4ZjV&WtrJyubCeoxoTR4fqt$ZlWG%irMoX`nqGju2wc?7YTD3M# zYucviveogrd}V^xEl<>ytx4Lj#Hwo+CF{E8>AImYMK{%_>XurYZmXW5J1S@DuJT#B zyL7hhDNfV9MRRoD!gSrgAVUw#&(wqSvh>j0Y(1Qvqen95>e2LEJ(f04duHY7$rFVw!cB6Y;twLhj<2ck=KD5_MQk!3m@QLZCl6*?MHsbfJ^ zIv!B16P6mC^sUt?pE{lPuGbl_2A%b6)On94U2t#Krz2YQ`LIR$a>!zRJ!px(9k5gv z`?czazRUEJdAWXZU7_DxR_c!)tMpg5)#3u+0^k>bUjY6B_zU13fO`OL0=Ws~DS)Q{ z9s_v{XLuM213xp~2X2Y&gpSEC;Y1!gdJjL97R{AI5$d3xX^NvLVWbC@aFO z2(u&Z{5#?f1i+#=NdY7U5EVgG1X&?ug%B1)SPW@Fqy-TdMO+klVdRAo7)M|niGd^r z5*bNkB$=Uv#u6G!YA~t6#6}YvO>Q{3;RMG!e{j450gxU~eE{_V^heMiL4gPbA~eX* zAVY-^6+(1K(IG{N7$st~$k8H4jUY9G^hnYpNs%Z;qBP0UBukYrRl;;h(oKmnitPyi?Z6aWeU1%LuT z0iXa-04M+y015yFfC4}Ppa4(+C;$`y3UEFY;6MN;EHygmTdPw(bvo@`FHis|KxaK0 zb>5>%7u=ggR0Jvn6@m&ug`h%EA*c{k2r2{>f(k)}ph8d~s1Q^LDg+gR3PFXSLQo;7 z5L5^%1Qmh`L4`Pl3UMHSBViRf8d9laK~*{)P%TivjzHyY4^sZNU=?f)Q6VS*6hKr2 zDuk>MSP)?`xG>U!fPutCwEzQwfxtjuATSUZ2n+-U0t118z(8OiFc26B3nGQ#k3ly;1PZ{kNW$p4;&dvbkf&z$&K!uPM0t+H61{X$J z5HOIqC}d~@G87q#3`K?_Ly@7#P-G}F6d8&P6*3eViVQ`DB14g($WUbHr7lBFZN?hy ojW5)`xFU7L+O>(); + crc32fast::hash(input.as_slice()) + }; + w.write_u32::(data.len() as u32) + .unwrap(); + w.write_all(chunk_type).unwrap(); + w.write_all(data).unwrap(); + w.write_u32::(crc).unwrap(); +} + +fn write_ihdr(w: &mut impl Write, width: u32) { + let mut data = Vec::new(); + data.write_u32::(width).unwrap(); + data.write_u32::(width).unwrap(); // height + data.write_u8(8).unwrap(); // bit depth = always 8-bits per channel + data.write_u8(6).unwrap(); // color type = color + alpha + data.write_u8(0).unwrap(); // compression method (0 is the only allowed value) + data.write_u8(0).unwrap(); // filter method (0 is the only allowed value) + data.write_u8(0).unwrap(); // interlace method = no interlacing + // + write_chunk(w, b"IHDR", &data); +} + +fn write_noncompressed_deflate_block(w: &mut impl Write, data: &[u8], last: bool) { + if last { + w.write_u8(1).unwrap(); + } else { + w.write_u8(0).unwrap(); + } + + assert!(data.len() < 65535); + let len = data.len() as u16; + w.write_u16::(len).unwrap(); + w.write_u16::(!len).unwrap(); + + w.write_all(data).unwrap(); +} + +fn write_idat(w: &mut impl Write, width: u32) { + // Generate arbitrary test pixels. + let image_pixels = { + let mut row = Vec::new(); + row.write_u8(0).unwrap(); // filter = no filter + + let row_pixels = (0..width) + .map(|i| { + let color: u8 = (i * 255 / width) as u8; + let alpha: u8 = 0xff; + [color, 255 - color, color / 2, alpha] + }) + .flatten(); + row.extend(row_pixels); + + std::iter::repeat(row) + .take(width as usize) + .flatten() + .collect::>() + }; + + let mut zlib_data = Vec::new(); + zlib_data.write_u8(0x78).unwrap(); // CM + CINFO + zlib_data.write_u8(0x01).unwrap(); // FLG + + let mut chunks = image_pixels.as_slice().chunks_exact(8192); + while let Some(chunk) = chunks.next() { + write_noncompressed_deflate_block(&mut zlib_data, chunk, false); + } + write_noncompressed_deflate_block(&mut zlib_data, chunks.remainder(), true); + + let adler = adler32::adler32(image_pixels.as_slice()).unwrap(); + zlib_data.write_u32::(adler).unwrap(); + + write_chunk(w, b"IDAT", &zlib_data); +} + +fn write_iend(w: &mut impl Write) { + write_chunk(w, b"IEND", &[]); +} + +fn write_png_file(w: &mut impl Write, width: u32) { + write_png_sig(w); + write_ihdr(w, width); + write_idat(w, width); + write_iend(w); +} + +fn main() { + let mut f = File::create("8x8-noncompressed.png").unwrap(); + write_png_file(&mut f, 8); + + let mut f = File::create("128x128-noncompressed.png").unwrap(); + write_png_file(&mut f, 128); +}