use core::convert::TryFrom;
use crate::error::{Error, Result};
use crate::utils::unlikely;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
#[repr(u8)]
pub enum ColorSpace {
Srgb = 0,
Linear = 1,
}
impl ColorSpace {
pub const fn is_srgb(self) -> bool {
matches!(self, Self::Srgb)
}
pub const fn is_linear(self) -> bool {
matches!(self, Self::Linear)
}
pub const fn as_u8(self) -> u8 {
self as u8
}
}
impl Default for ColorSpace {
fn default() -> Self {
Self::Srgb
}
}
impl From<ColorSpace> for u8 {
#[inline]
fn from(colorspace: ColorSpace) -> Self {
colorspace as Self
}
}
impl TryFrom<u8> for ColorSpace {
type Error = Error;
#[inline]
fn try_from(colorspace: u8) -> Result<Self> {
if unlikely(colorspace | 1 != 1) {
Err(Error::InvalidColorSpace { colorspace })
} else {
Ok(if colorspace == 0 { Self::Srgb } else { Self::Linear })
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
#[repr(u8)]
pub enum Channels {
Rgb = 3,
Rgba = 4,
}
impl Channels {
pub const fn is_rgb(self) -> bool {
matches!(self, Self::Rgb)
}
pub const fn is_rgba(self) -> bool {
matches!(self, Self::Rgba)
}
pub const fn as_u8(self) -> u8 {
self as u8
}
}
impl Default for Channels {
fn default() -> Self {
Self::Rgb
}
}
impl From<Channels> for u8 {
#[inline]
fn from(channels: Channels) -> Self {
channels as Self
}
}
impl TryFrom<u8> for Channels {
type Error = Error;
#[inline]
fn try_from(channels: u8) -> Result<Self> {
if unlikely(channels != 3 && channels != 4) {
Err(Error::InvalidChannels { channels })
} else {
Ok(if channels == 3 { Self::Rgb } else { Self::Rgba })
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum RawChannels {
Rgb,
Bgr,
Rgba,
Argb,
Rgbx,
Xrgb,
Bgra,
Abgr,
Bgrx,
Xbgr,
}
impl From<Channels> for RawChannels {
fn from(value: Channels) -> Self {
match value {
Channels::Rgb => Self::Rgb,
Channels::Rgba => Self::Rgba,
}
}
}
impl From<RawChannels> for Channels {
fn from(value: RawChannels) -> Self {
match value {
RawChannels::Rgb
| RawChannels::Bgr
| RawChannels::Rgbx
| RawChannels::Xrgb
| RawChannels::Bgrx
| RawChannels::Xbgr => Self::Rgb,
RawChannels::Rgba | RawChannels::Argb | RawChannels::Bgra | RawChannels::Abgr => {
Self::Rgba
}
}
}
}
impl RawChannels {
pub(crate) const fn bytes_per_pixel(self) -> usize {
match self {
Self::Rgb | Self::Bgr => 3,
Self::Rgba
| Self::Argb
| Self::Rgbx
| Self::Xrgb
| Self::Bgra
| Self::Abgr
| Self::Bgrx
| Self::Xbgr => 4,
}
}
}