From 8d79bf082e176a4a53a690d11f098059c5c45c9b Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 8 Oct 2026 22:23:51 +0000 Subject: [PATCH] Batch fix: the header test's RLE PSD fixture uses PackBits runs of at most 128 bytes The fixture wrote each row as one literal run of w bytes, which PackBits can't express past 128 (a 160-pixel row's header byte read as a repeat run). The old decoder clipped such rows silently; with the PSD fix in this batch an overrun is an error, as it should be, and the fixture now splits rows into valid runs. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01912WaK6Rmew3wxZuPyX7E8 --- crates/codecs/tests/header.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/codecs/tests/header.rs b/crates/codecs/tests/header.rs index 7b67478a..6ff12d08 100644 --- a/crates/codecs/tests/header.rs +++ b/crates/codecs/tests/header.rs @@ -55,15 +55,18 @@ fn psd(w: usize, h: usize, orientation: Option, rle: bool) -> Vec { b.extend_from_slice(&(rle as u16).to_be_bytes()); let plane = |c: usize| (0..w * h).map(move |i| ((i * (c + 3) * 11) % 256) as u8); if rle { - // every row one literal run of `w` bytes (w ≤ 128) + // every row as literal runs of at most 128 bytes (PackBits' longest) + let row_len = w + w.div_ceil(128); for _ in 0..3 * h { - b.extend_from_slice(&(w as u16 + 1).to_be_bytes()); + b.extend_from_slice(&(row_len as u16).to_be_bytes()); } for c in 0..3 { let p: Vec = plane(c).collect(); for row in p.chunks(w) { - b.push(w as u8 - 1); - b.extend_from_slice(row); + for run in row.chunks(128) { + b.push(run.len() as u8 - 1); + b.extend_from_slice(run); + } } } } else {