diff options
author | metamuffin <metamuffin@disroot.org> | 2022-12-07 21:23:42 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2022-12-07 21:23:42 +0100 |
commit | 2ac18802b58d671c10538e78d50a620baad9a188 (patch) | |
tree | 17f924039fd8f3dae2801902d4bdeaac8ea74624 /evc/src | |
parent | 9d7986bbfd44b69a623fa29528b5d13000b91c77 (diff) | |
download | video-codec-experiments-2ac18802b58d671c10538e78d50a620baad9a188.tar video-codec-experiments-2ac18802b58d671c10538e78d50a620baad9a188.tar.bz2 video-codec-experiments-2ac18802b58d671c10538e78d50a620baad9a188.tar.zst |
advanced transform
Diffstat (limited to 'evc/src')
-rw-r--r-- | evc/src/bin/decode.rs | 50 | ||||
-rw-r--r-- | evc/src/codec/encode.rs | 8 | ||||
-rw-r--r-- | evc/src/debug.rs | 53 | ||||
-rw-r--r-- | evc/src/frame.rs | 22 | ||||
-rw-r--r-- | evc/src/helpers/matrix.rs | 2 | ||||
-rw-r--r-- | evc/src/helpers/pixel.rs | 8 | ||||
-rw-r--r-- | evc/src/helpers/vector.rs | 9 | ||||
-rw-r--r-- | evc/src/refsampler.rs | 6 |
8 files changed, 95 insertions, 63 deletions
diff --git a/evc/src/bin/decode.rs b/evc/src/bin/decode.rs index 9be1a16..7b44ede 100644 --- a/evc/src/bin/decode.rs +++ b/evc/src/bin/decode.rs @@ -4,13 +4,9 @@ use clap::Parser; use evc::{ block::Block, codec::decode::decode_block, - format::{ - header::Header, - ser::{map_scalar8, Source}, - }, + debug::draw_debug, + format::{header::Header, ser::Source}, frame::Frame, - helpers::{matrix::Mat2, pixel::Pixel, vector::Vec2}, - view::View, }; use log::info; use std::io::{BufReader, BufWriter}; @@ -54,45 +50,3 @@ fn main() -> anyhow::Result<()> { drop(input); Ok(()) } - -fn draw_debug(block: &Block, mut target: View<&mut Frame>) { - match &block { - Block::Literal(_) => { - target.draw_box(Pixel::GREEN); - } - Block::Split(box [a, b]) => { - let [at, bt] = target.split_mut_unsafe(); - draw_debug(a, at); - draw_debug(b, bt); - } - Block::Reference { translation } => { - target.draw_box(Pixel::BLUE); - target.frame.draw_line( - target.center().into(), - (target.center() + *translation).into(), - Pixel::RED, - ) - } - Block::AdvancedReference(r) => { - let mat = Mat2 { - a: map_scalar8(r.transform.a), - b: map_scalar8(r.transform.b), - c: map_scalar8(r.transform.c), - d: map_scalar8(r.transform.d), - }; - let translation = Vec2 { - x: map_scalar8(r.translation.x), - y: map_scalar8(r.translation.y), - }; - let tl = mat.transform(target.offset.into()) + translation; - let tr = mat.transform((target.offset + target.size.x_only()).into()) + translation; - let bl = mat.transform((target.offset + target.size.y_only()).into()) + translation; - let br = mat.transform((target.offset + target.size).into()) + translation; - target.frame.draw_line(tl, tr, Pixel::MAGENTA); - target.frame.draw_line(tr, br, Pixel::MAGENTA); - target.frame.draw_line(br, bl, Pixel::MAGENTA); - target.frame.draw_line(bl, tl, Pixel::MAGENTA); - target.draw_box(Pixel::CYAN); - } - } -} diff --git a/evc/src/codec/encode.rs b/evc/src/codec/encode.rs index 5ffee4b..484ae4b 100644 --- a/evc/src/codec/encode.rs +++ b/evc/src/codec/encode.rs @@ -90,6 +90,14 @@ pub fn encode_block(view: View<&Frame>, prev: View<&Frame>, config: &EncodeConfi pk(&view, &prev, &mut d, &mut p, |p| p.translation.x -= 2); pk(&view, &prev, &mut d, &mut p, |p| p.translation.y += 2); pk(&view, &prev, &mut d, &mut p, |p| p.translation.y -= 2); + pk(&view, &prev, &mut d, &mut p, |p| p.transform.a -= 1); + pk(&view, &prev, &mut d, &mut p, |p| p.transform.a += 1); + pk(&view, &prev, &mut d, &mut p, |p| p.transform.b -= 1); + pk(&view, &prev, &mut d, &mut p, |p| p.transform.b += 1); + pk(&view, &prev, &mut d, &mut p, |p| p.transform.c -= 1); + pk(&view, &prev, &mut d, &mut p, |p| p.transform.c += 1); + pk(&view, &prev, &mut d, &mut p, |p| p.transform.d -= 1); + pk(&view, &prev, &mut d, &mut p, |p| p.transform.d += 1); debug!("{diff} -> {d}"); if d >= diff { diff --git a/evc/src/debug.rs b/evc/src/debug.rs index 06dd507..99723b8 100644 --- a/evc/src/debug.rs +++ b/evc/src/debug.rs @@ -1,4 +1,11 @@ -use crate::{frame::Frame, helpers::pixel::Pixel, helpers::vector::Vec2, view::View}; +use crate::{ + block::Block, + format::ser::map_scalar8, + frame::Frame, + helpers::vector::Vec2, + helpers::{matrix::Mat2, pixel::Pixel}, + view::View, +}; impl View<&mut Frame> { pub fn draw_box(&mut self, color: Pixel) { @@ -54,3 +61,47 @@ impl Pixel { b: 255, }; } + +pub fn draw_debug(block: &Block, mut target: View<&mut Frame>) { + match &block { + Block::Literal(_) => { + target.draw_box(Pixel::GREEN); + } + Block::Split(box [a, b]) => { + let [at, bt] = target.split_mut_unsafe(); + draw_debug(a, at); + draw_debug(b, bt); + } + Block::Reference { translation } => { + target.draw_box(Pixel::BLUE); + target.frame.draw_line( + target.center().into(), + (target.center() + *translation).into(), + Pixel::RED, + ) + } + Block::AdvancedReference(r) => { + let mat = Mat2 { + a: map_scalar8(r.transform.a), + b: map_scalar8(r.transform.b), + c: map_scalar8(r.transform.c), + d: map_scalar8(r.transform.d), + }; + let translation = Vec2 { + x: map_scalar8(r.translation.x), + y: map_scalar8(r.translation.y), + }; + let tl = mat.transform(translation) + target.offset.into(); + let tr = + mat.transform(translation + target.size.x_only().into()) + target.offset.into(); + let bl = + mat.transform(translation + target.size.y_only().into()) + target.offset.into(); + let br = mat.transform(translation + target.size.into()) + target.offset.into(); + target.frame.draw_line(tl, tr, Pixel::MAGENTA); + target.frame.draw_line(tr, br, Pixel::MAGENTA); + target.frame.draw_line(bl, br, Pixel::MAGENTA); + target.frame.draw_line(tl, bl, Pixel::MAGENTA); + target.draw_box(Pixel::CYAN); + } + } +} diff --git a/evc/src/frame.rs b/evc/src/frame.rs index e1c3a6e..81fdf3b 100644 --- a/evc/src/frame.rs +++ b/evc/src/frame.rs @@ -80,16 +80,20 @@ impl IndexMut<Vec2<isize>> for Frame { impl Frame { #[inline] pub fn sample(&self, p: Vec2<f32>) -> Pixel { - let fx = p.x.floor() as isize; - let fy = p.y.floor() as isize; - let cx = p.x.ceil() as isize; - let cy = p.y.ceil() as isize; + self[Vec2 { + x: p.x as isize, + y: p.y as isize, + }] + // let fx = p.x.floor() as isize; + // let fy = p.y.floor() as isize; + // let cx = p.x.ceil() as isize; + // let cy = p.y.ceil() as isize; - // TODO dont loose accuracy here - Pixel::average( - Pixel::average(self[Vec2 { x: fx, y: fy }], self[Vec2 { x: fx, y: cy }]), - Pixel::average(self[Vec2 { x: cx, y: fx }], self[Vec2 { x: cx, y: fy }]), - ) + // // TODO dont loose accuracy here + // Pixel::average( + // Pixel::average(self[Vec2 { x: fx, y: fy }], self[Vec2 { x: fx, y: cy }]), + // Pixel::average(self[Vec2 { x: cx, y: fx }], self[Vec2 { x: cx, y: fy }]), + // ) } } diff --git a/evc/src/helpers/matrix.rs b/evc/src/helpers/matrix.rs index 92f46b2..87c0e7d 100644 --- a/evc/src/helpers/matrix.rs +++ b/evc/src/helpers/matrix.rs @@ -9,6 +9,7 @@ pub struct Mat2<T> { } impl<T: std::ops::Mul<Output = T> + std::ops::Add<Output = T> + Copy> Mat2<T> { + #[inline] pub fn transform(&self, v: Vec2<T>) -> Vec2<T> { Vec2 { x: self.a * v.x + self.b * v.x, @@ -19,6 +20,7 @@ impl<T: std::ops::Mul<Output = T> + std::ops::Add<Output = T> + Copy> Mat2<T> { impl<T: std::ops::Mul<Output = T> + std::ops::Add<Output = T> + Copy> std::ops::Mul for Mat2<T> { type Output = Mat2<T>; + #[inline] fn mul(self, rhs: Mat2<T>) -> Mat2<T> { let (x, y) = (self, rhs); Mat2 { diff --git a/evc/src/helpers/pixel.rs b/evc/src/helpers/pixel.rs index 7b7c8d5..f7d6621 100644 --- a/evc/src/helpers/pixel.rs +++ b/evc/src/helpers/pixel.rs @@ -31,10 +31,12 @@ impl Pixel { } #[inline] pub fn average(a: Pixel, b: Pixel) -> Pixel { + //? this functions is broken + // TODO dont loose accuracy Pixel { - r: (a.r >> 2) + (b.r >> 2), - g: (a.g >> 2) + (b.g >> 2), - b: (a.b >> 2) + (b.b >> 2), + r: (a.r >> 1) + (b.r >> 1), + g: (a.g >> 1) + (b.g >> 1), + b: (a.b >> 1) + (b.b >> 1), } } pub fn scale(&self, factor: f32) -> Pixel { diff --git a/evc/src/helpers/vector.rs b/evc/src/helpers/vector.rs index 12243e4..f411832 100644 --- a/evc/src/helpers/vector.rs +++ b/evc/src/helpers/vector.rs @@ -24,6 +24,15 @@ impl<T: std::ops::Div<Output = T> + Copy> Vec2<T> { } } +impl<T: std::ops::Mul<Output = T> + Copy> Vec2<T> { + pub fn scale(&self, f: T) -> Self { + Self { + x: self.x * f, + y: self.y * f, + } + } +} + impl Vec2<isize> { pub fn x_only(&self) -> Self { Self { x: self.x, y: 0 } diff --git a/evc/src/refsampler.rs b/evc/src/refsampler.rs index ad02332..16a0600 100644 --- a/evc/src/refsampler.rs +++ b/evc/src/refsampler.rs @@ -9,6 +9,7 @@ use crate::{ #[derive(Debug, Clone)] pub struct Sampler<'a> { pub view: View<&'a Frame>, + pub halfsize: Vec2<f32>, pub translation: Vec2<f32>, pub transform: Mat2<f32>, @@ -20,8 +21,8 @@ impl<'a> Sampler<'a> { #[inline] pub fn sample(&self, p: Vec2<f32>) -> Pixel { self.view - .sample(self.translation + p) // self.transform.transform(p)) - // .scale(self.value_scale) + .sample(self.translation + self.transform.transform(p + self.halfsize) - self.halfsize) + // .scale(self.value_scale) } pub fn from_refblock( view: View<&'a Frame>, @@ -38,6 +39,7 @@ impl<'a> Sampler<'a> { c: map_scalar8(transform.c), d: map_scalar8(transform.d), }, + halfsize: Into::<Vec2<f32>>::into(view.size).scale(0.5), translation: Vec2 { x: map_scalar8(translation.x), y: map_scalar8(translation.y), |