1use pixman_sys as ffi;
2#[cfg(feature = "drm-fourcc")]
3use thiserror::Error;
4
5#[derive(Debug, Clone, Copy)]
7pub enum FormatCode {
8 RgbaFloat,
10 RgbFloat,
12 A8R8G8B8,
14 X8R8G8B8,
16 A8B8G8R8,
18 X8B8G8R8,
20 B8G8R8A8,
22 B8G8R8X8,
24 R8G8B8A8,
26 R8G8B8X8,
28 X14R6G6B6,
30 X2R10G10B10,
32 A2R10G10B10,
34 X2B10G10R10,
36 A2B10G10R10,
38 A8R8G8B8sRGB,
40 R8G8B8,
42 B8G8R8,
44 R5G6B5,
46 B5G6R5,
48 A1R5G5B5,
50 X1R5G5B5,
52 A1B5G5R5,
54 X1B5G5R5,
56 A4R4G4B4,
58 X4R4G4B4,
60 A4B4G4R4,
62 X4B4G4R4,
64 A8,
66 R3G3B2,
68 B2G3R3,
70 A2R2G2B2,
72 A2B2G2R2,
74 C8,
76 G8,
78 X4A4,
80 X4C4,
82 X4G4,
84 A4,
86 R1G2B1,
88 B1G2R1,
90 A1R1G1B1,
92 A1B1G1R1,
94 C4,
96 G4,
98 A1,
100 G1,
102 YUY2,
104 YV12,
106}
107
108impl FormatCode {
109 pub fn bpp(code: Self) -> u32 {
111 let val = Into::<ffi::pixman_format_code_t>::into(code);
112 let ofs = 24;
113 let num = 8;
114 ((val >> (ofs)) & ((1 << (num)) - 1)) << ((val >> 22) & 3)
115 }
116}
117
118impl From<ffi::pixman_format_code_t> for FormatCode {
119 fn from(value: ffi::pixman_format_code_t) -> Self {
120 match value {
121 ffi::pixman_format_code_t_PIXMAN_rgba_float => FormatCode::RgbaFloat,
122 ffi::pixman_format_code_t_PIXMAN_rgb_float => FormatCode::RgbFloat,
123 ffi::pixman_format_code_t_PIXMAN_a8r8g8b8 => FormatCode::A8R8G8B8,
124 ffi::pixman_format_code_t_PIXMAN_x8r8g8b8 => FormatCode::X8R8G8B8,
125 ffi::pixman_format_code_t_PIXMAN_a8b8g8r8 => FormatCode::A8B8G8R8,
126 ffi::pixman_format_code_t_PIXMAN_x8b8g8r8 => FormatCode::X8B8G8R8,
127 ffi::pixman_format_code_t_PIXMAN_b8g8r8a8 => FormatCode::B8G8R8A8,
128 ffi::pixman_format_code_t_PIXMAN_b8g8r8x8 => FormatCode::B8G8R8X8,
129 ffi::pixman_format_code_t_PIXMAN_r8g8b8a8 => FormatCode::R8G8B8A8,
130 ffi::pixman_format_code_t_PIXMAN_r8g8b8x8 => FormatCode::R8G8B8X8,
131 ffi::pixman_format_code_t_PIXMAN_x14r6g6b6 => FormatCode::X14R6G6B6,
132 ffi::pixman_format_code_t_PIXMAN_x2r10g10b10 => FormatCode::X2R10G10B10,
133 ffi::pixman_format_code_t_PIXMAN_a2r10g10b10 => FormatCode::A2R10G10B10,
134 ffi::pixman_format_code_t_PIXMAN_x2b10g10r10 => FormatCode::X2B10G10R10,
135 ffi::pixman_format_code_t_PIXMAN_a2b10g10r10 => FormatCode::A2B10G10R10,
136 ffi::pixman_format_code_t_PIXMAN_a8r8g8b8_sRGB => FormatCode::A8R8G8B8sRGB,
137 ffi::pixman_format_code_t_PIXMAN_r8g8b8 => FormatCode::R8G8B8,
138 ffi::pixman_format_code_t_PIXMAN_b8g8r8 => FormatCode::B8G8R8,
139 ffi::pixman_format_code_t_PIXMAN_r5g6b5 => FormatCode::R5G6B5,
140 ffi::pixman_format_code_t_PIXMAN_b5g6r5 => FormatCode::B5G6R5,
141 ffi::pixman_format_code_t_PIXMAN_a1r5g5b5 => FormatCode::A1R5G5B5,
142 ffi::pixman_format_code_t_PIXMAN_x1r5g5b5 => FormatCode::X1R5G5B5,
143 ffi::pixman_format_code_t_PIXMAN_a1b5g5r5 => FormatCode::A1B5G5R5,
144 ffi::pixman_format_code_t_PIXMAN_x1b5g5r5 => FormatCode::X1B5G5R5,
145 ffi::pixman_format_code_t_PIXMAN_a4r4g4b4 => FormatCode::A4R4G4B4,
146 ffi::pixman_format_code_t_PIXMAN_x4r4g4b4 => FormatCode::X4R4G4B4,
147 ffi::pixman_format_code_t_PIXMAN_a4b4g4r4 => FormatCode::A4B4G4R4,
148 ffi::pixman_format_code_t_PIXMAN_x4b4g4r4 => FormatCode::X4B4G4R4,
149 ffi::pixman_format_code_t_PIXMAN_a8 => FormatCode::A8,
150 ffi::pixman_format_code_t_PIXMAN_r3g3b2 => FormatCode::R3G3B2,
151 ffi::pixman_format_code_t_PIXMAN_b2g3r3 => FormatCode::B2G3R3,
152 ffi::pixman_format_code_t_PIXMAN_a2r2g2b2 => FormatCode::A2R2G2B2,
153 ffi::pixman_format_code_t_PIXMAN_a2b2g2r2 => FormatCode::A2B2G2R2,
154 ffi::pixman_format_code_t_PIXMAN_c8 => FormatCode::C8,
155 ffi::pixman_format_code_t_PIXMAN_g8 => FormatCode::G8,
156 ffi::pixman_format_code_t_PIXMAN_x4a4 => FormatCode::X4A4,
157 ffi::pixman_format_code_t_PIXMAN_a4 => FormatCode::A4,
161 ffi::pixman_format_code_t_PIXMAN_r1g2b1 => FormatCode::R1G2B1,
162 ffi::pixman_format_code_t_PIXMAN_b1g2r1 => FormatCode::B1G2R1,
163 ffi::pixman_format_code_t_PIXMAN_a1r1g1b1 => FormatCode::A1R1G1B1,
164 ffi::pixman_format_code_t_PIXMAN_a1b1g1r1 => FormatCode::A1B1G1R1,
165 ffi::pixman_format_code_t_PIXMAN_c4 => FormatCode::C4,
166 ffi::pixman_format_code_t_PIXMAN_g4 => FormatCode::G4,
167 ffi::pixman_format_code_t_PIXMAN_a1 => FormatCode::A1,
168 ffi::pixman_format_code_t_PIXMAN_g1 => FormatCode::G1,
169 ffi::pixman_format_code_t_PIXMAN_yuy2 => FormatCode::YUY2,
170 ffi::pixman_format_code_t_PIXMAN_yv12 => FormatCode::YV12,
171 _ => unreachable!(),
172 }
173 }
174}
175
176impl From<FormatCode> for ffi::pixman_format_code_t {
177 fn from(value: FormatCode) -> Self {
178 match value {
179 FormatCode::RgbaFloat => ffi::pixman_format_code_t_PIXMAN_rgba_float,
180 FormatCode::RgbFloat => ffi::pixman_format_code_t_PIXMAN_rgb_float,
181 FormatCode::A8R8G8B8 => ffi::pixman_format_code_t_PIXMAN_a8r8g8b8,
182 FormatCode::X8R8G8B8 => ffi::pixman_format_code_t_PIXMAN_x8r8g8b8,
183 FormatCode::A8B8G8R8 => ffi::pixman_format_code_t_PIXMAN_a8b8g8r8,
184 FormatCode::X8B8G8R8 => ffi::pixman_format_code_t_PIXMAN_x8b8g8r8,
185 FormatCode::B8G8R8A8 => ffi::pixman_format_code_t_PIXMAN_b8g8r8a8,
186 FormatCode::B8G8R8X8 => ffi::pixman_format_code_t_PIXMAN_b8g8r8x8,
187 FormatCode::R8G8B8A8 => ffi::pixman_format_code_t_PIXMAN_r8g8b8a8,
188 FormatCode::R8G8B8X8 => ffi::pixman_format_code_t_PIXMAN_r8g8b8x8,
189 FormatCode::X14R6G6B6 => ffi::pixman_format_code_t_PIXMAN_x14r6g6b6,
190 FormatCode::X2R10G10B10 => ffi::pixman_format_code_t_PIXMAN_x2r10g10b10,
191 FormatCode::A2R10G10B10 => ffi::pixman_format_code_t_PIXMAN_a2r10g10b10,
192 FormatCode::X2B10G10R10 => ffi::pixman_format_code_t_PIXMAN_x2b10g10r10,
193 FormatCode::A2B10G10R10 => ffi::pixman_format_code_t_PIXMAN_a2b10g10r10,
194 FormatCode::A8R8G8B8sRGB => ffi::pixman_format_code_t_PIXMAN_a8r8g8b8_sRGB,
195 FormatCode::R8G8B8 => ffi::pixman_format_code_t_PIXMAN_r8g8b8,
196 FormatCode::B8G8R8 => ffi::pixman_format_code_t_PIXMAN_b8g8r8,
197 FormatCode::R5G6B5 => ffi::pixman_format_code_t_PIXMAN_r5g6b5,
198 FormatCode::B5G6R5 => ffi::pixman_format_code_t_PIXMAN_b5g6r5,
199 FormatCode::A1R5G5B5 => ffi::pixman_format_code_t_PIXMAN_a1r5g5b5,
200 FormatCode::X1R5G5B5 => ffi::pixman_format_code_t_PIXMAN_x1r5g5b5,
201 FormatCode::A1B5G5R5 => ffi::pixman_format_code_t_PIXMAN_a1b5g5r5,
202 FormatCode::X1B5G5R5 => ffi::pixman_format_code_t_PIXMAN_x1b5g5r5,
203 FormatCode::A4R4G4B4 => ffi::pixman_format_code_t_PIXMAN_a4r4g4b4,
204 FormatCode::X4R4G4B4 => ffi::pixman_format_code_t_PIXMAN_x4r4g4b4,
205 FormatCode::A4B4G4R4 => ffi::pixman_format_code_t_PIXMAN_a4b4g4r4,
206 FormatCode::X4B4G4R4 => ffi::pixman_format_code_t_PIXMAN_x4b4g4r4,
207 FormatCode::A8 => ffi::pixman_format_code_t_PIXMAN_a8,
208 FormatCode::R3G3B2 => ffi::pixman_format_code_t_PIXMAN_r3g3b2,
209 FormatCode::B2G3R3 => ffi::pixman_format_code_t_PIXMAN_b2g3r3,
210 FormatCode::A2R2G2B2 => ffi::pixman_format_code_t_PIXMAN_a2r2g2b2,
211 FormatCode::A2B2G2R2 => ffi::pixman_format_code_t_PIXMAN_a2b2g2r2,
212 FormatCode::C8 => ffi::pixman_format_code_t_PIXMAN_c8,
213 FormatCode::G8 => ffi::pixman_format_code_t_PIXMAN_g8,
214 FormatCode::X4A4 => ffi::pixman_format_code_t_PIXMAN_x4a4,
215 FormatCode::X4C4 => ffi::pixman_format_code_t_PIXMAN_x4c4,
216 FormatCode::X4G4 => ffi::pixman_format_code_t_PIXMAN_x4g4,
217 FormatCode::A4 => ffi::pixman_format_code_t_PIXMAN_a4,
218 FormatCode::R1G2B1 => ffi::pixman_format_code_t_PIXMAN_r1g2b1,
219 FormatCode::B1G2R1 => ffi::pixman_format_code_t_PIXMAN_b1g2r1,
220 FormatCode::A1R1G1B1 => ffi::pixman_format_code_t_PIXMAN_a1r1g1b1,
221 FormatCode::A1B1G1R1 => ffi::pixman_format_code_t_PIXMAN_a1b1g1r1,
222 FormatCode::C4 => ffi::pixman_format_code_t_PIXMAN_c4,
223 FormatCode::G4 => ffi::pixman_format_code_t_PIXMAN_g4,
224 FormatCode::A1 => ffi::pixman_format_code_t_PIXMAN_a1,
225 FormatCode::G1 => ffi::pixman_format_code_t_PIXMAN_g1,
226 FormatCode::YUY2 => ffi::pixman_format_code_t_PIXMAN_yuy2,
227 FormatCode::YV12 => ffi::pixman_format_code_t_PIXMAN_yv12,
228 }
229 }
230}
231
232#[cfg(feature = "drm-fourcc")]
234#[derive(Debug, Error)]
235#[error("Unsupported drm fourcc {0}")]
236pub struct UnsupportedDrmFourcc(drm_fourcc::DrmFourcc);
237
238#[cfg(feature = "drm-fourcc")]
239impl TryFrom<drm_fourcc::DrmFourcc> for FormatCode {
240 type Error = UnsupportedDrmFourcc;
241
242 fn try_from(value: drm_fourcc::DrmFourcc) -> Result<Self, Self::Error> {
243 use drm_fourcc::DrmFourcc;
244
245 let format = match value {
246 #[cfg(target_endian = "little")]
247 DrmFourcc::Rgb565 => FormatCode::R5G6B5,
248
249 #[cfg(target_endian = "little")]
250 DrmFourcc::Xrgb8888 => FormatCode::X8R8G8B8,
251 #[cfg(target_endian = "big")]
252 DrmFourcc::Xrgb8888 => FormatCode::B8G8R8X8,
253
254 #[cfg(target_endian = "little")]
255 DrmFourcc::Argb8888 => FormatCode::A8R8G8B8,
256 #[cfg(target_endian = "big")]
257 DrmFourcc::Argb8888 => FormatCode::B8G8R8A8,
258
259 #[cfg(target_endian = "little")]
260 DrmFourcc::Xbgr8888 => FormatCode::X8B8G8R8,
261 #[cfg(target_endian = "big")]
262 DrmFourcc::Xbgr8888 => FormatCode::R8G8B8X8,
263
264 #[cfg(target_endian = "little")]
265 DrmFourcc::Abgr8888 => FormatCode::A8B8G8R8,
266 #[cfg(target_endian = "big")]
267 DrmFourcc::Abgr8888 => FormatCode::R8G8B8A8,
268
269 #[cfg(target_endian = "little")]
270 DrmFourcc::Rgbx8888 => FormatCode::R8G8B8X8,
271 #[cfg(target_endian = "big")]
272 DrmFourcc::Rgbx8888 => FormatCode::X8B8G8R8,
273
274 #[cfg(target_endian = "little")]
275 DrmFourcc::Rgba8888 => FormatCode::R8G8B8A8,
276 #[cfg(target_endian = "big")]
277 DrmFourcc::Rgba8888 => FormatCode::A8B8G8R8,
278
279 #[cfg(target_endian = "little")]
280 DrmFourcc::Bgrx8888 => FormatCode::B8G8R8X8,
281 #[cfg(target_endian = "big")]
282 DrmFourcc::Bgrx8888 => FormatCode::X8R8G8B8,
283
284 #[cfg(target_endian = "little")]
285 DrmFourcc::Bgra8888 => FormatCode::B8G8R8A8,
286 #[cfg(target_endian = "big")]
287 DrmFourcc::Bgra8888 => FormatCode::A8R8G8B8,
288
289 #[cfg(target_endian = "little")]
290 DrmFourcc::Xrgb2101010 => FormatCode::X2R10G10B10,
291
292 #[cfg(target_endian = "little")]
293 DrmFourcc::Argb2101010 => FormatCode::A2R10G10B10,
294
295 #[cfg(target_endian = "little")]
296 DrmFourcc::Xbgr2101010 => FormatCode::X2B10G10R10,
297
298 #[cfg(target_endian = "little")]
299 DrmFourcc::Abgr2101010 => FormatCode::A2B10G10R10,
300 other => return Err(UnsupportedDrmFourcc(other)),
301 };
302 Ok(format)
303 }
304}
305
306#[cfg(feature = "drm-fourcc")]
308#[derive(Debug, Error)]
309#[error("Unsupported format code {0:?}")]
310pub struct UnsupportedFormatCode(FormatCode);
311
312#[cfg(feature = "drm-fourcc")]
313impl TryFrom<FormatCode> for drm_fourcc::DrmFourcc {
314 type Error = UnsupportedFormatCode;
315
316 fn try_from(value: FormatCode) -> Result<Self, Self::Error> {
317 use drm_fourcc::DrmFourcc;
318
319 let format = match value {
320 #[cfg(target_endian = "little")]
321 FormatCode::R5G6B5 => DrmFourcc::Rgb565,
322
323 #[cfg(target_endian = "little")]
324 FormatCode::X8R8G8B8 => DrmFourcc::Xrgb8888,
325 #[cfg(target_endian = "big")]
326 FormatCode::B8G8R8X8 => DrmFourcc::Xrgb8888,
327
328 #[cfg(target_endian = "little")]
329 FormatCode::A8R8G8B8 => DrmFourcc::Argb8888,
330 #[cfg(target_endian = "big")]
331 FormatCode::B8G8R8A8 => DrmFourcc::Argb8888,
332
333 #[cfg(target_endian = "little")]
334 FormatCode::X8B8G8R8 => DrmFourcc::Xbgr8888,
335 #[cfg(target_endian = "big")]
336 FormatCode::R8G8B8X8 => DrmFourcc::Xbgr8888,
337
338 #[cfg(target_endian = "little")]
339 FormatCode::A8B8G8R8 => DrmFourcc::Abgr8888,
340 #[cfg(target_endian = "big")]
341 FormatCode::R8G8B8A8 => DrmFourcc::Abgr8888,
342
343 #[cfg(target_endian = "little")]
344 FormatCode::R8G8B8X8 => DrmFourcc::Rgbx8888,
345 #[cfg(target_endian = "big")]
346 FormatCode::X8B8G8R8 => DrmFourcc::Rgbx8888,
347
348 #[cfg(target_endian = "little")]
349 FormatCode::R8G8B8A8 => DrmFourcc::Rgba8888,
350 #[cfg(target_endian = "big")]
351 FormatCode::A8B8G8R8 => DrmFourcc::Rgba8888,
352
353 #[cfg(target_endian = "little")]
354 FormatCode::B8G8R8X8 => DrmFourcc::Bgrx8888,
355 #[cfg(target_endian = "big")]
356 FormatCode::X8R8G8B8 => DrmFourcc::Bgrx8888,
357
358 #[cfg(target_endian = "little")]
359 FormatCode::B8G8R8A8 => DrmFourcc::Bgra8888,
360 #[cfg(target_endian = "big")]
361 FormatCode::A8R8G8B8 => DrmFourcc::Bgra8888,
362
363 #[cfg(target_endian = "little")]
364 FormatCode::X2R10G10B10 => DrmFourcc::Xrgb2101010,
365
366 #[cfg(target_endian = "little")]
367 FormatCode::A2R10G10B10 => DrmFourcc::Argb2101010,
368
369 #[cfg(target_endian = "little")]
370 FormatCode::X2B10G10R10 => DrmFourcc::Xbgr2101010,
371
372 #[cfg(target_endian = "little")]
373 FormatCode::A2B10G10R10 => DrmFourcc::Abgr2101010,
374 other => return Err(UnsupportedFormatCode(other)),
375 };
376 Ok(format)
377 }
378}