use crate::{ImageSize, ResamplingFunction};
pub(crate) fn plan_intermediate_sizes(
src: ImageSize,
dst: ImageSize,
function: ResamplingFunction,
) -> Vec<ImageSize> {
let max_ratio = function
.get_resampling_filter::<f32>()
.min_kernel_size
.max(1.5)
.min(4.0) as f64;
if max_ratio == f64::MAX {
return Vec::new();
}
let steps_w = if dst.width > src.width {
let ratio = dst.width as f64 / src.width as f64;
(ratio.log2() / max_ratio.log2()).ceil() as usize
} else {
0
};
let steps_h = if dst.height > src.height {
let ratio = dst.height as f64 / src.height as f64;
(ratio.log2() / max_ratio.log2()).ceil() as usize
} else {
0
};
let steps = steps_w.max(steps_h);
if steps <= 1 {
return Vec::new();
}
let mut sizes = Vec::with_capacity(steps - 1);
for i in 1..steps {
let t = i as f64 / steps as f64;
let w = if dst.width > src.width {
(src.width as f64 * (dst.width as f64 / src.width as f64).powf(t)).round() as usize
} else {
dst.width
};
let h = if dst.height > src.height {
(src.height as f64 * (dst.height as f64 / src.height as f64).powf(t)).round() as usize
} else {
dst.height
};
let w = w.max(src.width).min(dst.width);
let h = h.max(src.height).min(dst.height);
sizes.push(ImageSize::new(w, h));
}
sizes.dedup_by(|a, b| a.width == b.width && a.height == b.height);
sizes
}