pixman/
format.rs

1use pixman_sys as ffi;
2#[cfg(feature = "drm-fourcc")]
3use thiserror::Error;
4
5/// Possible format codes
6#[derive(Debug, Clone, Copy)]
7pub enum FormatCode {
8    /// 128bpp RgbaFloat
9    RgbaFloat,
10    /// 96bpp RgbFloat
11    RgbFloat,
12    /// 32bpp A8R8G8B8
13    A8R8G8B8,
14    /// 32bpp X8R8G8B8
15    X8R8G8B8,
16    /// 32bpp A8B8G8R8
17    A8B8G8R8,
18    /// 32bpp X8B8G8R8
19    X8B8G8R8,
20    /// 32bpp B8G8R8A8
21    B8G8R8A8,
22    /// 32bpp B8G8R8X8
23    B8G8R8X8,
24    /// 32bpp R8G8B8A8
25    R8G8B8A8,
26    /// 32bpp R8G8B8X8
27    R8G8B8X8,
28    /// 32bpp X14R6G6B6
29    X14R6G6B6,
30    /// 32bpp X2R10G10B10
31    X2R10G10B10,
32    /// 32bpp A2R10G10B10
33    A2R10G10B10,
34    /// 32bpp X2B10G10R10
35    X2B10G10R10,
36    /// 32bpp A2B10G10R10
37    A2B10G10R10,
38    /// sRGB A8R8G8B8sRGB
39    A8R8G8B8sRGB,
40    /// 24bpp R8G8B8
41    R8G8B8,
42    /// 24bpp B8G8R8
43    B8G8R8,
44    /// 16bpp R5G6B5
45    R5G6B5,
46    /// 16bpp B5G6R5
47    B5G6R5,
48    /// 16bpp A1R5G5B5
49    A1R5G5B5,
50    /// 16bpp X1R5G5B5
51    X1R5G5B5,
52    /// 16bpp A1B5G5R5
53    A1B5G5R5,
54    /// 16bpp X1B5G5R5
55    X1B5G5R5,
56    /// 16bpp A4R4G4B4
57    A4R4G4B4,
58    /// 16bpp X4R4G4B4
59    X4R4G4B4,
60    /// 16bpp A4B4G4R4
61    A4B4G4R4,
62    /// 16bpp X4B4G4R4
63    X4B4G4R4,
64    /// 8bpp A8
65    A8,
66    /// 8bpp R3G3B2
67    R3G3B2,
68    /// 8bpp B2G3R3
69    B2G3R3,
70    /// 8bpp A2R2G2B2
71    A2R2G2B2,
72    /// 8bpp A2B2G2R2
73    A2B2G2R2,
74    /// 8bpp C8
75    C8,
76    /// 8bpp G8
77    G8,
78    /// 8bpp X4A4
79    X4A4,
80    /// 8bpp X4C4
81    X4C4,
82    /// 8bpp X4G4
83    X4G4,
84    /// 4bpp A4
85    A4,
86    /// 4bpp R1G2B1
87    R1G2B1,
88    /// 4bpp B1G2R1
89    B1G2R1,
90    /// 4bpp A1R1G1B1
91    A1R1G1B1,
92    /// 4bpp A1B1G1R1
93    A1B1G1R1,
94    /// 4bpp C4
95    C4,
96    /// 4bpp G4
97    G4,
98    /// 1bpp A1
99    A1,
100    /// 1bpp G1
101    G1,
102    /// YUV YUY2
103    YUY2,
104    /// YUV YV12
105    YV12,
106}
107
108impl FormatCode {
109    /// Get the bpp for the specified format
110    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            // NOTE: These format codes are identical to c8 and g8, respectively
158            // ffi::pixman_format_code_t_PIXMAN_x4c4 => FormatCode::X4C4,
159            // ffi::pixman_format_code_t_PIXMAN_x4g4 => FormatCode::X4G4,
160            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/// The provided drm-fourcc has no matching format code
233#[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/// The provided format code has no matching drm-fourcc
307#[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}