use crate::image::{BitDepth, Channels, ColorSpace};
mod private {
pub trait Sealed {}
}
pub trait Sample: Copy + Into<f64> + private::Sealed + 'static {
const MAX: f64;
const BIT_DEPTH: BitDepth;
}
impl private::Sealed for u8 {}
impl Sample for u8 {
const MAX: f64 = 255.0;
const BIT_DEPTH: BitDepth = BitDepth::Eight;
}
impl private::Sealed for u16 {}
impl Sample for u16 {
const MAX: f64 = 65_535.0;
const BIT_DEPTH: BitDepth = BitDepth::Sixteen;
}
pub trait PixelFormat: private::Sealed + Copy + 'static {
type Sample: Sample;
const CHANNELS: Channels;
const COLOR_SPACE: ColorSpace;
const BIT_DEPTH: BitDepth;
}
macro_rules! pixel_format {
($(#[$doc:meta])* $name:ident, $sample:ty, $channels:expr, $color:expr) => {
$(#[$doc])*
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct $name;
impl private::Sealed for $name {}
impl PixelFormat for $name {
type Sample = $sample;
const CHANNELS: Channels = $channels;
const COLOR_SPACE: ColorSpace = $color;
const BIT_DEPTH: BitDepth = <$sample as Sample>::BIT_DEPTH;
}
};
}
pixel_format!(
Srgb8, u8, Channels::Rgb, ColorSpace::Srgb
);
pixel_format!(
Srgb16, u16, Channels::Rgb, ColorSpace::Srgb
);
pixel_format!(
Gray8, u8, Channels::Gray, ColorSpace::Grayscale
);
pixel_format!(
Gray16, u16, Channels::Gray, ColorSpace::Grayscale
);
pixel_format!(
Rgba8, u8, Channels::Rgba, ColorSpace::Srgb
);
pixel_format!(
Rgba16, u16, Channels::Rgba, ColorSpace::Srgb
);