From f8c62de6c04d3cae30c6b6e308689131b57b5284 Mon Sep 17 00:00:00 2001 From: Josh Holmer Date: Sat, 23 Dec 2017 00:36:41 -0500 Subject: [PATCH] Fix unfiltering of first scan line in each pass of an interlaced input file Closes #92 --- CHANGELOG.md | 1 + src/png.rs | 7 +++++++ tests/files/issue-92.png | Bin 0 -> 1909 bytes tests/regression.rs | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 tests/files/issue-92.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b46e357..8ead3f13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### Version 0.18.2 (unreleased) - Bump `image` to 0.18 + - Fix unfiltering of scan lines in interlaced images ([#92](https://github.com/shssoichiro/oxipng/issues/92)) ### Version 0.18.1 - Bump `rayon` to 0.9 diff --git a/src/png.rs b/src/png.rs index dd35046f..a6b8a6d2 100644 --- a/src/png.rs +++ b/src/png.rs @@ -377,7 +377,14 @@ impl PngData { 8f32) .ceil() as usize; let mut last_line: Vec = Vec::new(); + let mut last_pass = 1; for line in self.scan_lines() { + if let Some(pass) = line.pass { + if pass != last_pass { + last_line = Vec::new(); + last_pass = pass; + } + } let unfiltered_line = unfilter_line(line.filter, bpp, &line.data, &last_line); unfiltered.push(0); unfiltered.extend_from_slice(&unfiltered_line); diff --git a/tests/files/issue-92.png b/tests/files/issue-92.png new file mode 100644 index 0000000000000000000000000000000000000000..e1b5f96cdb06dcbbfacab5d87a473d2b5b54f062 GIT binary patch literal 1909 zcmX9;dpwj|7vAr@?_7*Q!(ikTqEK$3R1{;xOr;q5@VRE(Z=>9A6EjT`ozsnqsGO98 zQ~4yP+(w6@UlQp=o!n9?xg|2!_e|$ozu(%=v)6w1TKk`87kKPTIH z*ZxR?Vu7LqIzB2;DUsoq1c0)}kAy(!WhwwLHJVQM@QC6hbCRMsiTX@BT|e;%Cn7p7 z9DwxK?2wR(v5ymzPmF{@4-aqFw{)~D zhBU3Lt+JaR3A=?tVWQuw{;rLDfQR=(MIkpYuft@0<2J?Zab*~$XJ#;IN-)eO z!7!h}O8u8ZKX@wRw2h*!&}bZB#_U#TV15#p7Va65=~}?MR#jESWAEXzYMc|p4>MyD z>UohtN4TCeu4gDShNut^s^Sz8bU~_){oeW10c!{!#BJoC=r+L;l*zjYn-PYE`9?l| zJv`?YJ{!MCWe*@lk@y8Za=x_qy*xX2Un?bJ%K;qrKNU`@0qdHfI(w7Ytu%CAiOG9as)t8G>}<1*JvzcNfNk z&8`~Wp+7%3f6}Aox!QOTS@TS5<#=Uq=Y|5^g5WdNr_Y~r*idX~Zl2?OW8Z%QmrDY! zv=mD91izmY?8)52DSlN$sV=RSd)rr!RFP|byDp+l=PnzSdk1dXNo(~HyOFf0f35DK zzA5c4vo341Z4POB5nAvbsogOhP`2%jlf6$?ES~MQ#&}EQdTp#vh8;F7TrK55prr;! zS1)Zeq#Z$}xnf}fZ7)Af5J1Y&c}6kNj@Hy92a;`UQV;yiNA9`2y?$r%`1vir*}d3q zZDwuL@F61jX?R~l-))m2@0DA=%|^A!2ZzguvL|P20=E=32BmmS>uvqK<)!VF_~O`2 zagMJ|-yR&ydEnD{yB?i&DPuMmqvfj|XXZ(#F3B3&`j{89GTTJFszMj7CJWI$vm{Y# zu|e(r+lT#{Ij!%H$CvHf${CLNU%W)Mwp^0dJiEQwG7jbQx94-$MmuicW_K~Cy{4WS zU6G}52X@cwb-Qg8BumSA=3eHXHa9rx)pm5^&-ZU zQuIR6&=RY$cVS~AiT}OCEXv}V^Y!hUDgQsAu*ss1O6dfaKe*BKufVdR0G;7|Gbvj~ zPbEZz9SRda7SA~v{woDepdE!YC@6rXI1CKozmp7B5TKPxP@0Yd?POfFvq}?2iqlhz zCEtVaR|g)2OE{1UfJCU05)4Tt00X{*MDPm=Y0707B^f~~CIAsu48sHjk}Z(!c5VUF zUsV7Ks5%$h%+*cStb0K(Y+_2ohZkndqU2QmEK(f6Ih<^3@`WXQ|P1-lHdrGw+ zGG4yu;YlPyA27$>kVFtsj^gk*1W4r)F(gC5JWx}-93rZI(|{*c5Ohg(kpNL-C<5c< zhy)R%C@e-Wu##f-B1$2XWRvr1h#d2E9@^k42A$7UFk%S8s>lv2J_`Z?Mz7t)%mW?! z`dCeM6Z7bvtxxLLt^&*_4%$ZAmbG=;BJouvFeW^E2)G>+tt>6<1JTL>m>IhjoQ}px zW#Ts&MWI)iEX$}bW=Fm%b-U!?F1G&-!G!!ZCv!U5{XX@1)wLrKVfBJ$!cPcJ4qs?O z3Cj=(h9s~|jFro9c$lz^$R#iqkB5L%Di%Y_D1-wjEJpzZ%Q3JNKuCvuEX9)o#*&_u z-(MW+Io%uK9$;j~6R6WXPIRjedh>j%qYfEr@etAqK90o@I@iVBwRJWs9y1i2eq`dx zJQroK$CdIpaA;seY`0RrIjJ zCRsEzl$wlfeg6^U=r9nDSK3rapTwpOWBe!{VjM z?AU1e^8%YzpSc|{6}L0KG}72t_kiH1rr0e1mmOj6-2q7Uv7 dPkYGKKv_h(-ubPAmI}84=I;G2x12+G{{WRgGRyz~ literal 0 HcmV?d00001 diff --git a/tests/regression.rs b/tests/regression.rs index 02b5498c..77d91496 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -325,3 +325,41 @@ fn issue_89() { BitDepth::Eight, ); } + +#[test] +fn issue_92_filter_0() { + let input = PathBuf::from("tests/files/issue-92.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts( + &input, + &output, + &opts, + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight, + ); +} + +#[test] +fn issue_92_filter_5() { + let input = PathBuf::from("tests/files/issue-92.png"); + let mut opts = get_opts(&input); + let mut filter = HashSet::new(); + filter.insert(5); + opts.filter = filter; + opts.out_file = input.with_extension("-f5-out.png").to_owned(); + let output = opts.out_file.clone(); + + test_it_converts( + &input, + &output, + &opts, + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight, + ); +}