aboutsummaryrefslogtreecommitdiff
path: root/old/evc/src/format
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 /old/evc/src/format
parent9cc089e2d6e841879e430b01d2f3d92c8820523e (diff)
downloadvideo-codec-experiments-306f96164784a8cbf405e72fa4364d6523366e95.tar
video-codec-experiments-306f96164784a8cbf405e72fa4364d6523366e95.tar.bz2
video-codec-experiments-306f96164784a8cbf405e72fa4364d6523366e95.tar.zst
old dir
Diffstat (limited to 'old/evc/src/format')
-rw-r--r--old/evc/src/format/header.rs29
-rw-r--r--old/evc/src/format/mod.rs2
-rw-r--r--old/evc/src/format/ser.rs335
3 files changed, 366 insertions, 0 deletions
diff --git a/old/evc/src/format/header.rs b/old/evc/src/format/header.rs
new file mode 100644
index 0000000..ecbae89
--- /dev/null
+++ b/old/evc/src/format/header.rs
@@ -0,0 +1,29 @@
+use crate::{
+ format::ser::{Ser, Sink, Source},
+ helpers::vector::Vec2,
+};
+
+#[derive(Debug, Clone, PartialEq, Copy)]
+pub struct Header {
+ pub resolution: Vec2<isize>,
+ pub frame_count: usize,
+}
+
+pub const MAGIC: [u8; 4] = [0x5eu8, 0xb1u8, 0xc3u8, 0x08u8];
+
+impl Ser for Header {
+ fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> {
+ sink.put(MAGIC)?;
+ sink.put((Into::<Vec2<u16>>::into(self.resolution), self.frame_count))?;
+ Ok(())
+ }
+
+ fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> {
+ assert_eq!(source.get::<[u8; 4]>()?, MAGIC);
+ let (resolution, frame_count): (Vec2<u16>, usize) = source.get()?;
+ Ok(Self {
+ resolution: resolution.into(),
+ frame_count,
+ })
+ }
+}
diff --git a/old/evc/src/format/mod.rs b/old/evc/src/format/mod.rs
new file mode 100644
index 0000000..d4fb18c
--- /dev/null
+++ b/old/evc/src/format/mod.rs
@@ -0,0 +1,2 @@
+pub mod header;
+pub mod ser; \ No newline at end of file
diff --git a/old/evc/src/format/ser.rs b/old/evc/src/format/ser.rs
new file mode 100644
index 0000000..f063377
--- /dev/null
+++ b/old/evc/src/format/ser.rs
@@ -0,0 +1,335 @@
+use anyhow::Context;
+use std::io::{Read, Write};
+
+use crate::helpers::{matrix::Mat2, vector::Vec2};
+
+pub trait Sink {
+ fn put<V: Ser>(&mut self, value: V) -> anyhow::Result<()>;
+}
+pub trait Source {
+ fn get<V: Ser>(&mut self) -> anyhow::Result<V>;
+}
+
+impl<T: Write> Sink for T {
+ fn put<V: Ser>(&mut self, value: V) -> anyhow::Result<()> {
+ value.write(self)
+ }
+}
+impl<T: Read> Source for T {
+ fn get<V: Ser>(&mut self) -> anyhow::Result<V> {
+ V::read(self)
+ }
+}
+
+pub trait Ser: Sized {
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()>;
+ fn read(source: &mut impl Read) -> anyhow::Result<Self>;
+}
+
+impl<A: Ser, B: Ser> Ser for (A, B) {
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ self.0.write(sink).context("first tuple field")?;
+ self.1.write(sink).context("second tuple field")?;
+ Ok(())
+ }
+
+ fn read(source: &mut impl Read) -> anyhow::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) -> anyhow::Result<()> {
+ self.0.write(sink).context("first tuple field")?;
+ self.1.write(sink).context("second tuple field")?;
+ self.2.write(sink).context("third tuple field")?;
+ Ok(())
+ }
+
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
+ Ok((A::read(source)?, B::read(source)?, C::read(source)?))
+ }
+}
+impl<A: Ser, B: Ser, C: Ser, D: Ser> Ser for (A, B, C, D) {
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ self.0.write(sink).context("first tuple field")?;
+ self.1.write(sink).context("second tuple field")?;
+ self.2.write(sink).context("third tuple field")?;
+ self.3.write(sink).context("fourth tuple field")?;
+ Ok(())
+ }
+
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
+ Ok((
+ A::read(source)?,
+ B::read(source)?,
+ C::read(source)?,
+ D::read(source)?,
+ ))
+ }
+}
+
+impl<A: Ser, const N: usize> Ser for [A; N] {
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ for e in self {
+ e.write(sink).context("some array")?;
+ }
+ Ok(())
+ }
+
+ fn read(source: &mut impl Read) -> anyhow::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) -> anyhow::Result<()> {
+ self.len().write(sink)?;
+ for e in self {
+ e.write(sink).context("some vec")?;
+ }
+ Ok(())
+ }
+
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
+ let mut v = vec![];
+ for _ in 0..usize::read(source)? {
+ v.push(T::read(source)?)
+ }
+ Ok(v)
+ }
+}
+
+pub trait ConstSizeSerExt: Sized {
+ fn write_const_size(&self, sink: &mut impl Write, size: usize) -> anyhow::Result<()>;
+ fn read_const_size(source: &mut impl Read, size: usize) -> anyhow::Result<Self>;
+}
+impl<T: Ser> ConstSizeSerExt for Vec<T> {
+ fn write_const_size(&self, sink: &mut impl Write, size: usize) -> anyhow::Result<()> {
+ assert_eq!(self.len(), size);
+ for e in self {
+ e.write(sink).context("some const-size vec")?;
+ }
+ Ok(())
+ }
+
+ fn read_const_size(source: &mut impl Read, size: usize) -> anyhow::Result<Self> {
+ let mut v = vec![];
+ for _ in 0..size {
+ v.push(T::read(source)?)
+ }
+ Ok(v)
+ }
+}
+
+impl Ser for u8 {
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ Ok(sink.write_all(&[*self]).context("write u8")?)
+ }
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
+ let mut buf = [0u8; 1];
+ source.read_exact(&mut buf)?;
+ Ok(buf[0])
+ }
+}
+impl Ser for i8 {
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 1]>(self) })
+ .context("write i8")?)
+ }
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
+ let mut buf = [0u8; 1];
+ source.read_exact(&mut buf)?;
+ Ok(unsafe { std::mem::transmute_copy(&buf) })
+ }
+}
+impl Ser for u16 {
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 2]>(self) })
+ .context("write u16")?)
+ }
+ fn read(source: &mut impl Read) -> anyhow::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) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) })
+ .context("write u32")?)
+ }
+ fn read(source: &mut impl Read) -> anyhow::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) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ .context("write u64")?)
+ }
+ fn read(source: &mut impl Read) -> anyhow::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) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ .context("write usize")?)
+ }
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
+ let mut buf = [0u8; 8];
+ source.read_exact(&mut buf)?;
+ Ok(unsafe { std::mem::transmute_copy(&buf) })
+ }
+}
+impl Ser for isize {
+ fn write(&self, sink: &mut impl Write) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ .context("write isize")?)
+ }
+ fn read(source: &mut impl Read) -> anyhow::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) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 4]>(self) })
+ .context("write f32")?)
+ }
+ fn read(source: &mut impl Read) -> anyhow::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) -> anyhow::Result<()> {
+ Ok(sink
+ .write_all(&unsafe { std::mem::transmute_copy::<_, [u8; 8]>(self) })
+ .context("write f64")?)
+ }
+ fn read(source: &mut impl Read) -> anyhow::Result<Self> {
+ let mut buf = [0u8; 8];
+ source.read_exact(&mut buf)?;
+ Ok(unsafe { std::mem::transmute_copy(&buf) })
+ }
+}
+
+impl<T: Ser + Copy> Ser for Vec2<T> {
+ fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> {
+ sink.put((self.x, self.y))
+ }
+
+ fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> {
+ let (x, y) = source.get()?;
+ Ok(Vec2 { x, y })
+ }
+}
+impl<T: Ser + Copy> Ser for Mat2<T> {
+ fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> {
+ sink.put((self.a, self.b, self.c, self.d))
+ }
+
+ fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> {
+ let (a, b, c, d) = source.get()?;
+ Ok(Mat2 { a, b, c, d })
+ }
+}
+
+pub struct Small<T>(pub T);
+impl Ser for Small<Vec2<isize>> {
+ fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> {
+ sink.put((self.0.x as i8, self.0.y as i8))
+ }
+
+ fn read(source: &mut impl std::io::Read) -> anyhow::Result<Self> {
+ let (x, y): (i8, i8) = source.get()?;
+ Ok(Small(Vec2 {
+ x: x as isize,
+ y: y as isize,
+ }))
+ }
+}
+
+pub fn map_scalar8(v: i8) -> f32 {
+ match v {
+ 0 => 0.0,
+ x if x > 0 => 2f32.powf((x as f32).abs() / 2.0 - 2.0),
+ x => -2f32.powf((-x as f32).abs() / 2.0 - 2.0),
+ }
+}
+// const SCALAR8: [f32; 256] = gen_scalar8_lookup();
+// const fn gen_scalar8_lookup() -> [f32; 256] {
+// let mut a = [0.0; 256];
+// let mut i = 0usize;
+// while i < 256 {
+// a[i as usize] = if i == 0 {
+// 0.0
+// } else {
+// let x = i as i8 as f32;
+// x.signum() * 2f32.powf(x.abs() / 2.0 - 2.0)
+// };
+// i += 1;
+// }
+// a
+// }
+
+#[cfg(test)]
+mod test {
+ use super::{Ser, Sink};
+ use crate::format::header::Header;
+ use crate::{format::ser::Source, helpers::vector::Vec2};
+ use std::fmt::Debug;
+ use std::io::Cursor;
+
+ fn test_ser<T: PartialEq + Ser + Debug + Clone>(value: T) {
+ let mut buf = vec![];
+ Cursor::new(&mut buf).put(value.clone()).unwrap();
+ assert_eq!(value, Cursor::new(&mut buf).get().unwrap());
+ }
+
+ #[test]
+ fn simple() {
+ let mut buf = vec![];
+ Cursor::new(&mut buf).put(10usize).unwrap();
+ assert_eq!(10usize, Cursor::new(&mut buf).get().unwrap());
+ }
+ #[test]
+ fn tuple() {
+ let mut buf = vec![];
+ Cursor::new(&mut buf).put((10usize, 5u8, 3u16)).unwrap();
+ assert_eq!((10usize, 5u8, 3u16), Cursor::new(&mut buf).get().unwrap());
+ }
+ #[test]
+ fn header() {
+ test_ser(Header {
+ frame_count: 123,
+ resolution: Vec2 { x: 13, y: 37 },
+ });
+ }
+ #[test]
+ fn vec() {
+ test_ser(vec![1u16, 2, 3, 4]);
+ }
+ #[test]
+ fn array() {
+ test_ser([1u16, 2, 3, 4]);
+ }
+}