From 8ca219c6b0d5448fd4529713ccd093e89de4e252 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Wed, 7 Dec 2022 17:55:27 +0100 Subject: refactor --- evc/src/bin/decode.rs | 8 +- evc/src/bin/encode.rs | 3 +- evc/src/block.rs | 6 +- evc/src/codec/encode.rs | 4 +- evc/src/debug.rs | 2 +- evc/src/format/header.rs | 29 +++++ evc/src/format/mod.rs | 2 + evc/src/format/ser.rs | 264 ++++++++++++++++++++++++++++++++++++++++++++++ evc/src/frame.rs | 5 +- evc/src/header.rs | 29 ----- evc/src/helpers/mod.rs | 3 +- evc/src/helpers/pixel.rs | 67 ++++++++++++ evc/src/helpers/vector.rs | 29 ----- evc/src/lib.rs | 4 +- evc/src/pixel.rs | 60 ----------- evc/src/refsampler.rs | 17 ++- evc/src/ser.rs | 235 ----------------------------------------- evc/src/view.rs | 5 +- 18 files changed, 397 insertions(+), 375 deletions(-) create mode 100644 evc/src/format/header.rs create mode 100644 evc/src/format/mod.rs create mode 100644 evc/src/format/ser.rs delete mode 100644 evc/src/header.rs create mode 100644 evc/src/helpers/pixel.rs delete mode 100644 evc/src/pixel.rs delete mode 100644 evc/src/ser.rs (limited to 'evc/src') diff --git a/evc/src/bin/decode.rs b/evc/src/bin/decode.rs index b15467f..b7dd4e1 100644 --- a/evc/src/bin/decode.rs +++ b/evc/src/bin/decode.rs @@ -2,8 +2,12 @@ use anyhow::Context; use clap::Parser; use evc::{ - block::Block, codec::decode::decode_block, frame::Frame, header::Header, pixel::Pixel, - ser::Source, view::View, + block::Block, + codec::decode::decode_block, + format::{header::Header, ser::Source}, + frame::Frame, + helpers::pixel::Pixel, + view::View, }; use log::info; use std::io::{BufReader, BufWriter}; diff --git a/evc/src/bin/encode.rs b/evc/src/bin/encode.rs index 611347f..f81bb5e 100644 --- a/evc/src/bin/encode.rs +++ b/evc/src/bin/encode.rs @@ -5,10 +5,9 @@ use evc::{ decode::decode_block, encode::{encode_block, EncodeConfig}, }, + format::{header::Header, ser::Sink}, frame::Frame, - header::Header, helpers::vector::Vec2, - ser::Sink, }; use log::info; use std::io::{BufReader, BufWriter}; diff --git a/evc/src/block.rs b/evc/src/block.rs index dd23207..3a37820 100644 --- a/evc/src/block.rs +++ b/evc/src/block.rs @@ -1,9 +1,9 @@ use anyhow::bail; use crate::{ - pixel::Pixel, - ser::{Ser, Sink, Source}, - helpers::vector::{Small, Vec2}, + format::ser::{Ser, Sink, Source, Small}, + helpers::pixel::Pixel, + helpers::vector::Vec2, }; #[derive(Clone, Debug)] diff --git a/evc/src/codec/encode.rs b/evc/src/codec/encode.rs index ce5d71b..b11bbc0 100644 --- a/evc/src/codec/encode.rs +++ b/evc/src/codec/encode.rs @@ -1,5 +1,7 @@ use crate::{ - block::Block, frame::Frame, helpers::threading::both_par, helpers::vector::Vec2, pixel::Pixel, + block::Block, + frame::Frame, + helpers::{pixel::Pixel, threading::both_par, vector::Vec2}, view::View, }; diff --git a/evc/src/debug.rs b/evc/src/debug.rs index d2102ba..fb2b53d 100644 --- a/evc/src/debug.rs +++ b/evc/src/debug.rs @@ -1,4 +1,4 @@ -use crate::{frame::Frame, helpers::vector::Vec2, pixel::Pixel, view::View}; +use crate::{frame::Frame, helpers::pixel::Pixel, helpers::vector::Vec2, view::View}; impl View<&mut Frame> { pub fn draw_box(&mut self, color: Pixel) { diff --git a/evc/src/format/header.rs b/evc/src/format/header.rs new file mode 100644 index 0000000..371b4ba --- /dev/null +++ b/evc/src/format/header.rs @@ -0,0 +1,29 @@ +use crate::{ + helpers::vector::Vec2, + format::ser::{Ser, Sink, Source}, +}; + +#[derive(Debug, Clone, PartialEq, Copy)] +pub struct Header { + pub resolution: Vec2, + 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((self.resolution, self.frame_count))?; + Ok(()) + } + + fn read(source: &mut impl std::io::Read) -> anyhow::Result { + assert_eq!(source.get::<[u8; 4]>()?, MAGIC); + let (resolution, frame_count) = source.get()?; + Ok(Self { + resolution, + frame_count, + }) + } +} diff --git a/evc/src/format/mod.rs b/evc/src/format/mod.rs new file mode 100644 index 0000000..d4fb18c --- /dev/null +++ b/evc/src/format/mod.rs @@ -0,0 +1,2 @@ +pub mod header; +pub mod ser; \ No newline at end of file diff --git a/evc/src/format/ser.rs b/evc/src/format/ser.rs new file mode 100644 index 0000000..65d5e26 --- /dev/null +++ b/evc/src/format/ser.rs @@ -0,0 +1,264 @@ +use anyhow::Context; +use std::io::{Read, Write}; + +use crate::helpers::vector::Vec2; + +pub trait Sink { + fn put(&mut self, value: V) -> anyhow::Result<()>; +} +pub trait Source { + fn get(&mut self) -> anyhow::Result; +} + +impl Sink for T { + fn put(&mut self, value: V) -> anyhow::Result<()> { + value.write(self) + } +} +impl Source for T { + fn get(&mut self) -> anyhow::Result { + V::read(self) + } +} + +pub trait Ser: Sized { + fn write(&self, sink: &mut impl Write) -> anyhow::Result<()>; + fn read(source: &mut impl Read) -> anyhow::Result; +} + +impl 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 { + Ok((A::read(source)?, B::read(source)?)) + } +} +impl 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 { + Ok((A::read(source)?, B::read(source)?, C::read(source)?)) + } +} + +impl 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 { + let mut k: [A; N] = unsafe { std::mem::zeroed() }; + for i in 0..N { + k[i] = A::read(source)?; + } + Ok(k) + } +} + +impl Ser for Vec { + 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 { + 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) -> anyhow::Result<()> { + Ok(sink.write_all(&[*self]).context("write u8")?) + } + fn read(source: &mut impl Read) -> anyhow::Result { + 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 { + 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 16")?) + } + fn read(source: &mut impl Read) -> anyhow::Result { + 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 { + 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 { + 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 { + 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 { + 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 { + 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 { + let mut buf = [0u8; 8]; + source.read_exact(&mut buf)?; + Ok(unsafe { std::mem::transmute_copy(&buf) }) + } +} + + +impl Ser for Vec2 { + 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 { + let (x, y) = source.get()?; + Ok(Vec2 { x, y }) + } +} + +pub struct Small(pub T); +impl Ser for Small> { + 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 { + let (x, y): (i8, i8) = source.get()?; + Ok(Small(Vec2 { + x: x as isize, + y: y as isize, + })) + } +} + + +#[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(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]); + } +} diff --git a/evc/src/frame.rs b/evc/src/frame.rs index 024b240..e1c3a6e 100644 --- a/evc/src/frame.rs +++ b/evc/src/frame.rs @@ -1,7 +1,6 @@ use crate::{ - helpers::vector::Vec2, - pixel::Pixel, - ser::{Sink, Source}, + format::ser::{Sink, Source}, + helpers::{pixel::Pixel, vector::Vec2}, view::View, }; use std::ops::{Index, IndexMut}; diff --git a/evc/src/header.rs b/evc/src/header.rs deleted file mode 100644 index 4c9118e..0000000 --- a/evc/src/header.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::{ - helpers::vector::Vec2, - ser::{Ser, Sink, Source}, -}; - -#[derive(Debug, Clone, PartialEq, Copy)] -pub struct Header { - pub resolution: Vec2, - 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((self.resolution, self.frame_count))?; - Ok(()) - } - - fn read(source: &mut impl std::io::Read) -> anyhow::Result { - assert_eq!(source.get::<[u8; 4]>()?, MAGIC); - let (resolution, frame_count) = source.get()?; - Ok(Self { - resolution, - frame_count, - }) - } -} diff --git a/evc/src/helpers/mod.rs b/evc/src/helpers/mod.rs index c5eed9d..d3aa3d2 100644 --- a/evc/src/helpers/mod.rs +++ b/evc/src/helpers/mod.rs @@ -1,3 +1,4 @@ pub mod vector; pub mod threading; -pub mod matrix; \ No newline at end of file +pub mod matrix; +pub mod pixel; diff --git a/evc/src/helpers/pixel.rs b/evc/src/helpers/pixel.rs new file mode 100644 index 0000000..7b7c8d5 --- /dev/null +++ b/evc/src/helpers/pixel.rs @@ -0,0 +1,67 @@ +use crate::format::ser::{Ser, Sink, Source}; + +#[derive(Copy, Clone, Debug, Default)] +pub struct Pixel { + pub r: u8, + pub g: u8, + pub b: u8, +} + +impl Ser for Pixel { + fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> { + sink.put((self.r, self.g, self.b)) + } + + fn read(source: &mut impl std::io::Read) -> anyhow::Result { + let (r, g, b) = source.get()?; + Ok(Self { r, g, b }) + } +} + +impl Pixel { + pub const BLACK: Pixel = Pixel { r: 0, g: 0, b: 0 }; + #[inline] + pub fn distance(a: Pixel, b: Pixel) -> usize { + let (rd, gd, bd) = ( + a.r.abs_diff(b.r) as usize, + a.r.abs_diff(b.r) as usize, + a.r.abs_diff(b.r) as usize, + ); + SQRT[rd + gd + bd] + } + #[inline] + pub fn average(a: Pixel, b: Pixel) -> Pixel { + Pixel { + r: (a.r >> 2) + (b.r >> 2), + g: (a.g >> 2) + (b.g >> 2), + b: (a.b >> 2) + (b.b >> 2), + } + } + pub fn scale(&self, factor: f32) -> Pixel { + Pixel { + r: ((self.r as f32) * factor).clamp(0.0, 255.0) as u8, + g: ((self.g as f32) * factor).clamp(0.0, 255.0) as u8, + b: ((self.b as f32) * factor).clamp(0.0, 255.0) as u8, + } + } +} + +const SQRT: [usize; 256 * 3] = gen_sqrt_lookup(); + +const fn gen_sqrt_lookup() -> [usize; N] { + let mut arr = [0; N]; + let mut i = 0; + while i < N { + arr[i] = sqrt(i as f32) as usize; + i += 1; + } + arr +} + +const fn sqrt(x: f32) -> f32 { + let a = 1.0; + let a = (a + x / a) * 0.5; + let a = (a + x / a) * 0.5; + let a = (a + x / a) * 0.5; + a +} diff --git a/evc/src/helpers/vector.rs b/evc/src/helpers/vector.rs index 9e7369e..4daa849 100644 --- a/evc/src/helpers/vector.rs +++ b/evc/src/helpers/vector.rs @@ -1,5 +1,3 @@ -use crate::ser::{Ser, Sink, Source}; - #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Vec2 { pub x: T, @@ -26,32 +24,6 @@ impl + Copy> Vec2 { } } -impl Ser for Vec2 { - 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 { - let (x, y) = source.get()?; - Ok(Vec2 { x, y }) - } -} - -pub struct Small(pub T); -impl Ser for Small> { - 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 { - let (x, y): (i8, i8) = source.get()?; - Ok(Small(Vec2 { - x: x as isize, - y: y as isize, - })) - } -} - impl std::ops::Add for Vec2 { type Output = Vec2; #[inline] @@ -89,4 +61,3 @@ impl From<(T, T)> for Vec2 { Vec2 { x, y } } } - diff --git a/evc/src/lib.rs b/evc/src/lib.rs index ffacf59..d269471 100644 --- a/evc/src/lib.rs +++ b/evc/src/lib.rs @@ -7,9 +7,7 @@ pub mod block; pub mod codec; pub mod debug; pub mod frame; -pub mod header; -pub mod pixel; -pub mod ser; pub mod view; pub mod refsampler; pub mod helpers; +pub mod format; diff --git a/evc/src/pixel.rs b/evc/src/pixel.rs deleted file mode 100644 index 121cb95..0000000 --- a/evc/src/pixel.rs +++ /dev/null @@ -1,60 +0,0 @@ -use crate::ser::{Ser, Sink, Source}; - -#[derive(Copy, Clone, Debug, Default)] -pub struct Pixel { - pub r: u8, - pub g: u8, - pub b: u8, -} - -impl Ser for Pixel { - fn write(&self, sink: &mut impl std::io::Write) -> anyhow::Result<()> { - sink.put((self.r, self.g, self.b)) - } - - fn read(source: &mut impl std::io::Read) -> anyhow::Result { - let (r, g, b) = source.get()?; - Ok(Self { r, g, b }) - } -} - -impl Pixel { - pub const BLACK: Pixel = Pixel { r: 0, g: 0, b: 0 }; - #[inline] - pub fn distance(a: Pixel, b: Pixel) -> usize { - let (rd, gd, bd) = ( - a.r.abs_diff(b.r) as usize, - a.r.abs_diff(b.r) as usize, - a.r.abs_diff(b.r) as usize, - ); - SQRT[rd + gd + bd] - } - #[inline] - pub fn average(a: Pixel, b: Pixel) -> Pixel { - Pixel { - r: (a.r >> 2) + (b.r >> 2), - g: (a.g >> 2) + (b.g >> 2), - b: (a.b >> 2) + (b.b >> 2), - } - } -} - -const SQRT: [usize; 256 * 3] = gen_sqrt_lookup(); - -const fn gen_sqrt_lookup() -> [usize; N] { - let mut arr = [0; N]; - let mut i = 0; - while i < N { - arr[i] = sqrt(i as f32) as usize; - i += 1; - } - arr -} - -const fn sqrt(x: f32) -> f32 { - let a = 1.0; - let a = (a + x / a) * 0.5; - let a = (a + x / a) * 0.5; - let a = (a + x / a) * 0.5; - a -} diff --git a/evc/src/refsampler.rs b/evc/src/refsampler.rs index 95e123b..db0ab6f 100644 --- a/evc/src/refsampler.rs +++ b/evc/src/refsampler.rs @@ -1,14 +1,21 @@ -use crate::{helpers::{matrix::Mat2, vector::Vec2}, frame::Frame}; +use crate::{ + frame::Frame, + helpers::{matrix::Mat2, pixel::Pixel, vector::Vec2}, +}; + +pub struct Sampler<'a> { + frame: &'a Frame, -pub struct Sampler { translation: Vec2, transform: Mat2, value_scale: f32, } -impl Sampler { - pub fn sample(&self, frame: &Frame, p: Vec2) { - +impl Sampler<'_> { + pub fn sample(&self, p: Vec2) -> Pixel { + self.frame + .sample(self.translation + self.transform.transform(p)) + .scale(self.value_scale) } } diff --git a/evc/src/ser.rs b/evc/src/ser.rs deleted file mode 100644 index d05e42e..0000000 --- a/evc/src/ser.rs +++ /dev/null @@ -1,235 +0,0 @@ -use anyhow::Context; -use std::io::{Read, Write}; - -pub trait Sink { - fn put(&mut self, value: V) -> anyhow::Result<()>; -} -pub trait Source { - fn get(&mut self) -> anyhow::Result; -} - -impl Sink for T { - fn put(&mut self, value: V) -> anyhow::Result<()> { - value.write(self) - } -} -impl Source for T { - fn get(&mut self) -> anyhow::Result { - V::read(self) - } -} - -pub trait Ser: Sized { - fn write(&self, sink: &mut impl Write) -> anyhow::Result<()>; - fn read(source: &mut impl Read) -> anyhow::Result; -} - -impl 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 { - Ok((A::read(source)?, B::read(source)?)) - } -} -impl 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 { - Ok((A::read(source)?, B::read(source)?, C::read(source)?)) - } -} - -impl 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 { - let mut k: [A; N] = unsafe { std::mem::zeroed() }; - for i in 0..N { - k[i] = A::read(source)?; - } - Ok(k) - } -} - -impl Ser for Vec { - 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 { - 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) -> anyhow::Result<()> { - Ok(sink.write_all(&[*self]).context("write u8")?) - } - fn read(source: &mut impl Read) -> anyhow::Result { - 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 { - 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 16")?) - } - fn read(source: &mut impl Read) -> anyhow::Result { - 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 { - 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 { - 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 { - 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 { - 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 { - 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 { - let mut buf = [0u8; 8]; - source.read_exact(&mut buf)?; - Ok(unsafe { std::mem::transmute_copy(&buf) }) - } -} - -#[cfg(test)] -mod test { - use super::{Ser, Sink}; - use crate::header::Header; - use crate::helpers::vector::Vec2; - use crate::ser::Source; - use std::fmt::Debug; - use std::io::Cursor; - - fn test_ser(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]); - } -} diff --git a/evc/src/view.rs b/evc/src/view.rs index 5596637..3843128 100644 --- a/evc/src/view.rs +++ b/evc/src/view.rs @@ -1,4 +1,7 @@ -use crate::{frame::Frame, helpers::vector::Vec2, pixel::Pixel}; +use crate::{ + frame::Frame, + helpers::{pixel::Pixel, vector::Vec2}, +}; use std::ops::{Index, IndexMut}; pub struct View { -- cgit v1.2.3-70-g09d2