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#[cfg(test)]
88mod tests {
89 use super::*;
90 #[test]
91 fn test_flip_vertical() {
92 let mut data = vec![
93 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ];
97 flip_vertical(&mut data, 6, 3);
98 assert_eq!(
99 data,
100 vec![
101 13, 14, 15, 16, 17, 18, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6
102 ]
103 );
104 }
105
106 #[test]
107 fn test_bgr_to_rgb() {
108 let mut data = vec![(0, 0, 255), (0, 255, 0), (255, 0, 0)];
109 bgr_to_rgb(&mut data);
110 assert_eq!(data, vec![(255, 0, 0), (0, 255, 0), (0, 0, 255)]);
111 }
112
113 #[test]
114 fn test_rgb_to_bgr() {
115 let mut data = vec![(255, 0, 0), (0, 255, 0), (0, 0, 255)];
116 rgb_to_bgr(&mut data);
117 assert_eq!(data, vec![(0, 0, 255), (0, 255, 0), (255, 0, 0)]);
118 }
119
120 #[test]
121 fn test_bgr_to_rgb_bytes() {
122 let mut data = vec![0, 0, 255, 0, 255, 0, 255, 0, 0];
123 bgr_to_rgb_bytes(&mut data);
124 assert_eq!(data, vec![255, 0, 0, 0, 255, 0, 0, 0, 255]);
125 }
126
127 #[test]
128 fn test_rgb_to_bgr_bytes() {
129 let mut data = vec![255, 0, 0, 0, 255, 0, 0, 0, 255];
130 rgb_to_bgr_bytes(&mut data);
131 assert_eq!(data, vec![0, 0, 255, 0, 255, 0, 255, 0, 0]);
132 }
133
134 #[test]
135 fn test_rgba_to_bgra() {
136 let mut data = vec![(255, 0, 0, 255), (0, 255, 0, 255), (0, 0, 255, 255)];
137 rgba_to_bgra(&mut data);
138 assert_eq!(
139 data,
140 vec![(0, 0, 255, 255), (0, 255, 0, 255), (255, 0, 0, 255)]
141 );
142 }
143
144 #[test]
145 fn test_bgra_to_rgba() {
146 let mut data = vec![(0, 0, 255, 255), (0, 255, 0, 255), (255, 0, 0, 255)];
147 bgra_to_rgba(&mut data);
148 assert_eq!(
149 data,
150 vec![(255, 0, 0, 255), (0, 255, 0, 255), (0, 0, 255, 255)]
151 );
152 }
153
154 #[test]
155 fn test_rgba_to_bgra_bytes() {
156 let mut data = vec![255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255];
157 rgba_to_bgra_bytes(&mut data);
158 assert_eq!(data, vec![0, 0, 255, 255, 0, 255, 0, 255, 255, 0, 0, 255]);
159 }
160
161 #[test]
162 fn test_bgra_to_rgba_bytes() {
163 let mut data = vec![0, 0, 255, 255, 0, 255, 0, 255, 255, 0, 0, 255];
164 bgra_to_rgba_bytes(&mut data);
165 assert_eq!(data, vec![255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255]);
166 }
167}