use rgb::{Gray, GrayAlpha, Rgb, Rgba};
use rgb::bytemuck::Pod;
use rgb::bytemuck::Zeroable;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum PixelFormat {
RGB8,
RGBA8,
GRAY8,
GRAYA8,
RGB16,
RGBA16,
GRAY16,
GRAYA16,
#[cfg(any(feature = "jpeg", feature = "mozjpeg"))]
CMYK8,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum ColorSpace {
Rgb,
Gray,
Cmyk,
Other,
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(not(any(feature = "jpeg", feature = "mozjpeg")), allow(dead_code))]
pub struct CMYK {
pub c: u8,
pub m: u8,
pub y: u8,
pub k: u8,
}
unsafe impl Pod for CMYK {}
unsafe impl Zeroable for CMYK {}
pub(crate) trait HasPixelFormat where Self: Copy + Pod {
fn pixel_format() -> (PixelFormat, ColorSpace);
}
pub(crate) trait PixelConversion where Self: Copy {
type Converted: Copy + Pod;
type ConvertedOpaque: Copy + Pod;
}
macro_rules! pixel_conversion {
( $in_type:ty => $out_type:ty, $out_type_opaque:ty ) => {
impl PixelConversion for $in_type {
type Converted = $out_type;
type ConvertedOpaque = $out_type_opaque;
}
};
}
macro_rules! pixel_format {
( $in_type:ty, $format:expr, $colorspace:expr ) => {
impl HasPixelFormat for $in_type {
fn pixel_format() -> (PixelFormat, ColorSpace) {
($format, $colorspace)
}
}
};
}
#[cfg(any(feature = "jpeg", feature = "mozjpeg"))]
pixel_format! {CMYK, PixelFormat::CMYK8, ColorSpace::Cmyk }
#[cfg(any(feature = "jpeg", feature = "mozjpeg"))]
pixel_conversion! {CMYK => Rgb<u16>, Rgb<u16>}
pixel_format! {Rgb<u8>, PixelFormat::RGB8, ColorSpace::Rgb }
pixel_format! {Rgba<u8>, PixelFormat::RGBA8, ColorSpace::Rgb }
pixel_format! {Gray<u8>, PixelFormat::GRAY8, ColorSpace::Gray }
pixel_format! {GrayAlpha<u8>, PixelFormat::GRAYA8, ColorSpace::Gray }
pixel_format! {Rgb<u16>, PixelFormat::RGB16, ColorSpace::Rgb }
pixel_format! {Rgba<u16>, PixelFormat::RGBA16, ColorSpace::Rgb }
pixel_format! {Gray<u16>, PixelFormat::GRAY16, ColorSpace::Gray }
pixel_format! {GrayAlpha<u16>, PixelFormat::GRAYA16, ColorSpace::Gray }
pixel_conversion! {Rgb<u8> => Rgb<u16>, Rgb<u16>}
pixel_conversion! {Rgba<u8> => Rgba<u16>, Rgb<u16>}
pixel_conversion! {Gray<u8> => Gray<u16>, Gray<u16>}
pixel_conversion! {GrayAlpha<u8> => GrayAlpha<u16>, Gray<u16>}
pixel_conversion! {Rgb<u16> => Rgb<u16>, Rgb<u16>}
pixel_conversion! {Rgba<u16> => Rgba<u16>, Rgb<u16>}
pixel_conversion! {Gray<u16> => Gray<u16>, Gray<u16>}
pixel_conversion! {GrayAlpha<u16> => GrayAlpha<u16>, Gray<u16>}