Tweak some naming
This commit is contained in:
parent
8d75a6acfe
commit
eef5633786
15 changed files with 62 additions and 64 deletions
|
|
@ -13,7 +13,7 @@ pub use zopfli_oxipng::deflate as zopfli_deflate;
|
||||||
|
|
||||||
/// DEFLATE algorithms supported by oxipng (for use in [`Options`][crate::Options])
|
/// DEFLATE algorithms supported by oxipng (for use in [`Options`][crate::Options])
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum Deflaters {
|
pub enum Deflater {
|
||||||
/// Use libdeflater.
|
/// Use libdeflater.
|
||||||
Libdeflater {
|
Libdeflater {
|
||||||
/// Which compression level to use on the file (0-12)
|
/// Which compression level to use on the file (0-12)
|
||||||
|
|
@ -29,7 +29,7 @@ pub enum Deflaters {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deflaters {
|
impl Deflater {
|
||||||
pub(crate) fn deflate(self, data: &[u8], max_size: Option<usize>) -> PngResult<Vec<u8>> {
|
pub(crate) fn deflate(self, data: &[u8], max_size: Option<usize>) -> PngResult<Vec<u8>> {
|
||||||
let compressed = match self {
|
let compressed = match self {
|
||||||
Self::Libdeflater { compression } => deflate(data, compression, max_size)?,
|
Self::Libdeflater { compression } => deflate(data, compression, max_size)?,
|
||||||
|
|
@ -45,7 +45,7 @@ impl Deflaters {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Deflaters {
|
impl Display for Deflater {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use std::sync::{
|
||||||
|
|
||||||
#[cfg(feature = "parallel")]
|
#[cfg(feature = "parallel")]
|
||||||
use crossbeam_channel::{Receiver, Sender, unbounded};
|
use crossbeam_channel::{Receiver, Sender, unbounded};
|
||||||
use deflate::Deflaters;
|
use deflate::Deflater;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
@ -50,7 +50,7 @@ impl Candidate {
|
||||||
pub(crate) struct Evaluator {
|
pub(crate) struct Evaluator {
|
||||||
deadline: Arc<Deadline>,
|
deadline: Arc<Deadline>,
|
||||||
filters: IndexSet<FilterStrategy>,
|
filters: IndexSet<FilterStrategy>,
|
||||||
deflater: Deflaters,
|
deflater: Deflater,
|
||||||
optimize_alpha: bool,
|
optimize_alpha: bool,
|
||||||
final_round: bool,
|
final_round: bool,
|
||||||
nth: AtomicUsize,
|
nth: AtomicUsize,
|
||||||
|
|
@ -68,7 +68,7 @@ impl Evaluator {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
deadline: Arc<Deadline>,
|
deadline: Arc<Deadline>,
|
||||||
filters: IndexSet<FilterStrategy>,
|
filters: IndexSet<FilterStrategy>,
|
||||||
deflater: Deflaters,
|
deflater: Deflater,
|
||||||
optimize_alpha: bool,
|
optimize_alpha: bool,
|
||||||
final_round: bool,
|
final_round: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use log::{debug, trace, warn};
|
||||||
use rgb::{RGB16, RGBA8};
|
use rgb::{RGB16, RGBA8};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Deflaters, Options, PngResult,
|
Deflater, Options, PngResult,
|
||||||
colors::{BitDepth, ColorType},
|
colors::{BitDepth, ColorType},
|
||||||
deflate::{crc32, inflate},
|
deflate::{crc32, inflate},
|
||||||
display_chunks::DISPLAY_CHUNKS,
|
display_chunks::DISPLAY_CHUNKS,
|
||||||
|
|
@ -276,7 +276,7 @@ pub fn extract_icc(iccp: &Chunk) -> Option<Vec<u8>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make an iCCP chunk by compressing the ICC profile
|
/// Make an iCCP chunk by compressing the ICC profile
|
||||||
pub fn make_iccp(icc: &[u8], deflater: Deflaters, max_size: Option<usize>) -> PngResult<Chunk> {
|
pub fn make_iccp(icc: &[u8], deflater: Deflater, max_size: Option<usize>) -> PngResult<Chunk> {
|
||||||
let mut compressed = deflater.deflate(icc, max_size)?;
|
let mut compressed = deflater.deflate(icc, max_size)?;
|
||||||
let mut data = Vec::with_capacity(compressed.len() + 5);
|
let mut data = Vec::with_capacity(compressed.len() + 5);
|
||||||
data.extend(b"icc"); // Profile name - generally unused, can be anything
|
data.extend(b"icc"); // Profile name - generally unused, can be anything
|
||||||
|
|
@ -348,7 +348,7 @@ pub fn preprocess_chunks(aux_chunks: &mut Vec<Chunk>, opts: &mut Options) {
|
||||||
} else if opts.idat_recoding {
|
} else if opts.idat_recoding {
|
||||||
// Try recompressing the profile
|
// Try recompressing the profile
|
||||||
let cur_len = aux_chunks[iccp_idx].data.len();
|
let cur_len = aux_chunks[iccp_idx].data.len();
|
||||||
if let Ok(iccp) = make_iccp(&icc, opts.deflate, Some(cur_len - 1)) {
|
if let Ok(iccp) = make_iccp(&icc, opts.deflater, Some(cur_len - 1)) {
|
||||||
debug!(
|
debug!(
|
||||||
"Recompressed iCCP chunk: {} ({} bytes decrease)",
|
"Recompressed iCCP chunk: {} ({} bytes decrease)",
|
||||||
iccp.data.len(),
|
iccp.data.len(),
|
||||||
|
|
|
||||||
34
src/lib.rs
34
src/lib.rs
|
|
@ -43,7 +43,7 @@ pub use rgb::{RGB16, RGBA8};
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
colors::{BitDepth, ColorType},
|
colors::{BitDepth, ColorType},
|
||||||
deflate::Deflaters,
|
deflate::Deflater,
|
||||||
error::PngError,
|
error::PngError,
|
||||||
filters::{FilterStrategy, RowFilter},
|
filters::{FilterStrategy, RowFilter},
|
||||||
headers::StripChunks,
|
headers::StripChunks,
|
||||||
|
|
@ -146,7 +146,7 @@ impl RawImage {
|
||||||
/// Add an ICC profile for the image
|
/// Add an ICC profile for the image
|
||||||
pub fn add_icc_profile(&mut self, data: &[u8]) {
|
pub fn add_icc_profile(&mut self, data: &[u8]) {
|
||||||
// Compress with fastest compression level - will be recompressed during optimization
|
// Compress with fastest compression level - will be recompressed during optimization
|
||||||
let deflater = Deflaters::Libdeflater { compression: 1 };
|
let deflater = Deflater::Libdeflater { compression: 1 };
|
||||||
if let Ok(iccp) = make_iccp(data, deflater, None) {
|
if let Ok(iccp) = make_iccp(data, deflater, None) {
|
||||||
self.aux_chunks.push(iccp);
|
self.aux_chunks.push(iccp);
|
||||||
}
|
}
|
||||||
|
|
@ -422,16 +422,16 @@ fn optimize_raw(
|
||||||
// 8 is a little slower but not noticeably when used only for reductions (o3 and higher)
|
// 8 is a little slower but not noticeably when used only for reductions (o3 and higher)
|
||||||
// 9 is not appreciably better than 8
|
// 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
|
// 10 and higher are quite slow - good for filters but only good for reductions if matching the main zc level
|
||||||
let compression = match opts.deflate {
|
let compression = match opts.deflater {
|
||||||
Deflaters::Libdeflater { compression } => {
|
Deflater::Libdeflater { compression } => {
|
||||||
if opts.fast_evaluation { 7 } else { 8 }.min(compression)
|
if opts.fast_evaluation { 7 } else { 8 }.min(compression)
|
||||||
}
|
}
|
||||||
_ => 8,
|
_ => 8,
|
||||||
};
|
};
|
||||||
let eval_deflater = Deflaters::Libdeflater { compression };
|
let eval_deflater = Deflater::Libdeflater { compression };
|
||||||
// If only one filter is selected, use this for evaluations
|
// If only one filter is selected, use this for evaluations
|
||||||
let eval_filters = if opts.filter.len() == 1 {
|
let eval_filters = if opts.filters.len() == 1 {
|
||||||
opts.filter.clone()
|
opts.filters.clone()
|
||||||
} else {
|
} else {
|
||||||
// None and Bigrams work well together, especially for alpha reductions
|
// None and Bigrams work well together, especially for alpha reductions
|
||||||
indexset! {FilterStrategy::NONE, FilterStrategy::Bigrams}
|
indexset! {FilterStrategy::NONE, FilterStrategy::Bigrams}
|
||||||
|
|
@ -442,7 +442,7 @@ fn optimize_raw(
|
||||||
eval_filters.clone(),
|
eval_filters.clone(),
|
||||||
eval_deflater,
|
eval_deflater,
|
||||||
false,
|
false,
|
||||||
opts.deflate == eval_deflater,
|
opts.deflater == eval_deflater,
|
||||||
);
|
);
|
||||||
let mut new_image = perform_reductions(image.clone(), opts, &deadline, &eval);
|
let mut new_image = perform_reductions(image.clone(), opts, &deadline, &eval);
|
||||||
let eval_result = eval.get_best_candidate();
|
let eval_result = eval.get_best_candidate();
|
||||||
|
|
@ -467,7 +467,7 @@ fn optimize_raw(
|
||||||
eval_filters,
|
eval_filters,
|
||||||
eval_deflater,
|
eval_deflater,
|
||||||
);
|
);
|
||||||
(result?, opts.deflate)
|
(result?, opts.deflater)
|
||||||
} else {
|
} else {
|
||||||
// If idat_recoding is off and reductions were attempted but ended up choosing the baseline,
|
// If idat_recoding is off and reductions were attempted but ended up choosing the baseline,
|
||||||
// we should still check if the evaluator compressed the baseline smaller than the original.
|
// we should still check if the evaluator compressed the baseline smaller than the original.
|
||||||
|
|
@ -492,9 +492,9 @@ fn perform_trials(
|
||||||
max_size: Option<usize>,
|
max_size: Option<usize>,
|
||||||
mut eval_result: Option<Candidate>,
|
mut eval_result: Option<Candidate>,
|
||||||
eval_filters: IndexSet<FilterStrategy>,
|
eval_filters: IndexSet<FilterStrategy>,
|
||||||
eval_deflater: Deflaters,
|
eval_deflater: Deflater,
|
||||||
) -> Option<Candidate> {
|
) -> Option<Candidate> {
|
||||||
let mut filters = opts.filter.clone();
|
let mut filters = opts.filters.clone();
|
||||||
let fast_eval = opts.fast_evaluation && (filters.len() > 1 || eval_result.is_some());
|
let fast_eval = opts.fast_evaluation && (filters.len() > 1 || eval_result.is_some());
|
||||||
if fast_eval {
|
if fast_eval {
|
||||||
// Perform a fast evaluation of selected filters followed by a single main compression trial
|
// Perform a fast evaluation of selected filters followed by a single main compression trial
|
||||||
|
|
@ -511,7 +511,7 @@ fn perform_trials(
|
||||||
filters,
|
filters,
|
||||||
eval_deflater,
|
eval_deflater,
|
||||||
opts.optimize_alpha,
|
opts.optimize_alpha,
|
||||||
opts.deflate == eval_deflater,
|
opts.deflater == eval_deflater,
|
||||||
);
|
);
|
||||||
if let Some(result) = &eval_result {
|
if let Some(result) = &eval_result {
|
||||||
eval.set_best_size(result.estimated_output_size);
|
eval.set_best_size(result.estimated_output_size);
|
||||||
|
|
@ -527,9 +527,9 @@ fn perform_trials(
|
||||||
|
|
||||||
if result.idat_data.is_none() {
|
if result.idat_data.is_none() {
|
||||||
// Compress with the main deflater
|
// Compress with the main deflater
|
||||||
debug!("Trying filter {} with {}", result.filter, opts.deflate);
|
debug!("Trying filter {} with {}", result.filter, opts.deflater);
|
||||||
let (data, _) = image.filter_image(result.filter_used.clone(), opts.optimize_alpha);
|
let (data, _) = image.filter_image(result.filter_used.clone(), opts.optimize_alpha);
|
||||||
match opts.deflate.deflate(&data, max_size) {
|
match opts.deflater.deflate(&data, max_size) {
|
||||||
Ok(idat_data) => {
|
Ok(idat_data) => {
|
||||||
result.estimated_output_size = result.image.estimated_output_size(&idat_data);
|
result.estimated_output_size = result.image.estimated_output_size(&idat_data);
|
||||||
result.idat_data = Some(idat_data);
|
result.idat_data = Some(idat_data);
|
||||||
|
|
@ -557,8 +557,8 @@ fn perform_trials(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Trying {} filters with {}", filters.len(), opts.deflate);
|
debug!("Trying {} filters with {}", filters.len(), opts.deflater);
|
||||||
let eval = Evaluator::new(deadline, filters, opts.deflate, opts.optimize_alpha, true);
|
let eval = Evaluator::new(deadline, filters, opts.deflater, opts.optimize_alpha, true);
|
||||||
if let Some(max_size) = max_size {
|
if let Some(max_size) = max_size {
|
||||||
eval.set_best_size(max_size);
|
eval.set_best_size(max_size);
|
||||||
}
|
}
|
||||||
|
|
@ -650,7 +650,7 @@ fn recompress_frames(
|
||||||
let image = PngImage::new(ihdr, &frame.data)?;
|
let image = PngImage::new(ihdr, &frame.data)?;
|
||||||
let (filtered, _) = image.filter_image(filter.clone(), opts.optimize_alpha);
|
let (filtered, _) = image.filter_image(filter.clone(), opts.optimize_alpha);
|
||||||
let max_size = Some(frame.data.len() - 1);
|
let max_size = Some(frame.data.len() - 1);
|
||||||
if let Ok(data) = opts.deflate.deflate(&filtered, max_size) {
|
if let Ok(data) = opts.deflater.deflate(&filtered, max_size) {
|
||||||
debug!(
|
debug!(
|
||||||
"Recompressed fdAT #{:<2}: {} ({} bytes decrease)",
|
"Recompressed fdAT #{:<2}: {} ({} bytes decrease)",
|
||||||
i,
|
i,
|
||||||
|
|
|
||||||
10
src/main.rs
10
src/main.rs
|
|
@ -26,7 +26,7 @@ use clap::ArgMatches;
|
||||||
mod cli;
|
mod cli;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use log::{Level, LevelFilter, error, warn};
|
use log::{Level, LevelFilter, error, warn};
|
||||||
use oxipng::{Deflaters, FilterStrategy, InFile, Options, OutFile, PngError, StripChunks};
|
use oxipng::{Deflater, FilterStrategy, InFile, Options, OutFile, PngError, StripChunks};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
use crate::cli::DISPLAY_CHUNKS;
|
use crate::cli::DISPLAY_CHUNKS;
|
||||||
|
|
@ -198,7 +198,7 @@ fn parse_opts_into_struct(
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(x) = matches.get_one::<IndexSet<u8>>("filters") {
|
if let Some(x) = matches.get_one::<IndexSet<u8>>("filters") {
|
||||||
opts.filter = x
|
opts.filters = x
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&f| match f {
|
.map(|&f| match f {
|
||||||
0..=4 => FilterStrategy::Basic(f.try_into().unwrap()),
|
0..=4 => FilterStrategy::Basic(f.try_into().unwrap()),
|
||||||
|
|
@ -336,12 +336,12 @@ fn parse_opts_into_struct(
|
||||||
#[cfg(feature = "zopfli")]
|
#[cfg(feature = "zopfli")]
|
||||||
if matches.get_flag("zopfli") {
|
if matches.get_flag("zopfli") {
|
||||||
let iterations = *matches.get_one::<i64>("iterations").unwrap();
|
let iterations = *matches.get_one::<i64>("iterations").unwrap();
|
||||||
opts.deflate = Deflaters::Zopfli {
|
opts.deflater = Deflater::Zopfli {
|
||||||
iterations: NonZeroU8::new(iterations as u8).unwrap(),
|
iterations: NonZeroU8::new(iterations as u8).unwrap(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if let (Deflaters::Libdeflater { compression }, Some(x)) =
|
if let (Deflater::Libdeflater { compression }, Some(x)) =
|
||||||
(&mut opts.deflate, matches.get_one::<i64>("compression"))
|
(&mut opts.deflater, matches.get_one::<i64>("compression"))
|
||||||
{
|
{
|
||||||
*compression = *x as u8;
|
*compression = *x as u8;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use indexmap::{IndexSet, indexset};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
deflate::Deflaters, filters::FilterStrategy, headers::StripChunks, interlace::Interlacing,
|
deflate::Deflater, filters::FilterStrategy, headers::StripChunks, interlace::Interlacing,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Write destination for [`optimize`][crate::optimize].
|
/// Write destination for [`optimize`][crate::optimize].
|
||||||
|
|
@ -99,7 +99,7 @@ pub struct Options {
|
||||||
/// Which `FilterStrategy` to try on the file
|
/// Which `FilterStrategy` to try on the file
|
||||||
///
|
///
|
||||||
/// Default: `None,Sub,Entropy,Bigrams`
|
/// Default: `None,Sub,Entropy,Bigrams`
|
||||||
pub filter: IndexSet<FilterStrategy>,
|
pub filters: IndexSet<FilterStrategy>,
|
||||||
/// Whether to change the interlacing type of the file.
|
/// Whether to change the interlacing type of the file.
|
||||||
///
|
///
|
||||||
/// These are the interlacing types avaliable:
|
/// These are the interlacing types avaliable:
|
||||||
|
|
@ -148,7 +148,7 @@ pub struct Options {
|
||||||
#[cfg_attr(feature = "zopfli", doc = "(e.g. Zopfli)")]
|
#[cfg_attr(feature = "zopfli", doc = "(e.g. Zopfli)")]
|
||||||
///
|
///
|
||||||
/// Default: `Libdeflater`
|
/// Default: `Libdeflater`
|
||||||
pub deflate: Deflaters,
|
pub deflater: Deflater,
|
||||||
/// Whether to use fast evaluation to pick the best filter
|
/// Whether to use fast evaluation to pick the best filter
|
||||||
///
|
///
|
||||||
/// Default: `true`
|
/// Default: `true`
|
||||||
|
|
@ -187,16 +187,16 @@ impl Options {
|
||||||
// The following methods make assumptions that they are operating
|
// The following methods make assumptions that they are operating
|
||||||
// on an `Options` struct generated by the `default` method.
|
// on an `Options` struct generated by the `default` method.
|
||||||
fn apply_preset_0(mut self) -> Self {
|
fn apply_preset_0(mut self) -> Self {
|
||||||
self.filter.clear();
|
self.filters.clear();
|
||||||
if let Deflaters::Libdeflater { compression } = &mut self.deflate {
|
if let Deflater::Libdeflater { compression } = &mut self.deflater {
|
||||||
*compression = 5;
|
*compression = 5;
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_preset_1(mut self) -> Self {
|
fn apply_preset_1(mut self) -> Self {
|
||||||
self.filter.clear();
|
self.filters.clear();
|
||||||
if let Deflaters::Libdeflater { compression } = &mut self.deflate {
|
if let Deflater::Libdeflater { compression } = &mut self.deflater {
|
||||||
*compression = 10;
|
*compression = 10;
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
|
|
@ -208,7 +208,7 @@ impl Options {
|
||||||
|
|
||||||
fn apply_preset_3(mut self) -> Self {
|
fn apply_preset_3(mut self) -> Self {
|
||||||
self.fast_evaluation = false;
|
self.fast_evaluation = false;
|
||||||
self.filter = indexset! {
|
self.filters = indexset! {
|
||||||
FilterStrategy::NONE,
|
FilterStrategy::NONE,
|
||||||
FilterStrategy::Bigrams,
|
FilterStrategy::Bigrams,
|
||||||
FilterStrategy::BigEnt,
|
FilterStrategy::BigEnt,
|
||||||
|
|
@ -218,7 +218,7 @@ impl Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_preset_4(mut self) -> Self {
|
fn apply_preset_4(mut self) -> Self {
|
||||||
if let Deflaters::Libdeflater { compression } = &mut self.deflate {
|
if let Deflater::Libdeflater { compression } = &mut self.deflater {
|
||||||
*compression = 12;
|
*compression = 12;
|
||||||
}
|
}
|
||||||
self.apply_preset_3()
|
self.apply_preset_3()
|
||||||
|
|
@ -226,19 +226,19 @@ impl Options {
|
||||||
|
|
||||||
fn apply_preset_5(mut self) -> Self {
|
fn apply_preset_5(mut self) -> Self {
|
||||||
self.fast_evaluation = false;
|
self.fast_evaluation = false;
|
||||||
self.filter.insert(FilterStrategy::UP);
|
self.filters.insert(FilterStrategy::UP);
|
||||||
self.filter.insert(FilterStrategy::MinSum);
|
self.filters.insert(FilterStrategy::MinSum);
|
||||||
self.filter.insert(FilterStrategy::BigEnt);
|
self.filters.insert(FilterStrategy::BigEnt);
|
||||||
self.filter.insert(FilterStrategy::Brute);
|
self.filters.insert(FilterStrategy::Brute);
|
||||||
if let Deflaters::Libdeflater { compression } = &mut self.deflate {
|
if let Deflater::Libdeflater { compression } = &mut self.deflater {
|
||||||
*compression = 12;
|
*compression = 12;
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_preset_6(mut self) -> Self {
|
fn apply_preset_6(mut self) -> Self {
|
||||||
self.filter.insert(FilterStrategy::AVERAGE);
|
self.filters.insert(FilterStrategy::AVERAGE);
|
||||||
self.filter.insert(FilterStrategy::PAETH);
|
self.filters.insert(FilterStrategy::PAETH);
|
||||||
self.apply_preset_5()
|
self.apply_preset_5()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -249,7 +249,7 @@ impl Default for Options {
|
||||||
Self {
|
Self {
|
||||||
fix_errors: false,
|
fix_errors: false,
|
||||||
force: false,
|
force: false,
|
||||||
filter: indexset! {
|
filters: indexset! {
|
||||||
FilterStrategy::NONE,
|
FilterStrategy::NONE,
|
||||||
FilterStrategy::SUB,
|
FilterStrategy::SUB,
|
||||||
FilterStrategy::Entropy,
|
FilterStrategy::Entropy,
|
||||||
|
|
@ -264,7 +264,7 @@ impl Default for Options {
|
||||||
idat_recoding: true,
|
idat_recoding: true,
|
||||||
scale_16: false,
|
scale_16: false,
|
||||||
strip: StripChunks::None,
|
strip: StripChunks::None,
|
||||||
deflate: Deflaters::Libdeflater { compression: 11 },
|
deflater: Deflater::Libdeflater { compression: 11 },
|
||||||
fast_evaluation: true,
|
fast_evaluation: true,
|
||||||
timeout: None,
|
timeout: None,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{ColorType, Deadline, Deflaters, Options, evaluate::Evaluator, png::PngImage};
|
use crate::{ColorType, Deadline, Deflater, Options, evaluate::Evaluator, png::PngImage};
|
||||||
|
|
||||||
pub mod alpha;
|
pub mod alpha;
|
||||||
use crate::alpha::*;
|
use crate::alpha::*;
|
||||||
|
|
@ -21,8 +21,8 @@ pub(crate) fn perform_reductions(
|
||||||
|
|
||||||
// At low compression levels, skip some transformations which are less likely to be effective
|
// At low compression levels, skip some transformations which are less likely to be effective
|
||||||
// This currently affects optimization presets 0-2
|
// This currently affects optimization presets 0-2
|
||||||
let cheap = match opts.deflate {
|
let cheap = match opts.deflater {
|
||||||
Deflaters::Libdeflater { compression } => compression < 12 && opts.fast_evaluation,
|
Deflater::Libdeflater { compression } => compression < 12 && opts.fast_evaluation,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ const RGBA: u8 = 6;
|
||||||
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
let options = oxipng::Options {
|
let options = oxipng::Options {
|
||||||
force: true,
|
force: true,
|
||||||
filter: indexset! {FilterStrategy::NONE},
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
|
|
@ -32,8 +31,7 @@ fn test_it_converts(
|
||||||
|
|
||||||
let (output, mut opts) = get_opts(&input);
|
let (output, mut opts) = get_opts(&input);
|
||||||
let png = PngData::new(&input, &opts).unwrap();
|
let png = PngData::new(&input, &opts).unwrap();
|
||||||
opts.filter = IndexSet::new();
|
opts.filters = indexset! {filter};
|
||||||
opts.filter.insert(filter);
|
|
||||||
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
||||||
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in);
|
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ fn get_opts(input: &Path) -> (OutFile, Options) {
|
||||||
let options = Options {
|
let options = Options {
|
||||||
force: true,
|
force: true,
|
||||||
fast_evaluation: false,
|
fast_evaluation: false,
|
||||||
filter: indexset! {FilterStrategy::NONE},
|
filters: indexset! {FilterStrategy::NONE},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
|
|
@ -409,7 +409,7 @@ fn interlaced_0_to_1_other_filter_mode() {
|
||||||
let input = PathBuf::from("tests/files/interlaced_0_to_1_other_filter_mode.png");
|
let input = PathBuf::from("tests/files/interlaced_0_to_1_other_filter_mode.png");
|
||||||
let (output, mut opts) = get_opts(&input);
|
let (output, mut opts) = get_opts(&input);
|
||||||
opts.interlace = Some(Interlacing::Adam7);
|
opts.interlace = Some(Interlacing::Adam7);
|
||||||
opts.filter = indexset! {FilterStrategy::PAETH};
|
opts.filters = indexset! {FilterStrategy::PAETH};
|
||||||
|
|
||||||
test_it_converts_callbacks(
|
test_it_converts_callbacks(
|
||||||
input,
|
input,
|
||||||
|
|
@ -649,7 +649,7 @@ fn scale_16() {
|
||||||
fn zopfli_mode() {
|
fn zopfli_mode() {
|
||||||
let input = PathBuf::from("tests/files/zopfli_mode.png");
|
let input = PathBuf::from("tests/files/zopfli_mode.png");
|
||||||
let (output, mut opts) = get_opts(&input);
|
let (output, mut opts) = get_opts(&input);
|
||||||
opts.deflate = Deflaters::Zopfli {
|
opts.deflater = Deflater::Zopfli {
|
||||||
iterations: NonZeroU8::new(15).unwrap(),
|
iterations: NonZeroU8::new(15).unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
let options = oxipng::Options {
|
let options = oxipng::Options {
|
||||||
force: true,
|
force: true,
|
||||||
fast_evaluation: false,
|
fast_evaluation: false,
|
||||||
filter: indexset! {FilterStrategy::NONE},
|
filters: indexset! {FilterStrategy::NONE},
|
||||||
interlace: None,
|
interlace: None,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const INDEXED: u8 = 3;
|
||||||
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
let options = oxipng::Options {
|
let options = oxipng::Options {
|
||||||
force: true,
|
force: true,
|
||||||
filter: indexset! {FilterStrategy::NONE},
|
filters: indexset! {FilterStrategy::NONE},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use oxipng::{internal_tests::*, *};
|
||||||
fn get_opts() -> Options {
|
fn get_opts() -> Options {
|
||||||
Options {
|
Options {
|
||||||
force: true,
|
force: true,
|
||||||
filter: indexset! {FilterStrategy::NONE},
|
filters: indexset! {FilterStrategy::NONE},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
let options = oxipng::Options {
|
let options = oxipng::Options {
|
||||||
force: true,
|
force: true,
|
||||||
fast_evaluation: false,
|
fast_evaluation: false,
|
||||||
filter: indexset! {FilterStrategy::NONE},
|
filters: indexset! {FilterStrategy::NONE},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const RGBA: u8 = 6;
|
||||||
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
let options = oxipng::Options {
|
let options = oxipng::Options {
|
||||||
force: true,
|
force: true,
|
||||||
filter: indexset! {FilterStrategy::NONE},
|
filters: indexset! {FilterStrategy::NONE},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
(OutFile::from_path(input.with_extension("out.png")), options)
|
(OutFile::from_path(input.with_extension("out.png")), options)
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ fn test_it_converts(
|
||||||
|
|
||||||
let (output, mut opts) = get_opts(&input);
|
let (output, mut opts) = get_opts(&input);
|
||||||
let png = PngData::new(&input, &opts).unwrap();
|
let png = PngData::new(&input, &opts).unwrap();
|
||||||
opts.filter = indexset! {filter};
|
opts.filters = indexset! {filter};
|
||||||
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
||||||
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in);
|
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue