Tests for prev_pixel and backbuffer

Gotta check that the previous pixel is recorded and the backbuffer is
filled. There are errors in the decoder that revolve around this.
This commit is contained in:
2024-05-08 09:48:19 -05:00
parent 8b99642e4c
commit b9aa3cf28f

View File

@@ -84,7 +84,16 @@ where
run_len: 0,
}
}
pub(crate) fn peek_prev_pixel(&self) -> &PixelRGBA {
&self.prev_pixel
}
pub(crate) fn peek_backbuffer(&self, idx: usize) -> &PixelRGBA {
&self.back_buffer[idx]
}
}
mod codec_utils {
use super::PixelRGBA;
pub(crate) fn hash(pixel: PixelRGBA) -> u8 {
@@ -456,4 +465,89 @@ mod test {
let result: Vec<PixelRGBA> = decoder.collect();
assert_eq!(result, expected);
}
#[test]
fn decoder_prev_pixel_verify() {
let compressed = [
QOI_OP_RGB, 0x10, 0x10, 0x10,
QOI_OP_RGBA, 0x20, 0x20, 0x20, 0x20,
(QOI_OP_INDEX | 1),
(QOI_OP_DIFF | 0b0011_1111),
(QOI_OP_LUMA | 0b0011_111), 0b0011_1111,
(QOI_OP_RUN | 2),
QOI_OP_RGBA, 0xFF, 0xFF, 0xFF, 0xFF,
];
let expected = [
PixelRGBA::new(0, 0, 0, 0xFF), // init
PixelRGBA::new(0x10, 0x10, 0x10, 0xFF), // RGB
PixelRGBA::new(0x20, 0x20, 0x20, 0xFF), // RGBA
PixelRGBA::new(0, 0, 0, 0), // INDEX -- this doubles as a small test for the backbuffer operation
PixelRGBA::new(0x1, 0x1, 0x1, 0x0), // DIFF
PixelRGBA::new(0x27, 0x20, 0x27, 0x0), // LUMA
PixelRGBA::new(0x27, 0x20, 0x27, 0x0), // RUN 1
PixelRGBA::new(0x27, 0x20, 0x27, 0x0), // RUN 2
PixelRGBA::new(0x27, 0x20, 0x27, 0x0), // RUN 3
// final OP_RGBA is just to flush out the OP_RUN prev_pixel value
];
let mut decoder = Decoder::new(compressed.into_iter());
let mut result = Vec::<PixelRGBA>::new();
loop {
if let Some(_) = decoder.next() {
result.push(*decoder.peek_prev_pixel());
} else {
break;
}
}
assert_eq!(result, expected);
}
#[test]
fn decoder_backbuffer_verify() {
let compressed = [
QOI_OP_RGB, 0x10, 0x10, 0x10,
QOI_OP_RGBA, 0x20, 0x20, 0x20, 0x20,
(QOI_OP_INDEX | 1),
(QOI_OP_DIFF | 0b0011_1111),
(QOI_OP_LUMA | 0b0011_111), 0b0011_1111,
(QOI_OP_RUN | 2),
QOI_OP_RGBA, 0xFF, 0xFF, 0xFF, 0xFF,
];
// these are the indices where we're expecting each pixel to land.
// Each pixel gets put into this backbuffer as it's en/de-coded.
// For RGB and RGBA, it'll simply assign a value into the index.
// For INDEX, the write can be skipped, and the expected index will be
// the same as the one in the op code. By definition, it has to be.
// OP_DIFF & OP_LUMA need to consider the value in the backbuffer, as
// they'll be using it to compute the new pixel.
//
let indices = [
31, // Pix (16, 16, 16, 255)
0, // Pix (32, 32, 32, 32)
1, // Pix (0, 0, 0, 0)
3, // current state: Pix (1, 1, 1, 0)
38, // current state: Pix(39, 32, 39, 0)
38, // run x1
38, // run x2
38, // run x3
];
let mut decoder = Decoder::new(compressed.into_iter());
let mut iters = 0;
loop {
if let Some(pixel) = decoder.next() {
// pixel has been decompressed, so it should be in the backbuffer by this point
// query it out:
let stored_px = decoder.peek_backbuffer(indices[iters]);
// and compare it to the value returned from iteration
assert_eq!(&pixel, stored_px);
} else {
break;
}
iters += 1;
}
}
}