aboutsummaryrefslogtreecommitdiff
path: root/old/evc/src/view.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-05-05 15:09:54 +0200
committermetamuffin <metamuffin@disroot.org>2025-05-05 15:09:54 +0200
commit306f96164784a8cbf405e72fa4364d6523366e95 (patch)
tree51717fc139871baa438aad806f4923669ae0896c /old/evc/src/view.rs
parent9cc089e2d6e841879e430b01d2f3d92c8820523e (diff)
downloadvideo-codec-experiments-306f96164784a8cbf405e72fa4364d6523366e95.tar
video-codec-experiments-306f96164784a8cbf405e72fa4364d6523366e95.tar.bz2
video-codec-experiments-306f96164784a8cbf405e72fa4364d6523366e95.tar.zst
old dir
Diffstat (limited to 'old/evc/src/view.rs')
-rw-r--r--old/evc/src/view.rs241
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 }]
+ }
+}