diff options
Diffstat (limited to 'evc/src/helpers')
-rw-r--r-- | evc/src/helpers/mod.rs | 3 | ||||
-rw-r--r-- | evc/src/helpers/pixel.rs | 67 | ||||
-rw-r--r-- | evc/src/helpers/vector.rs | 29 |
3 files changed, 69 insertions, 30 deletions
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<Self> { + 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<const N: usize>() -> [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<T> { pub x: T, @@ -26,32 +24,6 @@ impl<T: std::ops::Div<Output = T> + Copy> Vec2<T> { } } -impl Ser for Vec2<isize> { - 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 }) - } -} - -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, - })) - } -} - impl<T: std::ops::Add> std::ops::Add for Vec2<T> { type Output = Vec2<T::Output>; #[inline] @@ -89,4 +61,3 @@ impl<T> From<(T, T)> for Vec2<T> { Vec2 { x, y } } } - |