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 66138edb..2edd6dbf 100644 Binary files a/tests/files/grayscale_8_should_be_palette_4.png and b/tests/files/grayscale_8_should_be_palette_4.png differ 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, ); }