Commit b3f5dda
committed
fix(deringing): widen slope math to i32 to eliminate wrap risk
preprocess_deringing computed fslope and lslope in bare i16 arithmetic:
let mut fslope = (f1 - f2).max(MAX_SAMPLE - f1);
let mut lslope = (l1 - l2).max(MAX_SAMPLE - l1);
For the current in-contract use (level-shifted samples in -128..=127,
with overshoot values up to MAX_SAMPLE + 31 = 158 written back into the
block by a previous run), the largest magnitudes are well within i16
range: 158 - (-128) = 286 fits easily. But the subtractions are i16 -
i16, so pathological callers — or a future switch to wider sample types
— would wrap in release builds (panic in debug). That class of bug is
exactly what the mozilla/mozjpeg#453 i16-SIMD-DCT overflow documented in
CLAUDE.md warns about, except here in the scalar preprocessing step.
Widen the subtractions to i32 and saturate back to i16 via clamp. The
pattern matches what catmull_rom() already does at src/deringing.rs:121
for its tangent computation. For in-contract data the clamp is a no-op;
for out-of-contract data it clamps instead of wrapping.
zenjpeg sidesteps the whole issue by operating on f32 samples
(zenjpeg/zenjpeg/src/encode/deringing.rs:113). Moving mozjpeg-rs to
f32 would be the architecturally clean answer but would break the
byte-parity property we depend on with C mozjpeg, so widen-to-i32 is
the minimal-churn defensive fix.
Verified bit-exact with C mozjpeg via tests/parity_benchmark after the
change:
Baseline Q55-Q95: 0.00% delta, 0.00% max dev (all 6 levels)
Progressive Q55-Q95: 0.00% delta, 0.00% max dev (all 6 levels)
Trellis modes: -0.05% to -0.80% (unchanged from pre-fix numbers)
Max Compression: -0.72% to +0.21% (unchanged from pre-fix numbers)
All 7 deringing unit tests pass.1 parent 4d2a452 commit b3f5dda
1 file changed
Lines changed: 12 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
223 | 223 | | |
224 | 224 | | |
225 | 225 | | |
226 | | - | |
227 | | - | |
228 | | - | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
229 | 238 | | |
230 | 239 | | |
231 | 240 | | |
| |||
0 commit comments