libcamera/
pixel_format.rs1use std::{ffi::CStr, ptr::NonNull};
2
3use drm_fourcc::{DrmFormat, DrmFourcc, DrmModifier};
4use libcamera_sys::*;
5
6#[derive(Clone, Copy)]
8pub struct PixelFormat(pub(crate) libcamera_pixel_format_t);
9
10impl PixelFormat {
11 pub const fn new(fourcc: u32, modifier: u64) -> Self {
22 Self(libcamera_pixel_format_t { fourcc, modifier })
23 }
24
25 pub fn fourcc(&self) -> u32 {
26 self.0.fourcc
27 }
28
29 pub fn set_fourcc(&mut self, fourcc: u32) {
30 self.0.fourcc = fourcc;
31 }
32
33 pub fn modifier(&self) -> u64 {
34 self.0.modifier
35 }
36
37 pub fn set_modifier(&mut self, modifier: u64) {
38 self.0.modifier = modifier;
39 }
40}
41
42impl PartialEq for PixelFormat {
43 fn eq(&self, other: &Self) -> bool {
44 self.0.fourcc.eq(&other.0.fourcc) && self.0.modifier.eq(&other.0.modifier)
45 }
46}
47
48impl Eq for PixelFormat {}
49
50impl core::fmt::Debug for PixelFormat {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 let ptr = unsafe { libcamera_pixel_format_str(&self.0) };
53 let out = unsafe { CStr::from_ptr(ptr) }.to_str().unwrap();
54 f.write_str(out)?;
55 unsafe { libc::free(ptr.cast()) };
56 Ok(())
57 }
58}
59
60impl TryFrom<PixelFormat> for DrmFormat {
61 type Error = drm_fourcc::UnrecognizedFourcc;
62
63 fn try_from(value: PixelFormat) -> Result<Self, Self::Error> {
64 let code = DrmFourcc::try_from(value.0.fourcc)?;
65 let modifier = DrmModifier::from(value.0.modifier);
66 Ok(DrmFormat { code, modifier })
67 }
68}
69
70impl From<DrmFormat> for PixelFormat {
71 fn from(f: DrmFormat) -> Self {
72 PixelFormat::new(f.code as u32, f.modifier.into())
73 }
74}
75
76pub struct PixelFormats {
78 ptr: NonNull<libcamera_pixel_formats_t>,
79}
80
81impl PixelFormats {
82 pub(crate) unsafe fn from_ptr(ptr: NonNull<libcamera_pixel_formats_t>) -> Self {
83 Self { ptr }
84 }
85
86 pub fn len(&self) -> usize {
88 unsafe { libcamera_pixel_formats_size(self.ptr.as_ptr()) as _ }
89 }
90
91 pub fn is_empty(&self) -> bool {
93 self.len() == 0
94 }
95
96 pub fn get(&self, index: usize) -> Option<PixelFormat> {
100 if index >= self.len() {
101 None
102 } else {
103 Some(unsafe { self.get_unchecked(index) })
104 }
105 }
106
107 pub unsafe fn get_unchecked(&self, index: usize) -> PixelFormat {
113 PixelFormat(unsafe { libcamera_pixel_formats_get(self.ptr.as_ptr(), index as _) })
114 }
115}
116
117impl<'d> IntoIterator for &'d PixelFormats {
118 type Item = PixelFormat;
119
120 type IntoIter = PixelFormatsIterator<'d>;
121
122 fn into_iter(self) -> Self::IntoIter {
123 PixelFormatsIterator {
124 formats: self,
125 index: 0,
126 }
127 }
128}
129
130impl Drop for PixelFormats {
131 fn drop(&mut self) {
132 unsafe { libcamera_pixel_formats_destroy(self.ptr.as_ptr()) }
133 }
134}
135
136pub struct PixelFormatsIterator<'d> {
137 formats: &'d PixelFormats,
138 index: usize,
139}
140
141impl Iterator for PixelFormatsIterator<'_> {
142 type Item = PixelFormat;
143
144 fn next(&mut self) -> Option<Self::Item> {
145 if let Some(next) = self.formats.get(self.index) {
146 self.index += 1;
147 Some(next)
148 } else {
149 None
150 }
151 }
152}