1use core::convert::TryFrom;
2
3use crate::error::{Error, Result};
4use crate::utils::unlikely;
5
6#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
11#[repr(u8)]
12pub enum ColorSpace {
13 Srgb = 0,
15 Linear = 1,
17}
18
19impl ColorSpace {
20 pub const fn is_srgb(self) -> bool {
22 matches!(self, Self::Srgb)
23 }
24
25 pub const fn is_linear(self) -> bool {
27 matches!(self, Self::Linear)
28 }
29
30 pub const fn as_u8(self) -> u8 {
32 self as u8
33 }
34}
35
36impl Default for ColorSpace {
37 fn default() -> Self {
38 Self::Srgb
39 }
40}
41
42impl From<ColorSpace> for u8 {
43 #[inline]
44 fn from(colorspace: ColorSpace) -> Self {
45 colorspace as Self
46 }
47}
48
49impl TryFrom<u8> for ColorSpace {
50 type Error = Error;
51
52 #[inline]
53 fn try_from(colorspace: u8) -> Result<Self> {
54 if unlikely(colorspace | 1 != 1) {
55 Err(Error::InvalidColorSpace { colorspace })
56 } else {
57 Ok(if colorspace == 0 { Self::Srgb } else { Self::Linear })
58 }
59 }
60}
61
62#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
64#[repr(u8)]
65pub enum Channels {
66 Rgb = 3,
68 Rgba = 4,
70}
71
72impl Channels {
73 pub const fn is_rgb(self) -> bool {
75 matches!(self, Self::Rgb)
76 }
77
78 pub const fn is_rgba(self) -> bool {
80 matches!(self, Self::Rgba)
81 }
82
83 pub const fn as_u8(self) -> u8 {
85 self as u8
86 }
87}
88
89impl Default for Channels {
90 fn default() -> Self {
91 Self::Rgb
92 }
93}
94
95impl From<Channels> for u8 {
96 #[inline]
97 fn from(channels: Channels) -> Self {
98 channels as Self
99 }
100}
101
102impl TryFrom<u8> for Channels {
103 type Error = Error;
104
105 #[inline]
106 fn try_from(channels: u8) -> Result<Self> {
107 if unlikely(channels != 3 && channels != 4) {
108 Err(Error::InvalidChannels { channels })
109 } else {
110 Ok(if channels == 3 { Self::Rgb } else { Self::Rgba })
111 }
112 }
113}
114
115#[derive(Copy, Clone, PartialEq, Eq, Debug)]
116pub enum RawChannels {
117 Rgb,
118 Bgr,
119 Rgba,
120 Argb,
121 Rgbx,
122 Xrgb,
123 Bgra,
124 Abgr,
125 Bgrx,
126 Xbgr,
127}
128
129impl From<Channels> for RawChannels {
130 fn from(value: Channels) -> Self {
131 match value {
132 Channels::Rgb => Self::Rgb,
133 Channels::Rgba => Self::Rgba,
134 }
135 }
136}
137
138impl From<RawChannels> for Channels {
139 fn from(value: RawChannels) -> Self {
140 match value {
141 RawChannels::Rgb
142 | RawChannels::Bgr
143 | RawChannels::Rgbx
144 | RawChannels::Xrgb
145 | RawChannels::Bgrx
146 | RawChannels::Xbgr => Self::Rgb,
147 RawChannels::Rgba | RawChannels::Argb | RawChannels::Bgra | RawChannels::Abgr => {
148 Self::Rgba
149 }
150 }
151 }
152}
153
154impl RawChannels {
155 pub(crate) const fn bytes_per_pixel(self) -> usize {
156 match self {
157 Self::Rgb | Self::Bgr => 3,
158 Self::Rgba
159 | Self::Argb
160 | Self::Rgbx
161 | Self::Xrgb
162 | Self::Bgra
163 | Self::Abgr
164 | Self::Bgrx
165 | Self::Xbgr => 4,
166 }
167 }
168}