address review: crop padding is taken back only when the side would pass the cap

This commit is contained in:
Dylan M. Taylor
2026-11-03 23:12:57 +00:00
parent 462b2a51f0
commit 1c9bdff426
+9 -3
View File
@@ -782,10 +782,13 @@ pub struct Crop {
/// The largest side of a frame an output module writes (Resize is capped there too).
pub const MAX_OUTPUT_SIDE: i32 = 30_000;
/// Crop edges `a`/`b` of one axis of `side` pixels, each at most the side and padding at most
/// up to [`MAX_OUTPUT_SIDE`] in all.
/// Crop edges `a`/`b` of one axis of `side` pixels: padding is taken back only as far as keeps
/// the result within [`MAX_OUTPUT_SIDE`], so a mixed pair that stays inside the cap is kept as
/// saved. Each edge is also bounded (what the larger of the side and the cap allows), so the
/// arithmetic on them cannot overflow.
fn bound_edges(a: i32, b: i32, side: i32) -> (i32, i32) {
let (mut a, mut b) = (a.clamp(-MAX_OUTPUT_SIDE, side), b.clamp(-MAX_OUTPUT_SIDE, side));
let hi = side.max(MAX_OUTPUT_SIDE);
let (mut a, mut b) = (a.clamp(-MAX_OUTPUT_SIDE, hi), b.clamp(-MAX_OUTPUT_SIDE, hi));
let excess = i64::from(side) - i64::from(a) - i64::from(b) - i64::from(MAX_OUTPUT_SIDE);
if excess > 0 {
// Only padding (negative edges) grows the side: take back as much of it as needed.
@@ -1567,6 +1570,9 @@ mod tests {
assert_eq!(m(crop(-20_000, 0, -20_000, -1)).frame_size(100, 50, 1.0), (101, 30_000));
// Ordinary crops and pads are unchanged.
assert_eq!(crop(1, -2, 3, 4).edges(100, 50, 1.0), (1, -2, 3, 4));
// A mixed pair beyond the side that still ends within the cap is kept as saved (50 px).
assert_eq!(crop(0, 150, 0, -100).edges(100, 50, 1.0), (0, 150, 0, -100));
assert_eq!(m(crop(0, 150, 0, -100)).frame_size(100, 50, 1.0), (50, 50));
assert_eq!(m(crop(10, 10, 10, 10)).frame_size(100, 50, 1.0), (80, 30));
assert_eq!(m(crop(i32::MAX, 0, 0, 0)).frame_size(100, 50, 1.0), (100, 1));
}