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:
20
src/main.rs
20
src/main.rs
@@ -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)]
|
||||
|
||||
Reference in New Issue
Block a user