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.
This commit is contained in:
2024-05-06 14:36:27 -05:00
parent ef4b31dab6
commit 1ca0394d4a

View File

@@ -33,6 +33,7 @@ struct Decoder<I: Iterator<Item=u8>> {
prev_pixel: PixelRGBA,
bytes: I,
run_len: u8,
}
impl <I> Decoder <I> where I: Iterator<Item=u8> {
@@ -46,6 +47,7 @@ impl <I> Decoder <I> where I: Iterator<Item=u8> {
a: 255,
},
bytes,
run_len: 0,
}
}
@@ -60,7 +62,8 @@ impl <I> Decoder <I> where I: Iterator<Item=u8> {
prev_pixel: PixelRGBA {
r: 0, g: 0, b: 0, a: 255,
},
bytes
bytes,
run_len: 0,
}
}
@@ -71,6 +74,7 @@ impl <I> Decoder <I> where I: Iterator<Item=u8> {
back_buffer: [PixelRGBA::zero(); 64],
prev_pixel,
bytes,
run_len: 0,
}
}
}
@@ -91,6 +95,10 @@ impl<'input, I> Iterator for Decoder<I> where I: Iterator<Item=u8> {
type Item = PixelRGBA;
fn next(&mut self) -> Option<Self::Item> {
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<I> where I: Iterator<Item=u8> {
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)]