1use libcamera_sys::*;
2
3use crate::camera::Orientation;
4
5#[derive(Clone, Copy, Debug)]
7pub struct Transform(pub libcamera_transform_t);
8
9impl Transform {
10 pub fn hflip() -> Self {
11 Transform(unsafe { libcamera_transform_hflip() })
12 }
13 pub fn vflip() -> Self {
14 Transform(unsafe { libcamera_transform_vflip() })
15 }
16 pub fn transpose() -> Self {
17 Transform(unsafe { libcamera_transform_transpose() })
18 }
19}
20
21impl Transform {
22 pub fn identity() -> Self {
23 Transform(unsafe { libcamera_transform_identity() })
24 }
25
26 pub fn from_rotation(angle: i32, hflip: bool) -> Option<Self> {
28 let mut success = false;
29 let t = unsafe { libcamera_transform_from_rotation(angle, hflip, &mut success) };
30 if success {
31 Some(Transform(t))
32 } else {
33 None
34 }
35 }
36
37 pub fn inverse(self) -> Self {
38 Transform(unsafe { libcamera_transform_inverse(self.0) })
39 }
40
41 pub fn combine(self, other: Transform) -> Self {
42 Transform(unsafe { libcamera_transform_combine(self.0, other.0) })
43 }
44
45 pub fn to_string_repr(self) -> String {
46 unsafe {
47 let ptr = libcamera_transform_to_string(self.0);
48 if ptr.is_null() {
49 return String::new();
50 }
51 let s = std::ffi::CStr::from_ptr(ptr).to_string_lossy().into_owned();
52 libc::free(ptr.cast());
53 s
54 }
55 }
56}
57
58impl std::fmt::Display for Transform {
59 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 f.write_str(&self.to_string_repr())
61 }
62}
63
64impl Transform {
65 pub fn between_orientations(from: Orientation, to: Orientation) -> Self {
67 Transform(unsafe { libcamera_transform_between_orientations(from.into(), to.into()) })
68 }
69}
70
71pub fn apply_transform_to_orientation(orientation: Orientation, transform: Transform) -> Orientation {
72 unsafe {
73 libcamera_transform_apply_orientation(orientation.into(), transform.0)
74 .try_into()
75 .unwrap()
76 }
77}
78
79pub fn orientation_from_rotation(angle: i32) -> Option<Orientation> {
81 let mut success = false;
82 let ori = unsafe { libcamera_orientation_from_rotation(angle, &mut success) };
83 if success {
84 ori.try_into().ok()
85 } else {
86 None
87 }
88}
89
90impl core::ops::BitOr for Transform {
91 type Output = Transform;
92 fn bitor(self, rhs: Self) -> Self::Output {
93 Transform(unsafe { libcamera_transform_or(self.0, rhs.0) })
94 }
95}
96
97impl core::ops::BitAnd for Transform {
98 type Output = Transform;
99 fn bitand(self, rhs: Self) -> Self::Output {
100 Transform(unsafe { libcamera_transform_and(self.0, rhs.0) })
101 }
102}
103
104impl core::ops::BitXor for Transform {
105 type Output = Transform;
106 fn bitxor(self, rhs: Self) -> Self::Output {
107 Transform(unsafe { libcamera_transform_xor(self.0, rhs.0) })
108 }
109}
110
111impl core::ops::Not for Transform {
112 type Output = Transform;
113 fn not(self) -> Self::Output {
114 Transform(unsafe { libcamera_transform_not(self.0) })
115 }
116}