aboutsummaryrefslogtreecommitdiff
path: root/evc/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2022-12-05 20:29:05 +0100
committermetamuffin <metamuffin@disroot.org>2022-12-05 20:29:05 +0100
commit96e316ea16b7b915e02735457d5ac7495d3db305 (patch)
treee2ef2957009dd96c452fb8a80020ed83caa70993 /evc/src
parent75b87762196c461069fa087f8aa3c978d7407549 (diff)
downloadvideo-codec-experiments-96e316ea16b7b915e02735457d5ac7495d3db305.tar
video-codec-experiments-96e316ea16b7b915e02735457d5ac7495d3db305.tar.bz2
video-codec-experiments-96e316ea16b7b915e02735457d5ac7495d3db305.tar.zst
serialization
Diffstat (limited to 'evc/src')
-rw-r--r--evc/src/bin/encode.rs20
-rw-r--r--evc/src/block.rs69
-rw-r--r--evc/src/header.rs4
-rw-r--r--evc/src/lib.rs5
-rw-r--r--evc/src/ser.rs154
5 files changed, 252 insertions, 0 deletions
diff --git a/evc/src/bin/encode.rs b/evc/src/bin/encode.rs
new file mode 100644
index 0000000..88023b3
--- /dev/null
+++ b/evc/src/bin/encode.rs
@@ -0,0 +1,20 @@
+use std::io::BufReader;
+
+use clap::Parser;
+use evc::ser::Source;
+
+#[derive(Parser)]
+#[clap(about, version)]
+pub struct EncodeArgs {
+ #[arg(short, long)]
+ width: usize,
+ #[arg(short, long)]
+ height: usize,
+}
+
+fn main() {
+ let mut input = BufReader::new(std::io::stdin());
+
+
+
+}
diff --git a/evc/src/block.rs b/evc/src/block.rs
new file mode 100644
index 0000000..29dd4ba
--- /dev/null
+++ b/evc/src/block.rs
@@ -0,0 +1,69 @@
+use crate::ser::{Ser, Sink, Source};
+
+#[derive(Copy, Clone, Debug)]
+pub struct Pixel {
+ pub r: u8,
+ pub g: u8,
+ pub b: u8,
+}
+
+#[derive(Clone, Debug)]
+pub struct Block {
+ size: (usize, usize),
+ inner: BlockInner,
+}
+
+#[derive(Clone, Debug)]
+pub enum BlockInner {
+ Literal(Vec<Pixel>),
+ Split(Box<[Block; 2]>),
+ Reference { translation: (usize, usize) },
+}
+
+impl Block {
+ pub fn write(&self, sink: &mut impl std::io::Write) -> std::io::Result<()> {
+ match &self.inner {
+ BlockInner::Literal(pixels) => {
+ sink.put(0u8)?;
+ pixels.write(sink)?;
+ }
+ BlockInner::Split(box [a, b]) => {
+ sink.put(1u8)?;
+ a.write(sink)?;
+ b.write(sink)?;
+ }
+ BlockInner::Reference { translation } => {
+ sink.put(2u8)?;
+ }
+ }
+ Ok(())
+ }
+
+ pub fn read(source: &mut impl std::io::Read, size: (usize, usize)) -> std::io::Result<Self> {
+ let inner = match source.get::<u8>()? {
+ 0 => BlockInner::Literal(source.get()?),
+ 1 => BlockInner::Split(Box::new({
+ let subsize = if size.0 > size.1 {
+ (size.0 / 2, size.1)
+ } else {
+ (size.0, size.1 / 2)
+ };
+ [Block::read(source, subsize)?, Block::read(source, subsize)?]
+ })),
+ 2 => todo!(),
+ _ => panic!("file corrupt"),
+ };
+
+ Ok(Self { size, inner })
+ }
+}
+impl Ser for Pixel {
+ fn write(&self, sink: &mut impl std::io::Write) -> std::io::Result<()> {
+ sink.put((self.r, self.g, self.b))
+ }
+
+ fn read(source: &mut impl std::io::Read) -> std::io::Result<Self> {
+ let (r, g, b) = source.get()?;
+ Ok(Self { r, g, b })
+ }
+}
diff --git a/evc/src/header.rs b/evc/src/header.rs
new file mode 100644
index 0000000..2b2725c
--- /dev/null
+++ b/evc/src/header.rs
@@ -0,0 +1,4 @@
+
+pub struct Header {
+
+}
diff --git a/evc/src/lib.rs b/evc/src/lib.rs
new file mode 100644
index 0000000..3270ebb
--- /dev/null
+++ b/evc/src/lib.rs
@@ -0,0 +1,5 @@
+#![feature(box_patterns)]
+
+pub mod ser;
+pub mod block;
+pub mod header;
diff --git a/evc/src/ser.rs b/evc/src/ser.rs
new file mode 100644
index 0000000..05072b2
--- /dev/null
+++ b/evc/src/ser.rs
@@ -0,0 +1,154 @@
+use std::io::{self, Read, Write};
+
+pub trait Sink {
+ fn put<V: Ser>(&mut self, value: V) -> io::Result<()>;
+}
+pub trait Source {
+ fn get<V: Ser>(&mut self) -> io::Result<V>;
+}
+
+impl<T: Write> Sink for T {
+ fn put<V: Ser>(&mut self, value: V) -> io::Result<()> {
+ value.write(self)
+ }
+}
+impl<T: Read> Source for T {
+ fn get<V: Ser>(&mut self) -> io::Result<V> {
+ V::read(self)
+ }
+}
+
+pub trait Ser: Sized {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()>;
+ fn read(source: &mut impl Read) -> io::Result<Self>;
+}
+
+impl<A: Ser, B: Ser> Ser for (A, B) {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ self.0.write(sink)?;
+ self.1.write(sink)?;
+ Ok(())
+ }
+
+ fn read(source: &mut impl Read) -> io::Result<Self> {
+ Ok((A::read(source)?, B::read(source)?))
+ }
+}
+impl<A: Ser, B: Ser, C: Ser> Ser for (A, B, C) {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ self.0.write(sink)?;
+ self.1.write(sink)?;
+ self.2.write(sink)?;
+ Ok(())
+ }
+
+ fn read(source: &mut impl Read) -> io::Result<Self> {
+ Ok((A::read(source)?, B::read(source)?, C::read(source)?))
+ }
+}
+
+impl<A: Ser, const N: usize> Ser for [A; N] {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ for e in self {
+ e.write(sink)?;
+ }
+ Ok(())
+ }
+
+ fn read(source: &mut impl Read) -> io::Result<Self> {
+ let mut k: [A; N] = unsafe { std::mem::zeroed() };
+ for i in 0..N {
+ k[i] = A::read(source)?;
+ }
+ Ok(k)
+ }
+}
+
+impl<T: Ser> Ser for Vec<T> {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ self.len().write(sink)?;
+ for e in self {
+ e.write(sink)?;
+ }
+ Ok(())
+ }
+
+ fn read(source: &mut impl Read) -> io::Result<Self> {
+ let mut v = vec![];
+ for _ in 0..usize::read(source)? {
+ v.push(T::read(source)?)
+ }
+ Ok(v)
+ }
+}
+
+impl Ser for u8 {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ sink.write_all(&[*self])
+ }
+ fn read(source: &mut impl Read) -> io::Result<Self> {
+ let mut buf = [0u8; 1];
+ source.read_exact(&mut buf)?;
+ Ok(buf[0])
+ }
+}
+impl Ser for u16 {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 2]>(self) })
+ }
+ fn read(source: &mut impl Read) -> io::Result<Self> {
+ let mut buf = [0u8; 2];
+ source.read_exact(&mut buf)?;
+ Ok(unsafe { std::mem::transmute_copy(&buf) })
+ }
+}
+impl Ser for u32 {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) })
+ }
+ fn read(source: &mut impl Read) -> io::Result<Self> {
+ let mut buf = [0u8; 4];
+ source.read_exact(&mut buf)?;
+ Ok(unsafe { std::mem::transmute_copy(&buf) })
+ }
+}
+impl Ser for u64 {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ }
+ fn read(source: &mut impl Read) -> io::Result<Self> {
+ let mut buf = [0u8; 8];
+ source.read_exact(&mut buf)?;
+ Ok(unsafe { std::mem::transmute_copy(&buf) })
+ }
+}
+impl Ser for usize {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ }
+ fn read(source: &mut impl Read) -> io::Result<Self> {
+ let mut buf = [0u8; 8];
+ source.read_exact(&mut buf)?;
+ Ok(unsafe { std::mem::transmute_copy(&buf) })
+ }
+}
+impl Ser for f32 {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) })
+ }
+ fn read(source: &mut impl Read) -> io::Result<Self> {
+ let mut buf = [0u8; 4];
+ source.read_exact(&mut buf)?;
+ Ok(unsafe { std::mem::transmute_copy(&buf) })
+ }
+}
+impl Ser for f64 {
+ fn write(&self, sink: &mut impl Write) -> io::Result<()> {
+ sink.write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ }
+ fn read(source: &mut impl Read) -> io::Result<Self> {
+ let mut buf = [0u8; 8];
+ source.read_exact(&mut buf)?;
+ Ok(unsafe { std::mem::transmute_copy(&buf) })
+ }
+}