diff options
author | metamuffin <metamuffin@disroot.org> | 2025-05-05 15:09:54 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-05-05 15:09:54 +0200 |
commit | 306f96164784a8cbf405e72fa4364d6523366e95 (patch) | |
tree | 51717fc139871baa438aad806f4923669ae0896c /framework/src | |
parent | 9cc089e2d6e841879e430b01d2f3d92c8820523e (diff) | |
download | video-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.rs | 181 | ||||
-rw-r--r-- | framework/src/common/mod.rs | 1 | ||||
-rw-r--r-- | framework/src/lib.rs | 153 | ||||
-rw-r--r-- | framework/src/vector.rs | 128 |
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 } - } -} |