Files
ccvl/src/image.rs
T

152 lines
2.9 KiB
Rust

pub mod farbfeld;
pub use farbfeld::*;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SRGBA {
pub r: f32,
pub g: f32,
pub b: f32,
pub a: f32,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Extent {
pub x: usize,
pub y: usize,
}
#[derive(Debug)]
pub struct Image<P> {
pub extent: Extent,
pub pixels: Vec<P>,
}
#[derive(Debug)]
pub enum Error {
Invalid,
Io(std::io::Error),
}
pub trait Format<P> {
fn read<I>(input: &mut I) -> Result<Image<P>, Error>
where
I: std::io::Read;
fn write<O>(output: &mut O, img: &Image<P>) -> std::io::Result<()>
where
O: std::io::Write;
}
impl Extent {
pub fn size(&self) -> usize {
self.x * self.y
}
}
impl SRGBA {
pub fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
Self { r, g, b, a }
}
}
pub trait Pixel:
std::ops::AddAssign
+ std::ops::MulAssign<f32>
+ std::ops::DivAssign<f32>
+ std::ops::Mul<f32, Output = Self>
+ std::ops::Div<f32, Output = Self>
+ Clone
+ Copy
+ Default
+ Sized
{
}
impl<P> Pixel for P where
P: std::ops::AddAssign
+ std::ops::MulAssign<f32>
+ std::ops::DivAssign<f32>
+ std::ops::Mul<f32, Output = Self>
+ std::ops::Div<f32, Output = Self>
+ Clone
+ Copy
+ Default
+ Sized
{
}
impl std::ops::AddAssign for SRGBA {
fn add_assign(&mut self, other: SRGBA) {
self.r += other.r;
self.g += other.g;
self.b += other.b;
self.a += other.a;
}
}
impl std::ops::MulAssign<f32> for SRGBA {
fn mul_assign(&mut self, scalar: f32) {
self.r *= scalar;
self.g *= scalar;
self.b *= scalar;
self.a *= scalar;
}
}
impl std::ops::DivAssign<f32> for SRGBA {
fn div_assign(&mut self, scalar: f32) {
self.r /= scalar;
self.g /= scalar;
self.b /= scalar;
self.a /= scalar;
}
}
impl std::ops::Mul<f32> for SRGBA {
type Output = Self;
fn mul(mut self, scalar: f32) -> Self {
self *= scalar;
self
}
}
impl std::ops::Div<f32> for SRGBA {
type Output = Self;
fn div(mut self, scalar: f32) -> Self {
self /= scalar;
self
}
}
impl std::default::Default for SRGBA {
fn default() -> Self {
Self {
r: 0.0,
g: 0.0,
b: 0.0,
a: 0.0,
}
}
}
impl From<std::io::Error> for Error {
fn from(error: std::io::Error) -> Self {
Error::Io(error)
}
}
impl<P> Image<P> {
pub fn load<F: Format<P>>(path: &str) -> Result<Image<P>, Error> {
let file = std::fs::File::open(path)?;
F::read(&mut std::io::BufReader::new(file))
}
pub fn save<F: Format<P>>(&self, path: &str) -> std::io::Result<()> {
let file = std::fs::File::create(path)?;
F::write(&mut std::io::BufWriter::new(file), self)
}
}