From 1ca0394d4a1de6d77930e9ef95b6877400b1c713 Mon Sep 17 00:00:00 2001 From: Robert Garrett Date: Mon, 6 May 2024 14:36:27 -0500 Subject: [PATCH] Run length stored and checked during iteration The run length can simply be extracted and stored as part of the iterator state. For each iteration, check if the length is > 0, and emit more pixels until it isn't. Then continue the normal decode process. --- src/main.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7e88e12..e3b6ec1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,6 +33,7 @@ struct Decoder> { prev_pixel: PixelRGBA, bytes: I, + run_len: u8, } impl Decoder where I: Iterator { @@ -46,6 +47,7 @@ impl Decoder where I: Iterator { a: 255, }, bytes, + run_len: 0, } } @@ -60,7 +62,8 @@ impl Decoder where I: Iterator { prev_pixel: PixelRGBA { r: 0, g: 0, b: 0, a: 255, }, - bytes + bytes, + run_len: 0, } } @@ -71,6 +74,7 @@ impl Decoder where I: Iterator { back_buffer: [PixelRGBA::zero(); 64], prev_pixel, bytes, + run_len: 0, } } } @@ -91,6 +95,10 @@ impl<'input, I> Iterator for Decoder where I: Iterator { type Item = PixelRGBA; fn next(&mut self) -> Option { + if self.run_len > 0 { + self.run_len -= 1; + return Some(self.prev_pixel); + } else { let byte = self.bytes.next()?; match byte { QOI_OP_RGB => { @@ -138,10 +146,18 @@ impl<'input, I> Iterator for Decoder where I: Iterator { a: self.prev_pixel.a }); }, - QOI_OP_RUN => {todo!("Impl Decode QOI_OP_RUN")}, + QOI_OP_RUN => { + self.run_len = byte | 0b0011_1111; + // storage bias of -1, so a +1 should be on the end here. + // However, I'm immediately popping off the first occurrence + // and returning a PixelRGBA, so the count is also immediatly + // dropped by 1 + return Some(self.prev_pixel); + }, _ => {panic!("bad op code")} } } + } } #[cfg(test)]