diff options
Diffstat (limited to 'old/evc/src/view.rs')
-rw-r--r-- | old/evc/src/view.rs | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/old/evc/src/view.rs b/old/evc/src/view.rs new file mode 100644 index 0000000..6f34965 --- /dev/null +++ b/old/evc/src/view.rs @@ -0,0 +1,241 @@ +use crate::{ + frame::Frame, + helpers::{pixel::Pixel, vector::Vec2}, + refsampler::Sampler, +}; +use std::ops::{Index, IndexMut}; + +#[derive(Debug, Clone)] +pub struct View<T> { + pub frame: T, + pub offset: Vec2<isize>, + pub size: Vec2<isize>, +} + +impl<T> View<T> { + pub fn new(frame: T, offset: Vec2<isize>, size: Vec2<isize>) -> Self { + Self { + frame, + offset, + size, + } + } + pub fn area(&self) -> isize { + self.size.x * self.size.y + } + pub fn center(&self) -> Vec2<isize> { + self.offset + self.size.downscale(2) + } +} + +impl<T> View<&mut T> { + pub fn split_mut_unsafe(&mut self) -> [Self; 2] { + let vert = self.size.x > self.size.y; + [ + Self { + frame: unsafe { std::mem::transmute::<&mut T, &mut T>(&mut self.frame) }, + offset: self.offset, + size: if vert { + Vec2 { + x: self.size.x / 2, + y: self.size.y, + } + } else { + Vec2 { + x: self.size.x, + y: self.size.y / 2, + } + }, + }, + Self { + frame: unsafe { std::mem::transmute::<&mut T, &mut T>(&mut self.frame) }, + offset: if vert { + Vec2 { + x: self.offset.x + self.size.x / 2, + y: self.offset.y, + } + } else { + Vec2 { + x: self.offset.x, + y: self.offset.y + self.size.y / 2, + } + }, + size: if vert { + Vec2 { + x: self.size.x - self.size.x / 2, + y: self.size.y, + } + } else { + Vec2 { + x: self.size.x, + y: self.size.y - self.size.y / 2, + } + }, + }, + ] + } +} +impl<T: Copy> View<T> { + pub fn offset(&self, offset: Vec2<isize>) -> Self { + Self { + frame: self.frame, + offset: self.offset + offset, + size: self.size, + } + } + pub fn split(&self) -> [Self; 2] { + let vert = self.size.x > self.size.y; + [ + Self { + frame: self.frame, + offset: self.offset, + size: if vert { + Vec2 { + x: self.size.x / 2, + y: self.size.y, + } + } else { + Vec2 { + x: self.size.x, + y: self.size.y / 2, + } + }, + }, + Self { + frame: self.frame, + offset: if vert { + Vec2 { + x: self.offset.x + self.size.x / 2, + y: self.offset.y, + } + } else { + Vec2 { + x: self.offset.x, + y: self.offset.y + self.size.y / 2, + } + }, + size: if vert { + Vec2 { + x: self.size.x - self.size.x / 2, + y: self.size.y, + } + } else { + Vec2 { + x: self.size.x, + y: self.size.y - self.size.y / 2, + } + }, + }, + ] + } +} +impl<T: Index<Vec2<isize>, Output = Pixel>> View<&T> { + pub fn diff(va: &Self, vb: &Self) -> f64 { + assert_eq!(va.size, vb.size); + let mut acc = 0; + for x in 0..va.size.x { + for y in 0..va.size.y { + let a = va[(x, y)]; + let b = vb[(x, y)]; + acc += Pixel::distance(a, b); + } + } + acc as f64 + } + pub fn diff_sampler(va: &Self, vb: &Sampler<'_>) -> f64 { + assert_eq!(va.size, vb.view.size); + let mut acc = 0; + for x in 0..va.size.x { + for y in 0..va.size.y { + let a = va[(x, y)]; + let b = vb.sample(Vec2 { + x: x as f32, + y: y as f32, + }); + acc += Pixel::distance(a, b); + } + } + acc as f64 + } + + pub fn pixels(&self) -> Vec<Pixel> { + let mut v = vec![]; + for y in 0..self.size.y { + for x in 0..self.size.x { + 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.x { + for y in 0..self.size.y { + self[(x, y)] = other[(x, y)]; + } + } + } + pub fn copy_from_sampler(&mut self, other: &Sampler) { + for x in 0..self.size.x { + for y in 0..self.size.y { + self[(x, y)] = other.sample((x, y).into()); + } + } + } + + pub fn set_pixels(&mut self, pixels: &Vec<Pixel>) { + for y in 0..self.size.y { + for x in 0..self.size.x { + self[(x, y)] = pixels[(y * self.size.x + x) as usize] + } + } + } +} +impl View<&Frame> { + pub fn sample(&self, p: Vec2<f32>) -> Pixel { + self.frame.sample(p + self.offset.into()) + } +} + +impl<T: Index<Vec2<isize>, Output = Pixel>> Index<Vec2<isize>> for View<&T> { + type Output = Pixel; + #[inline] + fn index(&self, p: Vec2<isize>) -> &Self::Output { + &self.frame[self.offset + p] + } +} +impl<T: Index<Vec2<isize>, Output = Pixel>> Index<Vec2<isize>> for View<&mut T> { + type Output = Pixel; + #[inline] + fn index(&self, p: Vec2<isize>) -> &Self::Output { + &self.frame[self.offset + p] + } +} +impl<T: IndexMut<Vec2<isize>, Output = Pixel>> IndexMut<Vec2<isize>> for View<&mut T> { + #[inline] + fn index_mut(&mut self, p: Vec2<isize>) -> &mut Self::Output { + &mut self.frame[self.offset + p] + } +} + +impl<T: Index<Vec2<isize>, Output = Pixel>> Index<(isize, isize)> for View<&T> { + type Output = Pixel; + #[inline] + fn index(&self, (x, y): (isize, isize)) -> &Self::Output { + &self[Vec2 { x, y }] + } +} +impl<T: Index<Vec2<isize>, Output = Pixel>> Index<(isize, isize)> for View<&mut T> { + type Output = Pixel; + #[inline] + fn index(&self, (x, y): (isize, isize)) -> &Self::Output { + &self[Vec2 { x, y }] + } +} +impl<T: IndexMut<Vec2<isize>, Output = Pixel>> IndexMut<(isize, isize)> for View<&mut T> { + #[inline] + fn index_mut(&mut self, (x, y): (isize, isize)) -> &mut Self::Output { + &mut self[Vec2 { x, y }] + } +} |