Allow baseline to pass through evaluator

This commit is contained in:
Andrew 2022-11-16 18:10:19 +13:00 committed by Josh Holmer
parent 9b5353f0c6
commit affd86a2e5
2 changed files with 13 additions and 18 deletions

View file

@ -22,9 +22,10 @@ use std::sync::Arc;
const STD_COMPRESSION: u8 = 5;
const STD_FILTERS: [RowFilter; 2] = [RowFilter::None, RowFilter::MinSum];
struct Candidate {
image: PngData,
filter: RowFilter,
pub struct Candidate {
pub image: PngData,
pub filter: RowFilter,
pub is_reduction: bool,
// first wins tie-breaker
nth: usize,
}
@ -72,21 +73,17 @@ impl Evaluator {
/// Wait for all evaluations to finish and return smallest reduction
/// Or `None` if all reductions were worse than baseline.
#[cfg(feature = "parallel")]
fn get_best_candidate(self) -> Option<Candidate> {
pub fn get_best_candidate(self) -> Option<Candidate> {
let (eval_send, eval_recv) = self.eval_channel;
drop(eval_send); // disconnect the sender, breaking the loop in the thread
eval_recv.into_iter().min_by_key(Candidate::cmp_key)
}
#[cfg(not(feature = "parallel"))]
fn get_best_candidate(self) -> Option<Candidate> {
pub fn get_best_candidate(self) -> Option<Candidate> {
self.eval_best_candidate.into_inner()
}
pub fn get_result(self) -> Option<PngData> {
self.get_best_candidate().map(|candidate| candidate.image)
}
/// Set baseline image. It will be used only to measure minimum compression level required
pub fn set_baseline(&self, image: Arc<PngImage>) {
self.try_image_inner(image, false)
@ -123,17 +120,13 @@ impl Evaluator {
&best_candidate_size,
) {
best_candidate_size.set_min(idat_data.len());
// ignore baseline images after this point
if !is_reduction {
return;
}
// the rest is shipped to the evavluation/collection thread
let new = Candidate {
image: PngData {
idat_data,
raw: Arc::clone(&image),
},
filter,
is_reduction,
nth,
};

View file

@ -506,9 +506,9 @@ fn optimize_png(
eval.set_baseline(png.raw.clone());
}
perform_reductions(png.raw.clone(), opts, &deadline, &eval);
let reduction_occurred = if let Some(result) = eval.get_result() {
*png = result;
true
let reduction_occurred = if let Some(result) = eval.get_best_candidate() {
*png = result.image;
result.is_reduction
} else {
false
};
@ -593,9 +593,11 @@ fn optimize_png(
opts.filter,
png.idat_data.len()
);
} else if reduction_occurred {
} else {
*png = original_png;
}
} else if png.idat_data.len() > idat_original_size {
*png = original_png;
}
perform_strip(png, opts);