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,
|
prev_pixel: PixelRGBA,
|
||||||
|
|
||||||
bytes: I,
|
bytes: I,
|
||||||
|
run_len: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <I> Decoder <I> where I: Iterator<Item=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,
|
a: 255,
|
||||||
},
|
},
|
||||||
bytes,
|
bytes,
|
||||||
|
run_len: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +62,8 @@ impl <I> Decoder <I> where I: Iterator<Item=u8> {
|
|||||||
prev_pixel: PixelRGBA {
|
prev_pixel: PixelRGBA {
|
||||||
r: 0, g: 0, b: 0, a: 255,
|
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],
|
back_buffer: [PixelRGBA::zero(); 64],
|
||||||
prev_pixel,
|
prev_pixel,
|
||||||
bytes,
|
bytes,
|
||||||
|
run_len: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,6 +95,10 @@ impl<'input, I> Iterator for Decoder<I> where I: Iterator<Item=u8> {
|
|||||||
type Item = PixelRGBA;
|
type Item = PixelRGBA;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
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()?;
|
let byte = self.bytes.next()?;
|
||||||
match byte {
|
match byte {
|
||||||
QOI_OP_RGB => {
|
QOI_OP_RGB => {
|
||||||
@@ -138,11 +146,19 @@ impl<'input, I> Iterator for Decoder<I> where I: Iterator<Item=u8> {
|
|||||||
a: self.prev_pixel.a
|
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")}
|
_ => {panic!("bad op code")}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|||||||
Reference in New Issue
Block a user