From 5248831232fa22a1f3d6515f7f6c7bee8994faf2 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 21 Nov 2022 16:59:50 +0100 Subject: unify repos --- dhwt-codec/src/bin/decode.rs | 54 +++++++++++++++++++++++++++++++++ dhwt-codec/src/bin/encode.rs | 54 +++++++++++++++++++++++++++++++++ dhwt-codec/src/bin/export.rs | 42 ++++++++++++++++++++++++++ dhwt-codec/src/bin/import.rs | 51 +++++++++++++++++++++++++++++++ dhwt-codec/src/io.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++ dhwt-codec/src/lib.rs | 23 ++++++++++++++ dhwt-codec/src/transform.rs | 42 ++++++++++++++++++++++++++ dhwt-codec/src/trim.rs | 36 ++++++++++++++++++++++ dhwt-codec/src/view.rs | 42 ++++++++++++++++++++++++++ 9 files changed, 415 insertions(+) create mode 100644 dhwt-codec/src/bin/decode.rs create mode 100644 dhwt-codec/src/bin/encode.rs create mode 100644 dhwt-codec/src/bin/export.rs create mode 100644 dhwt-codec/src/bin/import.rs create mode 100644 dhwt-codec/src/io.rs create mode 100644 dhwt-codec/src/lib.rs create mode 100644 dhwt-codec/src/transform.rs create mode 100644 dhwt-codec/src/trim.rs create mode 100644 dhwt-codec/src/view.rs (limited to 'dhwt-codec/src') diff --git a/dhwt-codec/src/bin/decode.rs b/dhwt-codec/src/bin/decode.rs new file mode 100644 index 0000000..35881fc --- /dev/null +++ b/dhwt-codec/src/bin/decode.rs @@ -0,0 +1,54 @@ +use clap::Parser; +use dhwt_codec::{ + io::{empty_videobuf, infile, outfile, read_videobuf_small, write_videobuf, VideoBuf}, + transform, trim, + view::{BufferView, IndexMode}, + CommonArgs, +}; +use rayon::prelude::{IntoParallelIterator, ParallelIterator}; + +fn main() { + let args = CommonArgs::parse(); + + let mut inf = infile(&args.infile); + let mut of = outfile(&args.outfile); + + for c in 0..args.channels { + eprintln!("encoding channel #{c}"); + let a = empty_videobuf(args.x, args.y, args.z); + let b = read_videobuf_small(&mut inf); + + eprintln!("\tdecoding Z"); + (0..args.x).into_par_iter().for_each(|x| { + for y in 0..args.y { + run_mode(make_mut(&b), make_mut(&a), IndexMode::XY(x, y), args.z) + } + }); + eprintln!("\tdecoding Y"); + (0..args.x).into_par_iter().for_each(|x| { + for z in 0..args.z { + run_mode(make_mut(&a), make_mut(&b), IndexMode::XZ(x, z), args.y) + } + }); + eprintln!("\tdecoding X"); + (0..args.y).into_par_iter().for_each(|y| { + for z in 0..args.z { + run_mode(make_mut(&b), make_mut(&a), IndexMode::YZ(y, z), args.x) + } + }); + write_videobuf(&mut of, a); + } +} + +fn run_mode(a: &mut VideoBuf, b: &mut VideoBuf, mode: IndexMode, size: usize) { + trim::untrim(size, &mut BufferView::new(b, mode)); + transform::decode( + size, + &mut BufferView::new(a, mode), + &mut BufferView::new(b, mode), + ); +} + +fn make_mut(r: &T) -> &mut T { + unsafe { &mut *((r as *const T) as *mut T) } +} diff --git a/dhwt-codec/src/bin/encode.rs b/dhwt-codec/src/bin/encode.rs new file mode 100644 index 0000000..0e711b0 --- /dev/null +++ b/dhwt-codec/src/bin/encode.rs @@ -0,0 +1,54 @@ +use clap::Parser; +use dhwt_codec::{ + io::{empty_videobuf, infile, outfile, read_videobuf, write_videobuf_small, VideoBuf}, + transform, trim, + view::{BufferView, IndexMode}, + CommonArgs, +}; +use rayon::prelude::{IntoParallelIterator, ParallelIterator}; + +fn main() { + let args = CommonArgs::parse(); + + let mut inf = infile(&args.infile); + let mut of = outfile(&args.outfile); + + for c in 0..args.channels { + eprintln!("encoding channel #{c}"); + let o = empty_videobuf(args.x, args.y, args.z); + let i = read_videobuf(&mut inf); + + eprintln!("\tencoding X"); + (0..args.y).into_par_iter().for_each(|y| { + for z in 0..args.z { + run_mode(make_mut(&i), make_mut(&o), IndexMode::YZ(y, z), args.x) + } + }); + eprintln!("\tencoding Y"); + (0..args.x).into_par_iter().for_each(|x| { + for z in 0..args.z { + run_mode(make_mut(&o), make_mut(&i), IndexMode::XZ(x, z), args.y) + } + }); + eprintln!("\tencoding Z"); + (0..args.x).into_par_iter().for_each(|x| { + for y in 0..args.y { + run_mode(make_mut(&i), make_mut(&o), IndexMode::XY(x, y), args.z) + } + }); + write_videobuf_small(&mut of, o); + } +} + +fn run_mode(a: &mut VideoBuf, b: &mut VideoBuf, mode: IndexMode, size: usize) { + transform::encode( + size, + &mut BufferView::new(a, mode), + &mut BufferView::new(b, mode), + ); + trim::trim(size, &mut BufferView::new(b, mode)); +} + +fn make_mut(r: &T) -> &mut T { + unsafe { &mut *((r as *const T) as *mut T) } +} diff --git a/dhwt-codec/src/bin/export.rs b/dhwt-codec/src/bin/export.rs new file mode 100644 index 0000000..73f3067 --- /dev/null +++ b/dhwt-codec/src/bin/export.rs @@ -0,0 +1,42 @@ +use clap::Parser; +use dhwt_codec::io::{infile, read_videobuf}; +use std::io::{stdout, BufWriter, Write}; + +#[derive(Parser)] +#[clap(about)] +struct ExportArgs { + #[arg(short)] + x: usize, + #[arg(short)] + y: usize, + #[arg(short)] + z: usize, + + #[arg(short, long, default_value = "3")] + channels: usize, + + infile: String, +} + +fn main() { + let args = ExportArgs::parse(); + + let mut i = infile(&args.infile); + let mut writer = BufWriter::new(stdout()); + + let mut channels = vec![]; + for _ in 0..args.channels { + channels.push(read_videobuf(&mut i)) + } + + for z in 0..args.z { + for y in 0..args.y { + for x in 0..args.x { + for c in 0..args.channels { + writer.write_all(&[channels[c][x][y][z] as u8]).unwrap(); + } + } + } + } + writer.flush().unwrap(); +} diff --git a/dhwt-codec/src/bin/import.rs b/dhwt-codec/src/bin/import.rs new file mode 100644 index 0000000..cd2a35e --- /dev/null +++ b/dhwt-codec/src/bin/import.rs @@ -0,0 +1,51 @@ +use clap::Parser; +use dhwt_codec::io::{outfile, write_videobuf, Value}; +use std::io::{stdin, Read}; + +#[derive(Parser)] +#[clap(about)] +struct ImportArgs { + #[arg(short)] + x: usize, + #[arg(short)] + y: usize, + #[arg(short)] + z: usize, + + #[arg(short, long, default_value = "3")] + channels: usize, + + outfile: String, +} + +fn main() { + let args = ImportArgs::parse(); + + let mut rawbuf = (0..(args.x * args.y * args.z * args.channels)) + .map(|_| 0u8) + .collect::>(); + stdin().read_exact(&mut rawbuf).unwrap(); + + let mut o = outfile(&args.outfile); + + for c in 0..args.channels { + let mut cols = vec![]; + for x in 0..args.x { + let mut col = vec![]; + for y in 0..args.y { + let mut span = vec![]; + for z in 0..args.z { + span.push( + rawbuf[c + + (x * args.channels) + + (y * args.channels * args.x) + + (z * args.channels * args.x * args.y)] as Value, + ); + } + col.push(span); + } + cols.push(col) + } + write_videobuf(&mut o, cols) + } +} diff --git a/dhwt-codec/src/io.rs b/dhwt-codec/src/io.rs new file mode 100644 index 0000000..c60bc79 --- /dev/null +++ b/dhwt-codec/src/io.rs @@ -0,0 +1,71 @@ +use bincode::config; +use std::{ + fs::File, + io::{BufReader, BufWriter, Read, Write}, +}; + +pub type Value = f32; +pub type VideoBuf = Vec>>; +pub const ZERO: Value = 0 as Value; +pub const TWO: Value = 2 as Value; + +pub fn empty_videobuf(x: usize, y: usize, z: usize) -> VideoBuf { + (0..x) + .map(|_| (0..y).map(|_| (0..z).map(|_| ZERO).collect()).collect()) + .collect() +} + +pub fn outfile(p: &str) -> impl Write { + BufWriter::new(File::create(p).unwrap()) +} +pub fn infile(p: &str) -> impl Read { + BufReader::new(File::open(p).unwrap()) +} + +pub fn read_videobuf(f: &mut impl Read) -> VideoBuf { + bincode::decode_from_std_read(f, config::standard()).unwrap() +} +pub fn write_videobuf(f: &mut impl Write, i: VideoBuf) { + bincode::encode_into_std_write(i, f, config::standard()).unwrap(); +} + +pub fn write_videobuf_small(f: &mut impl Write, mut i: VideoBuf) { + for _ in 0..(i.len() / 2) { + i.pop(); + } + for i in &mut i { + for _ in 0..(i.len() / 2) { + i.pop(); + } + for i in i { + for _ in 0..(i.len() / 2) { + i.pop(); + } + } + } + write_videobuf(f, i); +} +pub fn read_videobuf_small(f: &mut impl Read) -> VideoBuf { + let mut i = read_videobuf(f); + + for i in &mut i { + for i in i { + for _ in 0..i.len() { + i.push(ZERO); + } + } + } + for i in &mut i { + for _ in 0..i.len() { + i.push((0..i[0].len()).map(|_| ZERO).collect()); + } + } + for _ in 0..i.len() { + i.push( + (0..i[0].len()) + .map(|_| ((0..i[0][0].len()).map(|_| ZERO)).collect()) + .collect(), + ); + } + i +} diff --git a/dhwt-codec/src/lib.rs b/dhwt-codec/src/lib.rs new file mode 100644 index 0000000..69d6b4c --- /dev/null +++ b/dhwt-codec/src/lib.rs @@ -0,0 +1,23 @@ +use clap::Parser; + +pub mod io; +pub mod transform; +pub mod trim; +pub mod view; + +#[derive(Parser)] +#[clap(about)] +pub struct CommonArgs { + #[arg(short)] + pub x: usize, + #[arg(short)] + pub y: usize, + #[arg(short)] + pub z: usize, + + #[arg(short, long, default_value = "3")] + pub channels: usize, + + pub infile: String, + pub outfile: String, +} diff --git a/dhwt-codec/src/transform.rs b/dhwt-codec/src/transform.rs new file mode 100644 index 0000000..82bccd1 --- /dev/null +++ b/dhwt-codec/src/transform.rs @@ -0,0 +1,42 @@ +use crate::io::{Value, TWO}; +use std::ops::{Index, IndexMut}; + +pub fn encode + IndexMut>( + size: usize, + a: &mut X, + b: &mut X, +) { + let mut k = size; + while k != 1 { + k /= 2; + for i in 0..k { + let x = a[i * 2]; + let y = a[i * 2 + 1]; + b[i] = x + y; + b[k + i] = x - y; + } + for i in 0..k { + a[i] = b[i] + } + } +} + +pub fn decode + IndexMut>( + size: usize, + a: &mut X, + b: &mut X, +) { + let mut k = 1; + while k != size { + for i in 0..k { + let avr = a[i] / TWO; + let spread = a[i + k] / TWO; + b[i * 2] = avr + spread; + b[i * 2 + 1] = avr - spread; + } + k *= 2; + for i in 0..k { + a[i] = b[i] + } + } +} diff --git a/dhwt-codec/src/trim.rs b/dhwt-codec/src/trim.rs new file mode 100644 index 0000000..85a920a --- /dev/null +++ b/dhwt-codec/src/trim.rs @@ -0,0 +1,36 @@ +use crate::io::{Value, TWO, ZERO}; +use std::ops::{Index, IndexMut}; + +pub fn trim + IndexMut>( + size: usize, + a: &mut X, +) { + let half = size / 2; + let quarter = size / 4; + for i in 0..(size / 2 / 4) { + let hi = half + i * 4; + let qi = quarter + i * 2; + a[qi] = (a[qi + 0] + a[qi + 1]) / TWO; + a[qi + 1] = (a[hi + 0] + a[hi + 1] + a[hi + 2] + a[hi + 3]) / (TWO * TWO); + } + for i in half..size { + a[i] = ZERO; + } +} + +pub fn untrim + IndexMut>( + size: usize, + a: &mut X, +) { + let half = size / 2; + let quarter = size / 4; + for i in 0..(size / 2 / 4) { + let hi = half + i * 4; + let qi = quarter + i * 2; + a[hi + 0] = a[qi + 1]; + a[hi + 1] = a[qi + 1]; + a[hi + 2] = a[qi + 1]; + a[hi + 3] = a[qi + 1]; + a[qi + 1] = a[qi]; + } +} diff --git a/dhwt-codec/src/view.rs b/dhwt-codec/src/view.rs new file mode 100644 index 0000000..0f2ecf7 --- /dev/null +++ b/dhwt-codec/src/view.rs @@ -0,0 +1,42 @@ +use std::ops::{Index, IndexMut}; + +use crate::io::{VideoBuf, Value}; + +#[derive(Copy, Clone, Debug)] +pub enum IndexMode { + XY(usize, usize), + XZ(usize, usize), + YZ(usize, usize), +} + +pub struct BufferView<'a> { + mode: IndexMode, + buf: &'a mut VideoBuf, +} + +impl<'a> BufferView<'a> { + pub fn new(buf: &'a mut VideoBuf, mode: IndexMode) -> Self { + BufferView { mode, buf } + } +} + +impl Index for BufferView<'_> { + type Output = Value; + + fn index(&self, a: usize) -> &Self::Output { + match self.mode { + IndexMode::XY(x, y) => &self.buf[x][y][a], + IndexMode::XZ(x, z) => &self.buf[x][a][z], + IndexMode::YZ(y, z) => &self.buf[a][y][z], + } + } +} +impl IndexMut for BufferView<'_> { + fn index_mut(&mut self, a: usize) -> &mut Self::Output { + match self.mode { + IndexMode::XY(x, y) => &mut self.buf[x][y][a], + IndexMode::XZ(x, z) => &mut self.buf[x][a][z], + IndexMode::YZ(y, z) => &mut self.buf[a][y][z], + } + } +} -- cgit v1.2.3-70-g09d2