Add "full" image decode test to decoder.rs

This is a full QOI file decode routine, although the image it contains
is just one single blue pixel. I've added this because I finally found
the bug I've been hunting:

I'm using `tests/codec.rs` to load reference files and decode them, but
this is resulting in data size errors. There are 32 extra bytes coming
out of the decoder -- too much for the WIDTH x HEIGHT number of pixels,
and it happens to every image.

The cause is the 8-byte end marker. It is not properly detected by the
decoder and is instead used as additional data (probably QOI_OP_INDEX).
Since the decoder emits *pixels*, each of which are 4 bytes, we have 32
bytes of garbage data coming out of the decoder.

Bug found! Now to make the test pass...
This commit is contained in:
2025-10-13 10:05:31 -05:00
parent 0b2408bda1
commit 04f83a55d2

View File

@@ -666,4 +666,38 @@ mod test {
expected
);
}
/// Try decoding an image consisting of a single pixel.
#[test]
fn decode_1_pixel_image() {
let input: [u8; 26] = [
0x71, 0x6f, 0x69, 0x66, // 'qoif' magic bytes
0x00, 0x00, 0x00, 0x01, // u32 width
0x00, 0x00, 0x00, 0x01, // u32 height
0x03, // u8 channels (3 for RGB mode)
0x00, // u8 colorspace (0 for sRGB w/ linear alpha)
// One single blue pixel, QOI_OP_RGB
0xFE, 0x00, 0x00, 0xFF,
// footer
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01
];
let mut decoder = Decoder::try_new(input.into_iter())
.expect("Failed to initialize decoder from byte array");
// Check the metadata
assert_eq!(decoder.width, 1);
assert_eq!(decoder.height, 1);
assert_eq!(decoder.channels, 3);
assert_eq!(decoder.colorspace, 0);
// Grab the one single pixel and check that it's solid blue.
let pixel = decoder.next().expect("Couldn't get pixel from decoder");
assert_eq!(pixel, PixelRGBA::new(0, 0, 255, 255));
// Assert that there are no more pixels.
let pixel = decoder.next();
assert!(pixel.is_none());
}
}