diff --git a/images/hi.qoi b/images/hi.qoi new file mode 100644 index 0000000..21ac898 Binary files /dev/null and b/images/hi.qoi differ diff --git a/images/hi.xcf b/images/hi.xcf new file mode 100644 index 0000000..0de368f Binary files /dev/null and b/images/hi.xcf differ diff --git a/images/large.qoi b/images/large.qoi new file mode 100644 index 0000000..9ebd755 Binary files /dev/null and b/images/large.qoi differ diff --git a/images/large.xcf b/images/large.xcf new file mode 100644 index 0000000..8fd96d9 Binary files /dev/null and b/images/large.xcf differ diff --git a/images/sheep.qoi b/images/sheep.qoi new file mode 100644 index 0000000..cc4ea45 Binary files /dev/null and b/images/sheep.qoi differ diff --git a/images/sheep.xcf b/images/sheep.xcf new file mode 100644 index 0000000..15175fa Binary files /dev/null and b/images/sheep.xcf differ diff --git a/src/qoi.rs b/src/qoi.rs index 0d82689..bb776c6 100644 --- a/src/qoi.rs +++ b/src/qoi.rs @@ -14,7 +14,7 @@ use crate::{ }; // https://qoiformat.org/qoi-specification.pdf -const image: &[u8; 288] = include_bytes!("../images/Image.qoi"); +const image: &[u8; 852] = include_bytes!("../images/sheep.qoi"); const BUFFER_SIZE: usize = 64; #[derive(Debug, uDebug)] @@ -57,30 +57,31 @@ pub fn draw_image( display.set_window( position, Position { - x: position.x + width, - y: position.y + height, + x: position.x + width - 1, + y: position.y + height - 1, }, ); - let qoi_iter = QoiIterator::from(iter, serial); - let mut prev_pixels = [0u8; 64]; + let qoi_iter = QoiIterator::from(iter, serial, width * height); - let mut chunks = qoi_iter.array_chunks::(); - while let Some(array) = chunks.next() { - let mut colors = [0u8; BUFFER_SIZE * 2]; - for (i, pixel) in array.iter().enumerate() { - let [c1, c2] = pixel.as_color().bytes; - colors[i * 2] = c1; - colors[i * 2 + 1] = c2; - } - display.write(Writeable::Data(&colors)); - } - if let Some(remainder) = chunks.into_remainder() { - for pixel in remainder { - let [c1, c2] = pixel.as_color().bytes; - display.write(Writeable::Data(&[c1, c2])); - } + // let mut chunks = qoi_iter.array_chunks::(); + // while let Some(array) = chunks.next() { + // let mut colors = [0u8; BUFFER_SIZE * 2]; + // for (i, pixel) in array.iter().enumerate() { + // let [c1, c2] = pixel.as_color().bytes; + // colors[i * 2] = c1; + // colors[i * 2 + 1] = c2; + // } + // display.write(Writeable::Data(&colors)); + // display.delay.delay_ms(100); + // } + let mut counter = 0u32; + for pixel in qoi_iter { + let [c1, c2] = pixel.as_color().bytes; + display.write(Writeable::Data(&[c1, c2])); + counter += 1; } + ufmt::uwriteln!(serial, "Counter: {}", counter).unwrap(); // display.draw_rect( // position, @@ -104,12 +105,15 @@ struct QoiIterator<'a> { last_pixel: Rgb565, last_alpha: u8, repeat: u8, + expected_colors: u16, + parsed_colors: u16, } impl<'a> QoiIterator<'a> { fn from( bytes: Iter<'a, u8>, serial: &'a mut Usart, Pin, CoreClock>, + expected: u16, ) -> Self { QoiIterator { inner: bytes, @@ -119,6 +123,8 @@ impl<'a> QoiIterator<'a> { last_pixel: Rgb565(0, 0, 0), last_alpha: 255, repeat: 0, + expected_colors: expected, + parsed_colors: 0, } } } @@ -127,6 +133,11 @@ impl<'a> Iterator for QoiIterator<'a> { type Item = Rgb565; fn next(&mut self) -> Option { + if self.parsed_colors >= self.expected_colors { + return None; + } + self.parsed_colors += 1; + if self.repeat > 0 { self.repeat -= 1; return Some(self.last_pixel); @@ -137,19 +148,19 @@ impl<'a> Iterator for QoiIterator<'a> { let green = self.inner.next().unwrap(); let blue = self.inner.next().unwrap(); let alpha = self.inner.next().unwrap(); - ufmt::uwriteln!(self.serial, "RGBA: {} {} {} {}", red, green, blue, alpha).unwrap(); + // ufmt::uwriteln!(self.serial, "RGBA: {} {} {} {}", red, green, blue, alpha).unwrap(); (Rgb565(*red, *green, *blue), *alpha) } else if *byte == 0b11111110 { let red = self.inner.next().unwrap(); let green = self.inner.next().unwrap(); let blue = self.inner.next().unwrap(); - ufmt::uwriteln!(self.serial, "RGB: {} {} {}", red, green, blue).unwrap(); + // ufmt::uwriteln!(self.serial, "RGB: {} {} {}", red, green, blue).unwrap(); (Rgb565(*red, *green, *blue), self.last_alpha) } else { let tag = (0b11000000 & byte) >> 6; let data = 0b00111111 & byte; - ufmt::uwriteln!(self.serial, "Tag: {}", tag).unwrap(); + // ufmt::uwriteln!(self.serial, "Tag: {}", tag).unwrap(); if tag == 0 { ( @@ -160,14 +171,14 @@ impl<'a> Iterator for QoiIterator<'a> { let dr = ((0b110000 & data) >> 4) as i8 - 2; let dg = ((0b001100 & data) >> 2) as i8 - 2; let db = (0b000011 & data) as i8 - 2; - ufmt::uwriteln!( - self.serial, - "Diffs: {} {} {}", - ((0b110000 & data) >> 4), - ((0b001100 & data) >> 2), - (0b000011 & data) - ) - .unwrap(); + // ufmt::uwriteln!( + // self.serial, + // "Diffs: {} {} {}", + // ((0b110000 & data) >> 4), + // ((0b001100 & data) >> 2), + // (0b000011 & data) + // ) + // .unwrap(); ( Rgb565( (self.last_pixel.0 as i8).wrapping_add(dr) as u8, @@ -183,36 +194,33 @@ impl<'a> Iterator for QoiIterator<'a> { let db_dg = (0b00001111 & second) as i8 - 8; let dr = dr_dg + dg; let db = db_dg + dg; - ufmt::uwriteln!( - self.serial, - "Last: {} {} {}", - self.last_pixel.0 as i8, - self.last_pixel.1 as i8, - self.last_pixel.2 as i8 - ) - .unwrap(); - ufmt::uwriteln!(self.serial, "Values: {} {} {}", dr_dg, dg, db_dg).unwrap(); - ufmt::uwriteln!(self.serial, "Diffs: {} {} {}", dr, dg, db).unwrap(); - ufmt::uwriteln!( - self.serial, - "Res: {} {} {}", - self.last_pixel.0 as i8 + dr, - self.last_pixel.1 as i8 + dg, - self.last_pixel.2 as i8 + db - ) - .unwrap(); + + let a = self.last_pixel.0 as i8; + let b = self.last_pixel.1 as i8; + let c = self.last_pixel.2 as i8; + // ufmt::uwriteln!(self.serial, "Hello there! {} {} {}", a, b, c).unwrap(); + // ufmt::uwriteln!(self.serial, "Values: {} {} {}", dr_dg, dg, db_dg).unwrap(); + // ufmt::uwriteln!(self.serial, "Diffs: {} {} {}", dr, dg, db).unwrap(); + // ufmt::uwriteln!( + // self.serial, + // "Res: {} {} {}", + // self.last_pixel.0 as i8 + dr, + // self.last_pixel.1 as i8 + dg, + // self.last_pixel.2 as i8 + db + // ) + // .unwrap(); ( Rgb565( - (self.last_pixel.0 as i8).wrapping_add(dr) as u8, - (self.last_pixel.1 as i8).wrapping_add(dg) as u8, - (self.last_pixel.2 as i8).wrapping_add(db) as u8, + (self.last_pixel.0 as i8 + dr) as u8, + (self.last_pixel.1 as i8 + dg) as u8, + (self.last_pixel.2 as i8 + db) as u8, ), self.last_alpha, ) } else if tag == 3 { // QOI_OP_RUN self.repeat = data; - ufmt::uwriteln!(self.serial, "Repeat: {}", self.repeat).unwrap(); + // ufmt::uwriteln!(self.serial, "Repeat: {}", self.repeat).unwrap(); (self.last_pixel, self.last_alpha) } else { (Rgb565::green(), 255) @@ -224,16 +232,16 @@ impl<'a> Iterator for QoiIterator<'a> { ((color.0 as u32 * 3 + color.1 as u32 * 5 + color.2 as u32 * 7 + alpha as u32 * 11) % 64) as usize; - ufmt::uwriteln!( - self.serial, - "Color: {} {} {} {}, Hash: {}", - color.0, - color.1, - color.2, - alpha, - hash - ) - .unwrap(); + // ufmt::uwriteln!( + // self.serial, + // "Color: {} {} {} {}, Hash: {}", + // color.0, + // color.1, + // color.2, + // alpha, + // hash + // ) + // .unwrap(); self.prev_pixels[hash] = color; Some(color) } else {