From 39b00910aeb6fa5fb68e8cc785c1c93bfb281c01 Mon Sep 17 00:00:00 2001 From: andrews05 Date: Sun, 9 Jul 2023 10:54:58 +1200 Subject: [PATCH] Use stronger compression in eval (#509) --- src/lib.rs | 14 ++++++++++++-- src/main.rs | 4 ++-- .../files/grayscale_8_should_be_palette_4.png | Bin 16844 -> 2719 bytes tests/flags.rs | 3 +-- tests/regression.rs | 4 ++-- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1ad15e6b..9c26a40c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -646,8 +646,18 @@ fn optimize_raw( max_size: Option, deflater: &T, ) -> Option { - // Must use normal (lazy) compression, as faster ones (greedy) are not representative - let eval_compression = 5; + // Libdeflate has four algorithms: 1-4 = 'greedy', 5-7 = 'lazy', 8-9 = 'lazy2', 10-12 = 'near-optimal' + // 5 is the minimumm required for a decent evaluation result + // 7 is not noticeably slower than 5 and improves evaluation of filters in 'fast' mode (o2 and lower) + // 8 is a little slower but not noticeably when used only for reductions (o3 and higher) + // 9 is not appreciably better than 8 + // 10 and higher are quite slow - good for filters but only good for reductions if matching the main zc level + let eval_compression = match opts.deflate { + Deflaters::Libdeflater { compression } => { + if opts.fast_evaluation { 7 } else { 8 }.min(compression) + } + _ => 8, + }; // None and Bigrams work well together, especially for alpha reductions let eval_filters = indexset! {RowFilter::None, RowFilter::Bigrams}; // This will collect all versions of images and pick one that compresses best diff --git a/src/main.rs b/src/main.rs index 422e79d9..9afc43fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -180,7 +180,7 @@ fn main() { ) .arg( Arg::new("fast") - .help("Use fast filter evaluation") + .help("Use fast filter evaluation (helpful when you have more filters enabled than CPU cores)") .long("fast") .action(ArgAction::SetTrue), ) @@ -242,7 +242,7 @@ fn main() { ) .arg( Arg::new("zopfli") - .help("Use the slower but better compressing Zopfli algorithm") + .help("Use the slow but stronger Zopfli compressor (recommended use is with all filters and `--fast` enabled)") .short('Z') .long("zopfli") .action(ArgAction::SetTrue), diff --git a/tests/files/grayscale_8_should_be_palette_4.png b/tests/files/grayscale_8_should_be_palette_4.png index 66138edb19b6f2ab3522ed66329ac9cb60f6789f..2edd6dbf107d826a8f5e7698c3d382488839c33a 100644 GIT binary patch literal 2719 zcmd7UYg7^l76)*&Z8RHoj4{c4loskKU&E-SgJz*%;WMYAL`Ty|vCKd)@{w99=9_%r z0}V*ccV_t}&787L2z;WcDGh?9jEW&R>NaQhoIShyq4~J?oO|xM_tXD=`;omo;Oc6+ zY5)L0-3ahR0Ls{rYH&lhhF_t!7iqc%todQTuD(oFbJe_3{K9 z>#gRV?)bfs1Ma*X)exkuY*tl+u`LLHEL|g&t7L7z&sF7x=oU!-yZ@7;){ZI&lJL^) zYpGy~;%_Mnk-V?G5DOjsxJv5sM?(|v$>b}W5k4stR{n&%zJ%Z!(BE6?Pwa;%ewx18 z+Kjn_t%fKNkKWvv{Mm{W@aT=^uJ|pv*V%M?2KLbF7!w62Wj_BbMoKWJN^CYi-e4U; z1fVJVLlrYj9dD|z>V26$tM9Ia=*k&<_7ul%vu;rptsO>RQsj!7kdb5)?;#_!80sVCps2ml zaMM!6jd0joZD1&MrT+>i>z6$XT8TbjyLKd$4uZ10tif;Jos2R(cqJJvK{wQ>1w6Ce zT&Crb4Gc|2^f+WC$CJ9D9;Cq(Ey0F>wsRv2Qp7<)Nb6y*j*f0U@v>^XTSP6V%Fn_R3=_f$cH90+rXG66nrWH=Jd;`91Pn@&$ zqkiwba(?#ktP1M>Mf~e~m!}e>0zoj%82Rf;B)xu)X;S}SNwd{mz`2i+`bJ$pT_nq( zSp{}{KA?HO_k%QJDzK-R%I(BSU*u98DlF{bp0^rkKiygz8p>tGlprH-_j@_Iw2Po( zvWbnHd0NG?D}LOjMg>hN_SEyQD;V>1if8Af1uy##V5eSnK?RAs4tYjQ*0+Ey#C1R- zVGih_?ekuhvJ11b4FB23TFjiOJSAUjKf1nRR;k=iyzQ3rxQKI&014tzvceS)r;+Sr zO68dd7``3SCNC8AtA8kY?pPrqAf(OWIV(1&whKJR>?;(ZTN?9gKa^^QBc)RCGF#bY zxpn;8G}<>lP;7B&afjvAbP1|svNY!e$X486*|Kmfe=YU`^#ao1=NfMcZ3eS7=@D{J z-tETWBZZF&z42Y3@prAFqrOzFA8%ty7gChrh2J|Q z#ZYm~f)9V^{pf-Va-W%nXSU%i7qMoerZNV z9BV{>lZVD2WKMvzCyE!w%2RuoA1W=irmR}WVFq|zL$0FOky8a zDZi~bs8I;Dt5v=>3?`_k(e8Y(F zMTa+mVv84p?r}v9c%8?eTm!l~#zO2B?fkwU1>AyKixE^7%a4faR_5x=TVSnL+hqH& zWgQylf~i7BnSn5a5>*RCA5JNFP^&$8iHI7w&h0xBjpF8V>+l6Gb-L(^l!B-_z1T1! zYHXGp;t`FS_=XE76qtX~+Q^q2BQ#xBCDtU*k$A8)h z)>H#QcK;VhjC0*f0~0gPexp=_pkN=YR59}Q#00000 literal 16844 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 diff --git a/tests/flags.rs b/tests/flags.rs index 65dcb5fd..1384a97f 100644 --- a/tests/flags.rs +++ b/tests/flags.rs @@ -11,7 +11,6 @@ use std::ops::Deref; use std::path::Path; use std::path::PathBuf; -const GRAYSCALE: u8 = 0; const RGB: u8 = 2; const INDEXED: u8 = 3; const RGBA: u8 = 6; @@ -597,7 +596,7 @@ fn fix_errors() { } }; - assert_eq!(png.raw.ihdr.color_type.png_header_code(), GRAYSCALE); + assert_eq!(png.raw.ihdr.color_type.png_header_code(), INDEXED); assert_eq!(png.raw.ihdr.bit_depth, BitDepth::Eight); // Cannot check if pixels are equal because image crate cannot read corrupt (input) PNGs diff --git a/tests/regression.rs b/tests/regression.rs index 9382f27a..99a9938b 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -177,8 +177,8 @@ fn issue_52_05() { None, RGBA, BitDepth::Eight, - INDEXED, - BitDepth::One, + RGB, + BitDepth::Eight, ); }