From 306f96164784a8cbf405e72fa4364d6523366e95 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 5 May 2025 15:09:54 +0200 Subject: old dir --- old/framework/src/common/huffman.rs | 181 ++++++++++++++++++++++++++++++++++++ old/framework/src/common/mod.rs | 1 + old/framework/src/lib.rs | 153 ++++++++++++++++++++++++++++++ old/framework/src/vector.rs | 128 +++++++++++++++++++++++++ 4 files changed, 463 insertions(+) create mode 100644 old/framework/src/common/huffman.rs create mode 100644 old/framework/src/common/mod.rs create mode 100644 old/framework/src/lib.rs create mode 100644 old/framework/src/vector.rs (limited to 'old/framework/src') diff --git a/old/framework/src/common/huffman.rs b/old/framework/src/common/huffman.rs new file mode 100644 index 0000000..474cfab --- /dev/null +++ b/old/framework/src/common/huffman.rs @@ -0,0 +1,181 @@ +#[derive(Debug, Clone)] +enum HT { + Branch(Box, Box), + Terminal(u8), +} + +pub fn encode_huff(buf: &[u8]) -> Vec { + 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) -> Vec { + 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::>(); + + 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, + byte: u8, + position: usize, +} +impl BitIO { + pub fn new(inner: Vec) -> 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/old/framework/src/common/mod.rs b/old/framework/src/common/mod.rs new file mode 100644 index 0000000..6f86024 --- /dev/null +++ b/old/framework/src/common/mod.rs @@ -0,0 +1 @@ +pub mod huffman; diff --git a/old/framework/src/lib.rs b/old/framework/src/lib.rs new file mode 100644 index 0000000..af535c5 --- /dev/null +++ b/old/framework/src/lib.rs @@ -0,0 +1,153 @@ +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 { + 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) -> 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>, +} + +#[derive(Debug, Clone, Copy)] +pub struct Pixel { + pub r: T, + pub g: T, + pub b: T, +} +pub type EPixel = Pixel; + +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 { + 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; + #[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 for Frame { + type Output = Pixel; + #[inline] + fn index(&self, Vec2 { x, y }: UVec2) -> &Self::Output { + &self.pixels[x + y * self.width] + } +} +impl IndexMut for Frame { + #[inline] + fn index_mut(&mut self, Vec2 { x, y }: UVec2) -> &mut Self::Output { + &mut self.pixels[x + y * self.width] + } +} + +impl Pixel { + pub const BLACK: Pixel = Pixel { r: 0, g: 0, b: 0 }; +} diff --git a/old/framework/src/vector.rs b/old/framework/src/vector.rs new file mode 100644 index 0000000..5227d04 --- /dev/null +++ b/old/framework/src/vector.rs @@ -0,0 +1,128 @@ +pub type UVec2 = Vec2; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct Vec2 { + pub x: T, + pub y: T, +} + +impl From> for Vec2 { + fn from(value: Vec2) -> Self { + Self { + x: value.x as u16, + y: value.y as u16, + } + } +} +impl From> for Vec2 { + fn from(value: Vec2) -> Self { + Self { + x: value.x as isize, + y: value.y as isize, + } + } +} +impl From> for Vec2 { + fn from(value: Vec2) -> Self { + Self { + x: value.x as isize, + y: value.y as isize, + } + } +} + +impl Vec2 { + pub const ZERO: Vec2 = Vec2 { x: 0, y: 0 }; + pub const UP: Vec2 = Vec2 { x: 0, y: -1 }; + pub const LEFT: Vec2 = Vec2 { x: -1, y: 0 }; +} +impl Vec2 { + pub const ZERO: Vec2 = Vec2 { x: 0.0, y: 0.0 }; + pub const UP: Vec2 = Vec2 { x: 0.0, y: -1.0 }; + pub const LEFT: Vec2 = Vec2 { x: -1.0, y: 0.0 }; +} + +impl + Copy> Vec2 { + pub fn downscale(&self, f: T) -> Self { + Self { + x: self.x / f, + y: self.y / f, + } + } +} + +impl + Copy> Vec2 { + 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 { + 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> for Vec2 { + fn into(self) -> Vec2 { + Vec2 { + x: self.x as f32, + y: self.y as f32, + } + } +} +impl From<(isize, isize)> for Vec2 { + fn from((x, y): (isize, isize)) -> Self { + Vec2 { + x: x as f32, + y: y as f32, + } + } +} + +impl std::ops::Add for Vec2 { + type Output = Vec2; + #[inline] + fn add(self, rhs: Self) -> Self::Output { + Vec2 { + x: self.x + rhs.x, + y: self.y + rhs.y, + } + } +} +impl std::ops::Sub for Vec2 { + type Output = Vec2; + #[inline] + fn sub(self, rhs: Self) -> Self::Output { + Vec2 { + x: self.x - rhs.x, + y: self.y - rhs.y, + } + } +} +impl std::ops::Mul for Vec2 { + type Output = Vec2; + #[inline] + fn mul(self, rhs: Self) -> Self::Output { + Vec2 { + x: self.x * rhs.x, + y: self.y * rhs.y, + } + } +} + +impl From<(T, T)> for Vec2 { + #[inline] + fn from((x, y): (T, T)) -> Self { + Vec2 { x, y } + } +} -- cgit v1.2.3-70-g09d2