From 2ac18802b58d671c10538e78d50a620baad9a188 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Wed, 7 Dec 2022 21:23:42 +0100 Subject: advanced transform --- evc/src/bin/decode.rs | 50 ++------------------------------------------ evc/src/codec/encode.rs | 8 +++++++ evc/src/debug.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++- evc/src/frame.rs | 22 ++++++++++++-------- evc/src/helpers/matrix.rs | 2 ++ evc/src/helpers/pixel.rs | 8 ++++--- evc/src/helpers/vector.rs | 9 ++++++++ evc/src/refsampler.rs | 6 ++++-- 8 files changed, 95 insertions(+), 63 deletions(-) (limited to 'evc/src') 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> for Frame { impl Frame { #[inline] pub fn sample(&self, p: Vec2) -> 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 { } impl + std::ops::Add + Copy> Mat2 { + #[inline] pub fn transform(&self, v: Vec2) -> Vec2 { Vec2 { x: self.a * v.x + self.b * v.x, @@ -19,6 +20,7 @@ impl + std::ops::Add + Copy> Mat2 { impl + std::ops::Add + Copy> std::ops::Mul for Mat2 { type Output = Mat2; + #[inline] fn mul(self, rhs: Mat2) -> Mat2 { 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 + Copy> Vec2 { } } +impl + Copy> Vec2 { + pub fn scale(&self, f: T) -> Self { + Self { + x: self.x * f, + y: self.y * f, + } + } +} + impl Vec2 { 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, pub translation: Vec2, pub transform: Mat2, @@ -20,8 +21,8 @@ impl<'a> Sampler<'a> { #[inline] pub fn sample(&self, p: Vec2) -> 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::>::into(view.size).scale(0.5), translation: Vec2 { x: map_scalar8(translation.x), y: map_scalar8(translation.y), -- cgit v1.2.3-70-g09d2