Use single compression level
This commit is contained in:
parent
15a9b4a3e7
commit
9b5353f0c6
3 changed files with 29 additions and 84 deletions
|
|
@ -1,5 +1,3 @@
|
|||
use indexmap::IndexSet;
|
||||
|
||||
mod deflater;
|
||||
pub use deflater::crc32;
|
||||
pub use deflater::deflate;
|
||||
|
|
@ -17,8 +15,8 @@ pub use zopfli_oxipng::deflate as zopfli_deflate;
|
|||
pub enum Deflaters {
|
||||
/// Use libdeflater.
|
||||
Libdeflater {
|
||||
/// Which compression levels to try on the file (1-12)
|
||||
compression: IndexSet<u8>,
|
||||
/// Which compression level to use on the file (1-12)
|
||||
compression: u8,
|
||||
},
|
||||
#[cfg(feature = "zopfli")]
|
||||
/// Use the better but slower Zopfli implementation
|
||||
|
|
@ -29,3 +27,5 @@ pub enum Deflaters {
|
|||
iterations: NonZeroU8,
|
||||
},
|
||||
}
|
||||
|
||||
impl Copy for Deflaters {}
|
||||
|
|
|
|||
92
src/lib.rs
92
src/lib.rs
|
|
@ -47,7 +47,7 @@ pub use crate::deflate::Deflaters;
|
|||
pub use crate::error::PngError;
|
||||
pub use crate::filters::RowFilter;
|
||||
pub use crate::headers::Headers;
|
||||
pub use indexmap::{IndexMap, IndexSet};
|
||||
pub use indexmap::{indexset, IndexMap, IndexSet};
|
||||
|
||||
mod atomicmin;
|
||||
mod colors;
|
||||
|
|
@ -232,8 +232,7 @@ impl Options {
|
|||
self.idat_recoding = false;
|
||||
self.filter.clear();
|
||||
if let Deflaters::Libdeflater { compression } = &mut self.deflate {
|
||||
compression.clear();
|
||||
compression.insert(5);
|
||||
*compression = 5;
|
||||
}
|
||||
self.use_heuristics = true;
|
||||
self
|
||||
|
|
@ -242,8 +241,7 @@ impl Options {
|
|||
fn apply_preset_1(mut self) -> Self {
|
||||
self.filter.clear();
|
||||
if let Deflaters::Libdeflater { compression } = &mut self.deflate {
|
||||
compression.clear();
|
||||
compression.insert(10);
|
||||
*compression = 10;
|
||||
}
|
||||
self.use_heuristics = true;
|
||||
self
|
||||
|
|
@ -263,45 +261,23 @@ impl Options {
|
|||
|
||||
fn apply_preset_4(mut self) -> Self {
|
||||
if let Deflaters::Libdeflater { compression } = &mut self.deflate {
|
||||
compression.clear();
|
||||
compression.insert(12);
|
||||
*compression = 12;
|
||||
}
|
||||
self.apply_preset_3()
|
||||
}
|
||||
|
||||
fn apply_preset_5(mut self) -> Self {
|
||||
if let Deflaters::Libdeflater { compression } = &mut self.deflate {
|
||||
compression.clear();
|
||||
for i in 9..=12 {
|
||||
compression.insert(i);
|
||||
}
|
||||
}
|
||||
self.apply_preset_3()
|
||||
fn apply_preset_5(self) -> Self {
|
||||
self.apply_preset_4()
|
||||
}
|
||||
|
||||
fn apply_preset_6(mut self) -> Self {
|
||||
if let Deflaters::Libdeflater { compression } = &mut self.deflate {
|
||||
compression.clear();
|
||||
for i in 1..=12 {
|
||||
compression.insert(i);
|
||||
}
|
||||
}
|
||||
self.apply_preset_3()
|
||||
fn apply_preset_6(self) -> Self {
|
||||
self.apply_preset_4()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Options {
|
||||
fn default() -> Options {
|
||||
// Default settings based on -o 2 from the CLI interface
|
||||
let mut filter = IndexSet::new();
|
||||
filter.insert(RowFilter::None);
|
||||
filter.insert(RowFilter::MinSum);
|
||||
let mut compression = IndexSet::new();
|
||||
compression.insert(11);
|
||||
// We always need NoOp to be present
|
||||
let mut alphas = IndexSet::new();
|
||||
alphas.insert(AlphaOptim::NoOp);
|
||||
|
||||
Options {
|
||||
backup: false,
|
||||
check: false,
|
||||
|
|
@ -309,16 +285,16 @@ impl Default for Options {
|
|||
fix_errors: false,
|
||||
force: false,
|
||||
preserve_attrs: false,
|
||||
filter,
|
||||
filter: indexset! {RowFilter::None, RowFilter::MinSum},
|
||||
interlace: None,
|
||||
alphas,
|
||||
alphas: IndexSet::new(),
|
||||
bit_depth_reduction: true,
|
||||
color_type_reduction: true,
|
||||
palette_reduction: true,
|
||||
grayscale_reduction: true,
|
||||
idat_recoding: true,
|
||||
strip: Headers::None,
|
||||
deflate: Deflaters::Libdeflater { compression },
|
||||
deflate: Deflaters::Libdeflater { compression: 11 },
|
||||
use_heuristics: false,
|
||||
timeout: None,
|
||||
}
|
||||
|
|
@ -539,48 +515,20 @@ fn optimize_png(
|
|||
|
||||
if opts.idat_recoding || reduction_occurred {
|
||||
// Go through selected permutations and determine the best
|
||||
let combinations = if let Deflaters::Libdeflater { compression } = &opts.deflate {
|
||||
filter.len() * compression.len()
|
||||
} else {
|
||||
filter.len()
|
||||
};
|
||||
let mut results: Vec<TrialOptions> = Vec::with_capacity(combinations);
|
||||
let mut results: Vec<TrialOptions> = Vec::with_capacity(filter.len());
|
||||
|
||||
for f in &filter {
|
||||
if let Deflaters::Libdeflater { compression } = &opts.deflate {
|
||||
for zc in compression {
|
||||
results.push(TrialOptions {
|
||||
filter: *f,
|
||||
compression: *zc,
|
||||
});
|
||||
if deadline.passed() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Zopfli has no additional options.
|
||||
results.push(TrialOptions {
|
||||
filter: *f,
|
||||
compression: 0,
|
||||
});
|
||||
}
|
||||
|
||||
if deadline.passed() {
|
||||
break;
|
||||
}
|
||||
results.push(TrialOptions {
|
||||
filter: *f,
|
||||
compression: match opts.deflate {
|
||||
Deflaters::Libdeflater { compression } => compression,
|
||||
_ => 0,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
info!("Trying: {} combinations", results.len());
|
||||
|
||||
let filters: IndexMap<RowFilter, Vec<u8>> = filter
|
||||
.par_iter()
|
||||
.with_max_len(1)
|
||||
.map(|f| {
|
||||
let png = png.clone();
|
||||
(*f, png.raw.filter_image(*f))
|
||||
})
|
||||
.collect();
|
||||
|
||||
let original_len = original_png.idat_data.len();
|
||||
let added_interlacing = opts.interlace == Some(1) && original_png.raw.ihdr.interlaced == 0;
|
||||
|
||||
|
|
@ -590,7 +538,7 @@ fn optimize_png(
|
|||
if deadline.passed() {
|
||||
return None;
|
||||
}
|
||||
let filtered = &filters[&trial.filter];
|
||||
let filtered = &png.raw.filter_image(trial.filter);
|
||||
let new_idat = match opts.deflate {
|
||||
Deflaters::Libdeflater { .. } => {
|
||||
deflate::deflate(filtered, trial.compression, &best_size)
|
||||
|
|
|
|||
13
src/main.rs
13
src/main.rs
|
|
@ -184,14 +184,11 @@ fn main() {
|
|||
)
|
||||
.arg(
|
||||
Arg::new("compression")
|
||||
.help("zlib compression levels (1-12) - Default: 12")
|
||||
.help("zlib compression level (1-12) - Default: 11")
|
||||
.long("zc")
|
||||
.takes_value(true)
|
||||
.value_name("levels")
|
||||
.validator(|x| match parse_numeric_range_opts(x, 1, 12) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(_) => Err("Invalid option for compression".to_owned()),
|
||||
})
|
||||
.value_name("level")
|
||||
.value_parser(1..=12)
|
||||
.conflicts_with("zopfli"),
|
||||
)
|
||||
.arg(
|
||||
|
|
@ -541,8 +538,8 @@ fn parse_opts_into_struct(
|
|||
opts.deflate = Deflaters::Zopfli { iterations };
|
||||
}
|
||||
} else if let Deflaters::Libdeflater { compression } = &mut opts.deflate {
|
||||
if let Some(x) = matches.value_of("compression") {
|
||||
*compression = parse_numeric_range_opts(x, 1, 12).unwrap();
|
||||
if let Some(x) = matches.get_one::<i64>("compression") {
|
||||
*compression = *x as u8;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue