use crate::{ pixel::Pixel, ser::{Sink, Source}, view::View, }; use std::ops::{Index, IndexMut}; #[derive(Debug, Clone)] pub struct Frame { pub size: (usize, usize), buffer: Vec>, } impl Frame { pub fn new(size: (usize, usize)) -> Self { Self { size, buffer: (0..size.0) .map(|_| (0..size.1).map(|_| Pixel::default()).collect()) .collect(), } } pub fn read(source: &mut impl Source, size: (usize, usize)) -> anyhow::Result { let mut frame = Frame::new(size); for y in 0..size.1 { for x in 0..size.0 { let pixel = source.get::()?; frame[(x, y)] = pixel; } } Ok(frame) } pub fn write(&self, sink: &mut impl Sink) -> anyhow::Result<()> { for y in 0..self.size.1 { for x in 0..self.size.0 { sink.put(self[(x, y)])?; } } Ok(()) } pub fn view<'a>(&'a self) -> View<&'a Frame> { View::new(self, (0, 0), self.size) } pub fn view_mut<'a>(&'a mut self) -> View<&'a mut Frame> { View::new(self, (0, 0), self.size) } pub fn view_area<'a>( &'a self, offset: (usize, usize), size: (usize, usize), ) -> View<&'a Frame> { View::new(self, offset, size) } pub fn view_area_mut<'a>( &'a mut self, offset: (usize, usize), size: (usize, usize), ) -> View<&'a mut Frame> { View::new(self, offset, size) } } impl Index<(usize, usize)> for Frame { type Output = Pixel; #[inline] fn index(&self, (x, y): (usize, usize)) -> &Self::Output { &self.buffer[x][y] } } impl IndexMut<(usize, usize)> for Frame { #[inline] fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output { &mut self.buffer[x][y] } }