use std::fmt;
mod private {
pub trait Sealed {}
impl Sealed for u8 {}
impl Sealed for u16 {}
impl Sealed for f32 {}
impl Sealed for f64 {}
}
pub trait Gray: Copy + Send + Sync + private::Sealed {
fn to_gray(self) -> f64;
fn as_f64_slice(image: &[Self]) -> Option<&[f64]> {
let _ = image;
None
}
}
impl Gray for u8 {
fn to_gray(self) -> f64 {
self as f64
}
}
impl Gray for u16 {
fn to_gray(self) -> f64 {
self as f64 / 257.0
}
}
impl Gray for f32 {
fn to_gray(self) -> f64 {
self as f64
}
}
impl Gray for f64 {
fn to_gray(self) -> f64 {
self
}
fn as_f64_slice(image: &[Self]) -> Option<&[f64]> {
Some(image)
}
}
pub trait Sample: Copy + Send + Sync + private::Sealed {
fn to_f64(self) -> f64;
fn from_f64(value: f64) -> Self;
}
impl Sample for u8 {
fn to_f64(self) -> f64 {
self as f64
}
fn from_f64(value: f64) -> Self {
(value + 0.5) as u8
}
}
impl Sample for u16 {
fn to_f64(self) -> f64 {
self as f64
}
fn from_f64(value: f64) -> Self {
(value + 0.5) as u16
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SizeMismatch {
pub expected: usize,
pub got: usize,
}
impl fmt::Display for SizeMismatch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"buffer holds {} samples, the dimensions demand {}",
self.got, self.expected
)
}
}
impl std::error::Error for SizeMismatch {}