aboutsummaryrefslogtreecommitdiff
path: root/evc/src
diff options
context:
space:
mode:
Diffstat (limited to 'evc/src')
-rw-r--r--evc/src/bin/encode.rs19
-rw-r--r--evc/src/frame.rs65
-rw-r--r--evc/src/lib.rs1
-rw-r--r--evc/src/view.rs74
4 files changed, 89 insertions, 70 deletions
diff --git a/evc/src/bin/encode.rs b/evc/src/bin/encode.rs
index 8d37443..0edc3a1 100644
--- a/evc/src/bin/encode.rs
+++ b/evc/src/bin/encode.rs
@@ -1,7 +1,8 @@
use clap::Parser;
use evc::{
block::{Block, BlockInner},
- frame::{Frame, View},
+ frame::Frame,
+ view::View,
};
use std::io::{self, BufReader};
@@ -40,12 +41,18 @@ fn main() -> io::Result<()> {
fn encode_block(view: View, prev: View) -> Block {
let diff = View::diff(&view, &prev);
- let inner = if diff > 100_000.0 {
- let [a, b] = view.split();
- let [ap, bp] = prev.split();
- BlockInner::Split(Box::new([encode_block(a, ap), encode_block(b, bp)]))
+ let inner = if diff < 10_000.0 {
+ BlockInner::Reference {
+ translation: (0, 0),
+ }
} else {
- todo!()
+ if view.size.0 < 32 {
+ BlockInner::Literal(view.pixels())
+ } else {
+ let [a, b] = view.split();
+ let [ap, bp] = prev.split();
+ BlockInner::Split(Box::new([encode_block(a, ap), encode_block(b, bp)]))
+ }
};
Block {
diff --git a/evc/src/frame.rs b/evc/src/frame.rs
index 1906555..6e565b6 100644
--- a/evc/src/frame.rs
+++ b/evc/src/frame.rs
@@ -1,4 +1,4 @@
-use crate::{pixel::Pixel, ser::Source};
+use crate::{pixel::Pixel, ser::Source, view::View};
use std::{
io,
ops::{Index, IndexMut},
@@ -46,66 +46,3 @@ impl IndexMut<(usize, usize)> for Frame {
&mut self.buffer[x][y]
}
}
-
-pub struct View<'a> {
- pub frame: &'a Frame,
- pub offset: (usize, usize),
- pub size: (usize, usize),
-}
-
-impl<'a> View<'a> {
- pub fn new(frame: &'a Frame, offset: (usize, usize), size: (usize, usize)) -> Self {
- Self {
- frame,
- offset,
- size,
- }
- }
- 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 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 Index<(usize, usize)> for View<'_> {
- type Output = Pixel;
- #[inline]
- fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
- &self.frame[(x + self.offset.0, y + self.offset.1)]
- }
-}
diff --git a/evc/src/lib.rs b/evc/src/lib.rs
index 26255d7..4c504ef 100644
--- a/evc/src/lib.rs
+++ b/evc/src/lib.rs
@@ -5,3 +5,4 @@ pub mod block;
pub mod header;
pub mod frame;
pub mod pixel;
+pub mod view;
diff --git a/evc/src/view.rs b/evc/src/view.rs
new file mode 100644
index 0000000..ae7012f
--- /dev/null
+++ b/evc/src/view.rs
@@ -0,0 +1,74 @@
+use crate::{frame::Frame, pixel::Pixel};
+use std::ops::Index;
+
+pub struct View<'a> {
+ pub frame: &'a Frame,
+ pub offset: (usize, usize),
+ pub size: (usize, usize),
+}
+
+impl<'a> View<'a> {
+ pub fn new(frame: &'a Frame, offset: (usize, usize), size: (usize, usize)) -> Self {
+ Self {
+ frame,
+ offset,
+ size,
+ }
+ }
+ 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 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)
+ },
+ },
+ ]
+ }
+ pub fn pixels(&self) -> Vec<Pixel> {
+ 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 Index<(usize, usize)> for View<'_> {
+ type Output = Pixel;
+ #[inline]
+ fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
+ &self.frame[(x + self.offset.0, y + self.offset.1)]
+ }
+}