From 98c1bf08406d5cdd56132817878e84f1a5bc304d Mon Sep 17 00:00:00 2001 From: Sofia Date: Fri, 12 Sep 2025 20:18:47 +0300 Subject: [PATCH] Add scaling iterator --- images/sheep.qoi | Bin 852 -> 446 bytes src/main.rs | 1 + src/qoi.rs | 130 +++++++++++++++++++++-------------------------- 3 files changed, 58 insertions(+), 73 deletions(-) diff --git a/images/sheep.qoi b/images/sheep.qoi index cc4ea456ebc9a5924231188d345d6a812bfd557a..ea32e1226ddc216fdb6cb57d983765af1a9bb235 100644 GIT binary patch literal 446 zcmZXP%SyvQ6oyB9gMhE_GcfD36<@-gYr&QH1o6pAW^!qow4vPz;;nX3s}QUeq>$)2 zQxlX9ocX`}=a#v;yf{}%ok$$2)8?a91C?Rgeh(C$Oo3Qqs3Sa@F&t~A*`1)~NVUU) zHP$KSrt)gJpI9CfR%Rl&tengy0(+|X^{C_zOFuLUi==ENf@MM7V2v;{SC?vc?3IoX!q?qt?0 z$}kaFVY~;E(AT`7q%}gMB!wI4jf7I6-V(_6oMGpz`!;X+0q!D@ss5QZ&%1EH@lmz?L?x9F|sLQkbnV4tkW5~PU8Qba^ViipS}ihW3Uy16}d o?yUS_wss>i( 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 } }