aboutsummaryrefslogtreecommitdiff
path: root/framework/src
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 /framework/src
parent9cc089e2d6e841879e430b01d2f3d92c8820523e (diff)
downloadvideo-codec-experiments-306f96164784a8cbf405e72fa4364d6523366e95.tar
video-codec-experiments-306f96164784a8cbf405e72fa4364d6523366e95.tar.bz2
video-codec-experiments-306f96164784a8cbf405e72fa4364d6523366e95.tar.zst
old dir
Diffstat (limited to 'framework/src')
-rw-r--r--framework/src/common/huffman.rs181
-rw-r--r--framework/src/common/mod.rs1
-rw-r--r--framework/src/lib.rs153
-rw-r--r--framework/src/vector.rs128
4 files changed, 0 insertions, 463 deletions
diff --git a/framework/src/common/huffman.rs b/framework/src/common/huffman.rs
deleted file mode 100644
index 474cfab..0000000
--- a/framework/src/common/huffman.rs
+++ /dev/null
@@ -1,181 +0,0 @@
-#[derive(Debug, Clone)]
-enum HT {
- Branch(Box<HT>, Box<HT>),
- Terminal(u8),
-}
-
-pub fn encode_huff(buf: &[u8]) -> Vec<u8> {
- let mut w = BitIO::new(Vec::new());
- assert!(buf.len() <= 0xffffff, "huff frame too big");
- w.wbyte((buf.len() & 0xff) as u8);
- w.wbyte(((buf.len() >> 8) & 0xff) as u8);
- w.wbyte(((buf.len() >> 16) & 0xff) as u8);
-
- let mut probs = [0usize; 256];
- for b in buf {
- probs[*b as usize] += 1;
- }
- let tree = HT::from_probabilities(probs);
- let mut table = [0u32; 256];
- tree.create_lut(&mut table, 1);
- tree.write(&mut w);
-
- for b in buf {
- let mut k = table[*b as usize];
- while k != 1 {
- w.wbit((k & 1) == 1);
- k >>= 1;
- }
- }
-
- w.flush();
- w.buffer
-}
-
-pub fn read_huff(r: Vec<u8>) -> Vec<u8> {
- let mut r = BitIO::new(r);
-
- let mut len = 0usize;
- len |= r.rbyte() as usize;
- len |= (r.rbyte() as usize) << 8;
- len |= (r.rbyte() as usize) << 16;
-
- let root = HT::read(&mut r);
- let root = match &root {
- HT::Branch(a, b) => [a, b],
- _ => panic!("no!"),
- };
-
- let mut cursor = root;
- let mut buf = Vec::new();
- while buf.len() != len {
- let v = r.rbit();
- match cursor[v as usize].as_ref() {
- HT::Branch(a, b) => {
- cursor = [a, b];
- }
- HT::Terminal(n) => {
- buf.push(*n);
- cursor = root;
- }
- }
- }
- buf
-}
-
-impl HT {
- pub fn from_probabilities(ps: [usize; 256]) -> Self {
- let mut parts = ps
- .into_iter()
- .enumerate()
- .map(|(n, p)| (p, HT::Terminal(n as u8)))
- .collect::<Vec<_>>();
-
- while parts.len() != 1 {
- parts.sort_by_key(|e| -(e.0 as isize));
- let ((ap, at), (bp, bt)) = (parts.pop().unwrap(), parts.pop().unwrap());
- parts.push((ap + bp + 1, HT::Branch(Box::new(at), Box::new(bt))))
- }
- parts[0].1.clone()
- }
- pub fn create_lut(&self, table: &mut [u32; 256], mut prefix: u32) {
- assert!(self.depth() < 30, "too deep! doesnt fit {}", self.depth());
- match self {
- HT::Branch(a, b) => {
- let pz = 32 - prefix.leading_zeros();
- prefix ^= 1 << pz;
- prefix ^= 1 << (pz - 1);
- a.create_lut(table, prefix);
- prefix ^= 1 << (pz - 1);
- b.create_lut(table, prefix);
- }
- HT::Terminal(n) => {
- assert_eq!(table[*n as usize], 0);
- table[*n as usize] = prefix
- }
- }
- }
- pub fn depth(&self) -> usize {
- match self {
- HT::Branch(a, b) => a.depth().max(b.depth()) + 1,
- HT::Terminal(_) => 0,
- }
- }
- pub fn write(&self, w: &mut BitIO) {
- match self {
- HT::Branch(a, b) => {
- w.wbit(false);
- a.write(w);
- b.write(w);
- }
- HT::Terminal(n) => {
- w.wbit(true);
- w.wbyte(*n);
- }
- }
- }
- pub fn read(r: &mut BitIO) -> Self {
- match r.rbit() {
- false => Self::Branch(Box::new(Self::read(r)), Box::new(Self::read(r))),
- true => Self::Terminal(r.rbyte()),
- }
- }
-}
-
-pub struct BitIO {
- buffer: Vec<u8>,
- byte: u8,
- position: usize,
-}
-impl BitIO {
- pub fn new(inner: Vec<u8>) -> Self {
- Self {
- buffer: inner,
- byte: 0,
- position: 0,
- }
- }
- #[inline]
- pub fn wbit(&mut self, b: bool) {
- self.byte <<= 1;
- self.byte |= b as u8;
- self.position += 1;
- if self.position & 0b111 == 0 {
- self.buffer.push(self.byte)
- }
- }
- #[inline]
- pub fn wbyte(&mut self, v: u8) {
- for i in 0..8 {
- self.wbit((v & (1 << i)) != 0);
- }
- }
-
- #[inline]
- pub fn flush(&mut self) {
- while self.position & 0b111 != 0 {
- self.wbit(false);
- }
- }
-
- #[inline]
- pub fn rbit(&mut self) -> bool {
- if self.position & 0b111 == 0 {
- self.byte = self.buffer[self.position >> 3];
- }
-
- let v = (self.byte & 0b10000000) != 0;
- self.byte <<= 1;
- self.position += 1;
- v
- }
-
- #[inline]
- pub fn rbyte(&mut self) -> u8 {
- let mut v = 0u8;
- for i in 0..8 {
- v |= (self.rbit() as u8) << i;
- }
- v
- }
-}
diff --git a/framework/src/common/mod.rs b/framework/src/common/mod.rs
deleted file mode 100644
index 6f86024..0000000
--- a/framework/src/common/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod huffman;
diff --git a/framework/src/lib.rs b/framework/src/lib.rs
deleted file mode 100644
index af535c5..0000000
--- a/framework/src/lib.rs
+++ /dev/null
@@ -1,153 +0,0 @@
-use std::{
- io::{self, stdin, stdout, Read, Write},
- ops::{Index, IndexMut},
- time::Instant,
-};
-use vector::{UVec2, Vec2};
-
-pub mod common;
-pub mod vector;
-
-#[derive(Clone)]
-pub struct CodecParams {
- pub width: usize,
- pub height: usize,
- pub debug: usize,
- pub mode: CodecMode,
-}
-#[derive(Clone)]
-pub enum CodecMode {
- Encode,
- Decode,
-}
-
-pub struct Framework {
- process_start: Instant,
- params: CodecParams,
-}
-
-impl Framework {
- pub fn init() -> (Self, CodecParams) {
- let width = std::env::var("V_WIDTH").unwrap().parse().unwrap();
- let height = std::env::var("V_HEIGHT").unwrap().parse().unwrap();
- let debug = std::env::var("V_DEBUG").unwrap().parse().unwrap();
- let mode = match std::env::var("V_MODE").unwrap().as_str() {
- "encode" => CodecMode::Encode,
- "decode" => CodecMode::Decode,
- _ => panic!("invalid mode"),
- };
- let params = CodecParams {
- height,
- width,
- debug,
- mode,
- };
- (
- Self {
- params: params.clone(),
- process_start: Instant::now(),
- },
- params,
- )
- }
-
- pub fn next_frame(&mut self) -> Option<Frame> {
- let f = Some(Frame::read(self.params.width, self.params.height, stdin()).unwrap());
- self.next_frame_manual();
- f
- }
- pub fn next_frame_manual(&mut self) {
- self.process_start = Instant::now();
- }
- pub fn encode_done(&mut self, output: &[u8]) {
- let el = self.process_start.elapsed();
- eprintln!(
- "size={}KB ratio={:.02} t={el:?}",
- output.len() / 1000,
- (self.params.width * self.params.height * 3) as f32 / output.len() as f32
- )
- }
-
- pub fn next_chunk(&mut self, _buffer: &mut Vec<u8>) -> bool {
- true
- }
- pub fn decode_done(&mut self, output: &Frame) {
- output.write(stdout()).unwrap();
- }
-}
-
-#[derive(Debug, Clone)]
-pub struct Frame {
- pub width: usize,
- pub height: usize,
- pub pixels: Vec<Pixel<u8>>,
-}
-
-#[derive(Debug, Clone, Copy)]
-pub struct Pixel<T> {
- pub r: T,
- pub g: T,
- pub b: T,
-}
-pub type EPixel = Pixel<u8>;
-
-impl Frame {
- pub fn new(width: usize, height: usize) -> Self {
- Self {
- height,
- width,
- pixels: vec![Pixel::BLACK; width * height],
- }
- }
- pub fn read(width: usize, height: usize, mut r: impl Read) -> io::Result<Self> {
- let mut f = Frame::new(width, height);
- let p = unsafe {
- std::slice::from_raw_parts_mut(
- f.pixels.as_mut_slice().as_mut_ptr() as *mut u8,
- width * height * 3,
- )
- };
- r.read_exact(p)?;
- Ok(f)
- }
- pub fn write(&self, mut w: impl Write) -> io::Result<()> {
- let p = unsafe {
- std::slice::from_raw_parts(
- self.pixels.as_slice().as_ptr() as *const u8,
- self.width * self.height * 3,
- )
- };
- w.write_all(p)
- }
-}
-
-impl Index<(usize, usize)> for Frame {
- type Output = Pixel<u8>;
- #[inline]
- fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
- &self.pixels[x + y * self.width]
- }
-}
-impl IndexMut<(usize, usize)> for Frame {
- #[inline]
- fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
- &mut self.pixels[x + y * self.width]
- }
-}
-impl Index<UVec2> for Frame {
- type Output = Pixel<u8>;
- #[inline]
- fn index(&self, Vec2 { x, y }: UVec2) -> &Self::Output {
- &self.pixels[x + y * self.width]
- }
-}
-impl IndexMut<UVec2> for Frame {
- #[inline]
- fn index_mut(&mut self, Vec2 { x, y }: UVec2) -> &mut Self::Output {
- &mut self.pixels[x + y * self.width]
- }
-}
-
-impl Pixel<u8> {
- pub const BLACK: Pixel<u8> = Pixel { r: 0, g: 0, b: 0 };
-}
diff --git a/framework/src/vector.rs b/framework/src/vector.rs
deleted file mode 100644
index 5227d04..0000000
--- a/framework/src/vector.rs
+++ /dev/null
@@ -1,128 +0,0 @@
-pub type UVec2 = Vec2<usize>;
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Vec2<T> {
- pub x: T,
- pub y: T,
-}
-
-impl From<Vec2<isize>> for Vec2<u16> {
- fn from(value: Vec2<isize>) -> Self {
- Self {
- x: value.x as u16,
- y: value.y as u16,
- }
- }
-}
-impl From<Vec2<u16>> for Vec2<isize> {
- fn from(value: Vec2<u16>) -> Self {
- Self {
- x: value.x as isize,
- y: value.y as isize,
- }
- }
-}
-impl From<Vec2<f32>> for Vec2<isize> {
- fn from(value: Vec2<f32>) -> Self {
- Self {
- x: value.x as isize,
- y: value.y as isize,
- }
- }
-}
-
-impl Vec2<isize> {
- pub const ZERO: Vec2<isize> = Vec2 { x: 0, y: 0 };
- pub const UP: Vec2<isize> = Vec2 { x: 0, y: -1 };
- pub const LEFT: Vec2<isize> = Vec2 { x: -1, y: 0 };
-}
-impl Vec2<f32> {
- pub const ZERO: Vec2<f32> = Vec2 { x: 0.0, y: 0.0 };
- pub const UP: Vec2<f32> = Vec2 { x: 0.0, y: -1.0 };
- pub const LEFT: Vec2<f32> = Vec2 { x: -1.0, y: 0.0 };
-}
-
-impl<T: std::ops::Div<Output = T> + Copy> Vec2<T> {
- pub fn downscale(&self, f: T) -> Self {
- Self {
- x: self.x / f,
- y: self.y / f,
- }
- }
-}
-
-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,
- }
- }
- pub fn area(&self) -> T {
- self.x * self.y
- }
-}
-
-impl Vec2<isize> {
- pub fn x_only(&self) -> Self {
- Self { x: self.x, y: 0 }
- }
- pub fn y_only(&self) -> Self {
- Self { x: 0, y: self.y }
- }
-}
-
-impl Into<Vec2<f32>> for Vec2<isize> {
- fn into(self) -> Vec2<f32> {
- Vec2 {
- x: self.x as f32,
- y: self.y as f32,
- }
- }
-}
-impl From<(isize, isize)> for Vec2<f32> {
- fn from((x, y): (isize, isize)) -> Self {
- Vec2 {
- x: x as f32,
- y: y as f32,
- }
- }
-}
-
-impl<T: std::ops::Add> std::ops::Add for Vec2<T> {
- type Output = Vec2<T::Output>;
- #[inline]
- fn add(self, rhs: Self) -> Self::Output {
- Vec2 {
- x: self.x + rhs.x,
- y: self.y + rhs.y,
- }
- }
-}
-impl<T: std::ops::Sub> std::ops::Sub for Vec2<T> {
- type Output = Vec2<T::Output>;
- #[inline]
- fn sub(self, rhs: Self) -> Self::Output {
- Vec2 {
- x: self.x - rhs.x,
- y: self.y - rhs.y,
- }
- }
-}
-impl<T: std::ops::Mul> std::ops::Mul for Vec2<T> {
- type Output = Vec2<T::Output>;
- #[inline]
- fn mul(self, rhs: Self) -> Self::Output {
- Vec2 {
- x: self.x * rhs.x,
- y: self.y * rhs.y,
- }
- }
-}
-
-impl<T> From<(T, T)> for Vec2<T> {
- #[inline]
- fn from((x, y): (T, T)) -> Self {
- Vec2 { x, y }
- }
-}