use crate::{frame::Frame, pixel::Pixel}; use std::ops::{Index, IndexMut}; pub struct View { pub frame: T, pub offset: (usize, usize), pub size: (usize, usize), } impl View { pub fn new(frame: T, offset: (usize, usize), size: (usize, usize)) -> Self { Self { frame, offset, size, } } pub fn area(&self) -> usize { self.size.0 * self.size.1 } } impl View<&mut T> { pub fn split_mut_unsafe(&mut self) -> [Self; 2] { let vert = self.size.0 > self.size.1; [ Self { frame: unsafe { std::mem::transmute::<&mut T, &mut T>(&mut self.frame) }, offset: self.offset, size: if vert { (self.size.0 / 2, self.size.1) } else { (self.size.0, self.size.1 / 2) }, }, Self { frame: unsafe { std::mem::transmute::<&mut T, &mut T>(&mut self.frame) }, offset: if vert { (self.offset.0 + self.size.0 / 2, self.offset.1) } else { (self.offset.0, self.offset.1 + self.size.1 / 2) }, size: if vert { (self.size.0 - self.size.0 / 2, self.size.1) } else { (self.size.0, self.size.1 - self.size.1 / 2) }, }, ] } } impl View { pub fn split(&self) -> [Self; 2] { let vert = self.size.0 > self.size.1; [ Self { frame: self.frame, offset: self.offset, size: if vert { (self.size.0 / 2, self.size.1) } else { (self.size.0, self.size.1 / 2) }, }, Self { frame: self.frame, offset: if vert { (self.offset.0 + self.size.0 / 2, self.offset.1) } else { (self.offset.0, self.offset.1 + self.size.1 / 2) }, size: if vert { (self.size.0 - self.size.0 / 2, self.size.1) } else { (self.size.0, self.size.1 - self.size.1 / 2) }, }, ] } } impl> View<&T> { pub fn diff(va: &Self, vb: &Self) -> f64 { assert_eq!(va.size, vb.size); let mut acc = 0.0; for x in 0..va.size.0 { for y in 0..va.size.1 { let a = va[(x, y)]; let b = vb[(x, y)]; acc += Pixel::distance(a, b); } } acc } pub fn pixels(&self) -> Vec { let mut v = vec![]; for x in 0..self.size.0 { for y in 0..self.size.1 { v.push(self[(x, y)]); } } v } } impl View<&mut Frame> { pub fn copy_from(&mut self, other: &View<&Frame>) { for x in 0..self.size.0 { for y in 0..self.size.1 { self[(x, y)] = other[(x, y)]; } } } pub fn set_pixels(&mut self, pixels: &Vec) { for x in 0..self.size.0 { for y in 0..self.size.1 { self[(x, y)] = pixels[x * self.size.1 + y] } } } } impl> Index<(usize, usize)> for View<&T> { type Output = Pixel; #[inline] fn index(&self, (x, y): (usize, usize)) -> &Self::Output { &self.frame[(x + self.offset.0, y + self.offset.1)] } } impl> Index<(usize, usize)> for View<&mut T> { type Output = Pixel; #[inline] fn index(&self, (x, y): (usize, usize)) -> &Self::Output { &self.frame[(x + self.offset.0, y + self.offset.1)] } } impl> IndexMut<(usize, usize)> for View<&mut T> { #[inline] fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output { &mut self.frame[(x + self.offset.0, y + self.offset.1)] } }