diff --git a/images/sheep.qoi b/images/sheep.qoi index cc4ea45..ea32e12 100644 Binary files a/images/sheep.qoi and b/images/sheep.qoi differ diff --git a/src/main.rs b/src/main.rs index 19afeab..8b32267 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ #![feature(iter_array_chunks)] #![feature(const_slice_make_iter)] #![feature(slice_as_chunks)] +#![feature(generic_const_exprs)] use atmega_hal::{ Adc, Eeprom, Usart, diff --git a/src/qoi.rs b/src/qoi.rs index 46cfc70..b65011b 100644 --- a/src/qoi.rs +++ b/src/qoi.rs @@ -62,8 +62,7 @@ macro_rules! non_bss_statics {( // static ref SHEEP: [u8] = *include_bytes!("../images/sheep.qoi"); // // static ref LARGE: [u8] = *include_bytes!("../images/large.qoi"); // } -static SHEEP: [u8; 852] = *include_bytes!("../images/sheep.qoi"); -static LARGE: [u8; 1966] = *include_bytes!("../images/large.qoi"); +static SHEEP: [u8; 446] = *include_bytes!("../images/sheep.qoi"); // const LARGE_C1: [u8; 512] = LARGE.as_chunks().0[0]; // const LARGE_C2: [u8; 512] = LARGE.as_chunks().0[1]; @@ -123,56 +122,86 @@ pub fn draw_image( next(&mut iter)?, next(&mut iter)?, ]) as u16; - let channels = next(&mut iter)?; - let colorspace = next(&mut iter)?; + let _channels = next(&mut iter)?; + let _colorspace = next(&mut iter)?; ufmt::uwriteln!(serial, "Successfully read QOI header").unwrap(); display.set_window( position, Position { - x: position.x + width - 1, - y: position.y + height - 1, + x: position.x + 191, + y: position.y + 191, }, ); - let qoi_iter = QoiIterator::from(&mut iter, serial, width * height); + let qoi_iter = QoiIterator::from(&mut iter, width * height); + let scale_iter = ScaleIterator { + qoi: qoi_iter, + last_row: [Rgb565::yellow(); 64], + scale_factor: 3, + width: width as usize, + counter: 0, + index: 0, + }; - // 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)); - // } let mut counter = 0u32; - for pixel in qoi_iter { + for pixel in scale_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, - // Position { - // x: position.x + 100, - // y: position.y + 100, - // }, - // Rgb565::green().as_color(), - // ); Ok(()) } else { Err(QoiErr::InvalidMagicNumber) } } +struct ScaleIterator<'a> { + qoi: QoiIterator<'a>, + last_row: [Rgb565; 64], + width: usize, + scale_factor: usize, + counter: usize, + index: usize, +} + +impl<'a> Iterator for ScaleIterator<'a> { + type Item = Rgb565; + + fn next(&mut self) -> Option { + if self.index >= self.width * self.scale_factor { + self.counter = (self.counter + 1) % self.scale_factor; + self.index = 0; + } + let index_div = self.index / self.scale_factor; + + if self.counter % self.scale_factor == 0 { + if (self.index % self.scale_factor) == 0 { + if let Some(pixel) = self.qoi.next() { + self.last_row[index_div] = pixel; + self.index += 1; + Some(pixel) + } else { + None + } + } else { + let pixel = self.last_row[index_div]; + self.index += 1; + Some(pixel) + } + } else { + let pixel = self.last_row[index_div]; + self.index += 1; + Some(pixel) + } + } +} + struct QoiIterator<'a> { inner: &'a mut dyn Iterator, - serial: &'a mut Usart, Pin, CoreClock>, prev_pixels: [Rgb565; 64], last_pixel: Rgb565, repeat: u8, @@ -181,14 +210,9 @@ struct QoiIterator<'a> { } impl<'a> QoiIterator<'a> { - fn from( - bytes: &'a mut dyn Iterator, - serial: &'a mut Usart, Pin, CoreClock>, - expected: u16, - ) -> Self { + fn from(bytes: &'a mut dyn Iterator, expected: u16) -> Self { QoiIterator { inner: bytes, - serial, prev_pixels: [Rgb565(0, 255, 0); 64], last_pixel: Rgb565(0, 0, 0), repeat: 0, @@ -203,7 +227,6 @@ impl<'a> Iterator for QoiIterator<'a> { fn next(&mut self) -> Option { if self.parsed_colors >= self.expected_colors { - ufmt::uwriteln!(self.serial, "Reached expected").unwrap(); return None; } self.parsed_colors += 1; @@ -218,35 +241,22 @@ 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) - // .unwrap(); Rgb565(red, green, blue) } else if byte == 0b11111110 { let red = self.inner.next()?; let green = self.inner.next()?; let blue = self.inner.next()?; - // ufmt::uwriteln!(self.serial, "RGB: {} {} {}", red, green, blue).unwrap(); Rgb565(red, green, blue) } else { let tag = (0b11000000 & byte) >> 6; let data = 0b00111111 & byte; - // ufmt::uwriteln!(self.serial, "Tag: {}", tag).unwrap(); - if tag == 0 { self.prev_pixels[data as usize] } else if tag == 1 { 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(); Rgb565( (self.last_pixel.0 as i8).wrapping_add(dr) as u8, (self.last_pixel.1 as i8).wrapping_add(dg) as u8, @@ -260,20 +270,6 @@ impl<'a> Iterator for QoiIterator<'a> { let dr = dr_dg + dg; let db = db_dg + dg; - 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 + dr) as u8, (self.last_pixel.1 as i8 + dg) as u8, @@ -282,7 +278,6 @@ impl<'a> Iterator for QoiIterator<'a> { } else if tag == 3 { // QOI_OP_RUN self.repeat = data; - // ufmt::uwriteln!(self.serial, "Repeat: {}", self.repeat).unwrap(); self.last_pixel } else { Rgb565::green() @@ -293,20 +288,9 @@ impl<'a> Iterator for QoiIterator<'a> { ((color.0 as u32 * 3 + color.1 as u32 * 5 + color.2 as u32 * 7 + 255 as u32 * 11) % 64) as usize; - // ufmt::uwriteln!( - // self.serial, - // "Color: {} {} {} {}, Hash: {}", - // color.0, - // color.1, - // color.2, - // alpha, - // hash - // ) - // .unwrap(); self.prev_pixels[hash] = color; Some(color) } else { - ufmt::uwriteln!(self.serial, "End reached").unwrap(); None } }