Add scaling iterator
This commit is contained in:
parent
6e61b3df5c
commit
98c1bf0840
BIN
images/sheep.qoi
BIN
images/sheep.qoi
Binary file not shown.
@ -6,6 +6,7 @@
|
|||||||
#![feature(iter_array_chunks)]
|
#![feature(iter_array_chunks)]
|
||||||
#![feature(const_slice_make_iter)]
|
#![feature(const_slice_make_iter)]
|
||||||
#![feature(slice_as_chunks)]
|
#![feature(slice_as_chunks)]
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
|
||||||
use atmega_hal::{
|
use atmega_hal::{
|
||||||
Adc, Eeprom, Usart,
|
Adc, Eeprom, Usart,
|
||||||
|
130
src/qoi.rs
130
src/qoi.rs
@ -62,8 +62,7 @@ macro_rules! non_bss_statics {(
|
|||||||
// static ref SHEEP: [u8] = *include_bytes!("../images/sheep.qoi");
|
// static ref SHEEP: [u8] = *include_bytes!("../images/sheep.qoi");
|
||||||
// // static ref LARGE: [u8] = *include_bytes!("../images/large.qoi");
|
// // static ref LARGE: [u8] = *include_bytes!("../images/large.qoi");
|
||||||
// }
|
// }
|
||||||
static SHEEP: [u8; 852] = *include_bytes!("../images/sheep.qoi");
|
static SHEEP: [u8; 446] = *include_bytes!("../images/sheep.qoi");
|
||||||
static LARGE: [u8; 1966] = *include_bytes!("../images/large.qoi");
|
|
||||||
|
|
||||||
// const LARGE_C1: [u8; 512] = LARGE.as_chunks().0[0];
|
// const LARGE_C1: [u8; 512] = LARGE.as_chunks().0[0];
|
||||||
// const LARGE_C2: [u8; 512] = LARGE.as_chunks().0[1];
|
// const LARGE_C2: [u8; 512] = LARGE.as_chunks().0[1];
|
||||||
@ -123,56 +122,86 @@ pub fn draw_image<T: DelayNs, DCPin: PinOps, RSTPin: PinOps>(
|
|||||||
next(&mut iter)?,
|
next(&mut iter)?,
|
||||||
next(&mut iter)?,
|
next(&mut iter)?,
|
||||||
]) as u16;
|
]) as u16;
|
||||||
let channels = next(&mut iter)?;
|
let _channels = next(&mut iter)?;
|
||||||
let colorspace = next(&mut iter)?;
|
let _colorspace = next(&mut iter)?;
|
||||||
|
|
||||||
ufmt::uwriteln!(serial, "Successfully read QOI header").unwrap();
|
ufmt::uwriteln!(serial, "Successfully read QOI header").unwrap();
|
||||||
|
|
||||||
display.set_window(
|
display.set_window(
|
||||||
position,
|
position,
|
||||||
Position {
|
Position {
|
||||||
x: position.x + width - 1,
|
x: position.x + 191,
|
||||||
y: position.y + height - 1,
|
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::<BUFFER_SIZE>();
|
|
||||||
// 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;
|
let mut counter = 0u32;
|
||||||
for pixel in qoi_iter {
|
for pixel in scale_iter {
|
||||||
let [c1, c2] = pixel.as_color().bytes;
|
let [c1, c2] = pixel.as_color().bytes;
|
||||||
display.write(Writeable::Data(&[c1, c2]));
|
display.write(Writeable::Data(&[c1, c2]));
|
||||||
counter += 1;
|
counter += 1;
|
||||||
}
|
}
|
||||||
ufmt::uwriteln!(serial, "Counter: {}", counter).unwrap();
|
ufmt::uwriteln!(serial, "Counter: {}", counter).unwrap();
|
||||||
|
|
||||||
// display.draw_rect(
|
|
||||||
// position,
|
|
||||||
// Position {
|
|
||||||
// x: position.x + 100,
|
|
||||||
// y: position.y + 100,
|
|
||||||
// },
|
|
||||||
// Rgb565::green().as_color(),
|
|
||||||
// );
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(QoiErr::InvalidMagicNumber)
|
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<Self::Item> {
|
||||||
|
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> {
|
struct QoiIterator<'a> {
|
||||||
inner: &'a mut dyn Iterator<Item = u8>,
|
inner: &'a mut dyn Iterator<Item = u8>,
|
||||||
serial: &'a mut Usart<USART0, Pin<mode::Input, PD0>, Pin<mode::Output, PD1>, CoreClock>,
|
|
||||||
prev_pixels: [Rgb565; 64],
|
prev_pixels: [Rgb565; 64],
|
||||||
last_pixel: Rgb565,
|
last_pixel: Rgb565,
|
||||||
repeat: u8,
|
repeat: u8,
|
||||||
@ -181,14 +210,9 @@ struct QoiIterator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> QoiIterator<'a> {
|
impl<'a> QoiIterator<'a> {
|
||||||
fn from(
|
fn from(bytes: &'a mut dyn Iterator<Item = u8>, expected: u16) -> Self {
|
||||||
bytes: &'a mut dyn Iterator<Item = u8>,
|
|
||||||
serial: &'a mut Usart<USART0, Pin<mode::Input, PD0>, Pin<mode::Output, PD1>, CoreClock>,
|
|
||||||
expected: u16,
|
|
||||||
) -> Self {
|
|
||||||
QoiIterator {
|
QoiIterator {
|
||||||
inner: bytes,
|
inner: bytes,
|
||||||
serial,
|
|
||||||
prev_pixels: [Rgb565(0, 255, 0); 64],
|
prev_pixels: [Rgb565(0, 255, 0); 64],
|
||||||
last_pixel: Rgb565(0, 0, 0),
|
last_pixel: Rgb565(0, 0, 0),
|
||||||
repeat: 0,
|
repeat: 0,
|
||||||
@ -203,7 +227,6 @@ impl<'a> Iterator for QoiIterator<'a> {
|
|||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if self.parsed_colors >= self.expected_colors {
|
if self.parsed_colors >= self.expected_colors {
|
||||||
ufmt::uwriteln!(self.serial, "Reached expected").unwrap();
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.parsed_colors += 1;
|
self.parsed_colors += 1;
|
||||||
@ -218,35 +241,22 @@ impl<'a> Iterator for QoiIterator<'a> {
|
|||||||
let green = self.inner.next().unwrap();
|
let green = self.inner.next().unwrap();
|
||||||
let blue = self.inner.next().unwrap();
|
let blue = self.inner.next().unwrap();
|
||||||
let _alpha = self.inner.next().unwrap();
|
let _alpha = self.inner.next().unwrap();
|
||||||
// ufmt::uwriteln!(self.serial, "RGBA: {} {} {} {}", red, green, blue)
|
|
||||||
// .unwrap();
|
|
||||||
Rgb565(red, green, blue)
|
Rgb565(red, green, blue)
|
||||||
} else if byte == 0b11111110 {
|
} else if byte == 0b11111110 {
|
||||||
let red = self.inner.next()?;
|
let red = self.inner.next()?;
|
||||||
let green = self.inner.next()?;
|
let green = self.inner.next()?;
|
||||||
let blue = self.inner.next()?;
|
let blue = self.inner.next()?;
|
||||||
// ufmt::uwriteln!(self.serial, "RGB: {} {} {}", red, green, blue).unwrap();
|
|
||||||
Rgb565(red, green, blue)
|
Rgb565(red, green, blue)
|
||||||
} else {
|
} else {
|
||||||
let tag = (0b11000000 & byte) >> 6;
|
let tag = (0b11000000 & byte) >> 6;
|
||||||
let data = 0b00111111 & byte;
|
let data = 0b00111111 & byte;
|
||||||
|
|
||||||
// ufmt::uwriteln!(self.serial, "Tag: {}", tag).unwrap();
|
|
||||||
|
|
||||||
if tag == 0 {
|
if tag == 0 {
|
||||||
self.prev_pixels[data as usize]
|
self.prev_pixels[data as usize]
|
||||||
} else if tag == 1 {
|
} else if tag == 1 {
|
||||||
let dr = ((0b110000 & data) >> 4) as i8 - 2;
|
let dr = ((0b110000 & data) >> 4) as i8 - 2;
|
||||||
let dg = ((0b001100 & data) >> 2) as i8 - 2;
|
let dg = ((0b001100 & data) >> 2) as i8 - 2;
|
||||||
let db = (0b000011 & data) 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(
|
Rgb565(
|
||||||
(self.last_pixel.0 as i8).wrapping_add(dr) as u8,
|
(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.1 as i8).wrapping_add(dg) as u8,
|
||||||
@ -260,20 +270,6 @@ impl<'a> Iterator for QoiIterator<'a> {
|
|||||||
let dr = dr_dg + dg;
|
let dr = dr_dg + dg;
|
||||||
let db = db_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(
|
Rgb565(
|
||||||
(self.last_pixel.0 as i8 + dr) as u8,
|
(self.last_pixel.0 as i8 + dr) as u8,
|
||||||
(self.last_pixel.1 as i8 + dg) 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 {
|
} else if tag == 3 {
|
||||||
// QOI_OP_RUN
|
// QOI_OP_RUN
|
||||||
self.repeat = data;
|
self.repeat = data;
|
||||||
// ufmt::uwriteln!(self.serial, "Repeat: {}", self.repeat).unwrap();
|
|
||||||
self.last_pixel
|
self.last_pixel
|
||||||
} else {
|
} else {
|
||||||
Rgb565::green()
|
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)
|
((color.0 as u32 * 3 + color.1 as u32 * 5 + color.2 as u32 * 7 + 255 as u32 * 11)
|
||||||
% 64) as usize;
|
% 64) as usize;
|
||||||
|
|
||||||
// ufmt::uwriteln!(
|
|
||||||
// self.serial,
|
|
||||||
// "Color: {} {} {} {}, Hash: {}",
|
|
||||||
// color.0,
|
|
||||||
// color.1,
|
|
||||||
// color.2,
|
|
||||||
// alpha,
|
|
||||||
// hash
|
|
||||||
// )
|
|
||||||
// .unwrap();
|
|
||||||
self.prev_pixels[hash] = color;
|
self.prev_pixels[hash] = color;
|
||||||
Some(color)
|
Some(color)
|
||||||
} else {
|
} else {
|
||||||
ufmt::uwriteln!(self.serial, "End reached").unwrap();
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user