From b05daa503e03b41d9b334964454cc8ccadeeb3f6 Mon Sep 17 00:00:00 2001 From: Robert Garrett Date: Tue, 7 May 2024 09:48:35 -0500 Subject: [PATCH] Fix: wrapping, store previous pixel value The wrapping wasn't working properly, clearly, but I forgot about the previous pixel entirely. I'll add some more explicit tests for the previous pixel behavior. I think it's still broken for RGB and RGBA, because I'm dumb. --- src/main.rs | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/main.rs b/src/main.rs index 98cabe6..ddb907a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -134,29 +134,33 @@ where return Some(self.back_buffer[idx]); } QOI_OP_DIFF => { - let dr = ((byte & 0b0011_0000) >> 4) - 2; - let dg = ((byte & 0b0000_1100) >> 2) - 2; - let db = (byte & 0b0000_0011) - 2; - return Some(PixelRGBA { - r: self.prev_pixel.r + dr, - g: self.prev_pixel.g + dg, - b: self.prev_pixel.b + db, + let dr = ((byte & 0b0011_0000) >> 4).wrapping_sub(2); + let dg = ((byte & 0b0000_1100) >> 2).wrapping_sub(2); + let db = (byte & 0b0000_0011).wrapping_sub(2); + let result = PixelRGBA { + r: self.prev_pixel.r.wrapping_add(dr), + g: self.prev_pixel.g.wrapping_add(dg), + b: self.prev_pixel.b.wrapping_add(db), a: self.prev_pixel.a, - }); + }; + self.prev_pixel = result; + return Some(result); } QOI_OP_LUMA => { - let dg = (byte & !QOI_OP_SMALL_MASK) - 32; + let dg = (byte & !QOI_OP_SMALL_MASK).wrapping_sub(32); let packed = self.bytes.next()?; - let drdg = ((packed & 0b1111_0000) >> 4) - 8; - let dbdg = (packed & 0b0000_1111) - 8; - let dr = drdg + dg; - let db = dbdg + dg; - return Some(PixelRGBA { - r: self.prev_pixel.r + dr, - g: self.prev_pixel.g + dg, - b: self.prev_pixel.b + db, + let drdg = ((packed & 0b1111_0000) >> 4).wrapping_sub(8); + let dbdg = (packed & 0b0000_1111).wrapping_sub(8); + let dr = drdg.wrapping_add(dg); + let db = dbdg.wrapping_add(dg); + let result = PixelRGBA { + r: self.prev_pixel.r.wrapping_add(dr), + g: self.prev_pixel.g.wrapping_add(dg), + b: self.prev_pixel.b.wrapping_add(db), a: self.prev_pixel.a, - }); + }; + self.prev_pixel = result; + return Some(result); } QOI_OP_RUN => { self.run_len = byte & !QOI_OP_SMALL_MASK;