1pub fn flip_vertical<T>(data: &mut [T], width: usize, height: usize) {
7 assert!(data.len() == width * height);
8 let data_ptr = data.as_mut_ptr();
9 let row_size = width;
10 unsafe {
11 for y in 0..(height / 2) {
12 let top_row_start = data_ptr.add(y * row_size);
13 let bottom_row_start = data_ptr.add((height - 1 - y) * row_size);
14 std::ptr::swap_nonoverlapping(top_row_start, bottom_row_start, row_size);
15 }
16 }
17}
18
19pub fn bgr_to_rgb(data: &mut [(u8, u8, u8)]) {
22 for pixel in data.iter_mut() {
23 let (b, g, r) = *pixel;
24 *pixel = (r, g, b);
25 }
26}
27
28#[inline]
30pub fn rgb_to_bgr(data: &mut [(u8, u8, u8)]) {
31 bgr_to_rgb(data);
32}
33
34pub fn bgr_to_rgb_bytes(data: &mut [u8]) {
41 assert!(data.len().is_multiple_of(3));
42 for chunk in data.chunks_exact_mut(3) {
43 chunk.swap(0, 2);
44 }
45}
46
47#[inline]
49pub fn rgb_to_bgr_bytes(data: &mut [u8]) {
50 bgr_to_rgb_bytes(data);
51}
52
53pub fn rgba_to_bgra(data: &mut [(u8, u8, u8, u8)]) {
56 for pixel in data.iter_mut() {
57 let (b, g, r, a) = *pixel;
58 *pixel = (r, g, b, a);
59 }
60}
61
62#[inline]
64pub fn bgra_to_rgba(data: &mut [(u8, u8, u8, u8)]) {
65 rgba_to_bgra(data);
66}
67
68pub fn rgba_to_bgra_bytes(data: &mut [u8]) {
75 assert!(data.len().is_multiple_of(4));
76 for chunk in data.chunks_exact_mut(4) {
77 chunk.swap(0, 2);
78 }
79}
80
81#[inline]
83pub fn bgra_to_rgba_bytes(data: &mut [u8]) {
84 rgba_to_bgra_bytes(data);
85}
86
87#[macro_export]
104macro_rules! bitflag {
105 ($ty:ty { $($name:ident : $bit:expr),* $(,)? }) => {
106 {
107 let mut value: $ty = ::std::default::Default::default();
108 $(
109 value.$name = $bit;
110 )*
111 value
112 }
113 }
114}
115
116pub(crate) fn catch_unwind_with_panic_info<F, R>(f: F) -> Result<R, String>
117where
118 F: FnOnce() -> R + std::panic::UnwindSafe,
119{
120 match std::panic::catch_unwind(f) {
121 Ok(result) => Ok(result),
122 Err(err) => {
123 if let Some(s) = err.downcast_ref::<&str>() {
124 Err(s.to_string())
125 } else if let Some(s) = err.downcast_ref::<String>() {
126 Err(s.clone())
127 } else {
128 Err("<unknown panic".to_string())
129 }
130 }
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137 #[test]
138 fn test_flip_vertical() {
139 let mut data = vec![
140 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ];
144 flip_vertical(&mut data, 6, 3);
145 assert_eq!(
146 data,
147 vec![
148 13, 14, 15, 16, 17, 18, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6
149 ]
150 );
151 }
152
153 #[test]
154 fn test_bgr_to_rgb() {
155 let mut data = vec![(0, 0, 255), (0, 255, 0), (255, 0, 0)];
156 bgr_to_rgb(&mut data);
157 assert_eq!(data, vec![(255, 0, 0), (0, 255, 0), (0, 0, 255)]);
158 }
159
160 #[test]
161 fn test_rgb_to_bgr() {
162 let mut data = vec![(255, 0, 0), (0, 255, 0), (0, 0, 255)];
163 rgb_to_bgr(&mut data);
164 assert_eq!(data, vec![(0, 0, 255), (0, 255, 0), (255, 0, 0)]);
165 }
166
167 #[test]
168 fn test_bgr_to_rgb_bytes() {
169 let mut data = vec![0, 0, 255, 0, 255, 0, 255, 0, 0];
170 bgr_to_rgb_bytes(&mut data);
171 assert_eq!(data, vec![255, 0, 0, 0, 255, 0, 0, 0, 255]);
172 }
173
174 #[test]
175 fn test_rgb_to_bgr_bytes() {
176 let mut data = vec![255, 0, 0, 0, 255, 0, 0, 0, 255];
177 rgb_to_bgr_bytes(&mut data);
178 assert_eq!(data, vec![0, 0, 255, 0, 255, 0, 255, 0, 0]);
179 }
180
181 #[test]
182 fn test_rgba_to_bgra() {
183 let mut data = vec![(255, 0, 0, 255), (0, 255, 0, 255), (0, 0, 255, 255)];
184 rgba_to_bgra(&mut data);
185 assert_eq!(
186 data,
187 vec![(0, 0, 255, 255), (0, 255, 0, 255), (255, 0, 0, 255)]
188 );
189 }
190
191 #[test]
192 fn test_bgra_to_rgba() {
193 let mut data = vec![(0, 0, 255, 255), (0, 255, 0, 255), (255, 0, 0, 255)];
194 bgra_to_rgba(&mut data);
195 assert_eq!(
196 data,
197 vec![(255, 0, 0, 255), (0, 255, 0, 255), (0, 0, 255, 255)]
198 );
199 }
200
201 #[test]
202 fn test_rgba_to_bgra_bytes() {
203 let mut data = vec![255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255];
204 rgba_to_bgra_bytes(&mut data);
205 assert_eq!(data, vec![0, 0, 255, 255, 0, 255, 0, 255, 255, 0, 0, 255]);
206 }
207
208 #[test]
209 fn test_bgra_to_rgba_bytes() {
210 let mut data = vec![0, 0, 255, 255, 0, 255, 0, 255, 255, 0, 0, 255];
211 bgra_to_rgba_bytes(&mut data);
212 assert_eq!(data, vec![255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255]);
213 }
214}