1use crate::pixels::{
2 F32x2, F32x3, F32x4, InnerPixel, IntoPixelComponent, U16x2, U16x3, U16x4, U8x2, U8x3, U8x4,
3 F32, I32, U16, U8,
4};
5use crate::{
6 try_pixel_type, DifferentDimensionsError, ImageView, ImageViewMut, IntoImageView,
7 IntoImageViewMut, MappingError, PixelTrait, PixelType,
8};
9
10pub fn change_type_of_pixel_components(
11 src_image: &impl IntoImageView,
12 dst_image: &mut impl IntoImageViewMut,
13) -> Result<(), MappingError> {
14 macro_rules! map_dst {
15 (
16 $src_pt:ty, $dst_type:expr,
17 $(($dst_enum:path, $dst_pt:ty)),*
18 ) => {
19 match $dst_type {
20 $(
21 $dst_enum =>
22 change_components_type::<$src_pt, $dst_pt>(src_image, dst_image),
23 )*
24 _ => Err(MappingError::UnsupportedCombinationOfImageTypes),
25 }
26 }
27 }
28
29 let src_pixel_type = try_pixel_type(src_image)?;
30 let dst_pixel_type = try_pixel_type(dst_image)?;
31
32 use PixelType as PT;
33
34 #[cfg(not(feature = "only_u8x4"))]
35 match src_pixel_type {
36 PixelType::U8 => map_dst!(
37 U8,
38 dst_pixel_type,
39 (PT::U8, U8),
40 (PT::U16, U16),
41 (PT::I32, I32),
42 (PT::F32, F32)
43 ),
44 PixelType::U8x2 => map_dst!(
45 U8x2,
46 dst_pixel_type,
47 (PT::U8x2, U8x2),
48 (PT::U16x2, U16x2),
49 (PT::F32x2, F32x2)
50 ),
51 PixelType::U8x3 => map_dst!(
52 U8x3,
53 dst_pixel_type,
54 (PT::U8x3, U8x3),
55 (PT::U16x3, U16x3),
56 (PT::F32x3, F32x3)
57 ),
58 PixelType::U8x4 => map_dst!(
59 U8x4,
60 dst_pixel_type,
61 (PT::U8x4, U8x4),
62 (PT::U16x4, U16x4),
63 (PT::F32x4, F32x4)
64 ),
65 PixelType::U16 => map_dst!(
66 U16,
67 dst_pixel_type,
68 (PT::U8, U8),
69 (PT::U16, U16),
70 (PT::I32, I32),
71 (PT::F32, F32)
72 ),
73 PixelType::U16x2 => map_dst!(
74 U16x2,
75 dst_pixel_type,
76 (PT::U8x2, U8x2),
77 (PT::U16x2, U16x2),
78 (PT::F32x2, F32x2)
79 ),
80 PixelType::U16x3 => map_dst!(
81 U16x3,
82 dst_pixel_type,
83 (PT::U8x3, U8x3),
84 (PT::U16x3, U16x3),
85 (PT::F32x3, F32x3)
86 ),
87 PixelType::U16x4 => map_dst!(
88 U16x4,
89 dst_pixel_type,
90 (PT::U8x4, U8x4),
91 (PT::U16x4, U16x4),
92 (PT::F32x4, F32x4)
93 ),
94 PixelType::I32 => map_dst!(
95 I32,
96 dst_pixel_type,
97 (PT::U8, U8),
98 (PT::U16, U16),
99 (PT::I32, I32),
100 (PT::F32, F32)
101 ),
102 PixelType::F32 => map_dst!(
103 F32,
104 dst_pixel_type,
105 (PT::U8, U8),
106 (PT::U16, U16),
107 (PT::I32, I32),
108 (PT::F32, F32)
109 ),
110 PixelType::F32x2 => map_dst!(
111 F32x2,
112 dst_pixel_type,
113 (PT::U8x2, U8x2),
114 (PT::U16x2, U16x2),
115 (PT::F32x2, F32x2)
116 ),
117 PixelType::F32x3 => map_dst!(
118 F32x3,
119 dst_pixel_type,
120 (PT::U8x3, U8x3),
121 (PT::U16x3, U16x3),
122 (PT::F32x3, F32x3)
123 ),
124 PixelType::F32x4 => map_dst!(
125 F32x4,
126 dst_pixel_type,
127 (PT::U8x4, U8x4),
128 (PT::U16x4, U16x4),
129 (PT::F32x4, F32x4)
130 ),
131 }
132
133 #[cfg(feature = "only_u8x4")]
134 match src_pixel_type {
135 PixelType::U8x4 => map_dst!(U8x4, dst_pixel_type, (PT::U8x4, U8x4)),
136 _ => Err(MappingError::UnsupportedCombinationOfImageTypes),
137 }
138}
139
140#[inline(always)]
141fn change_components_type<S, D>(
142 src_image: &impl IntoImageView,
143 dst_image: &mut impl IntoImageViewMut,
144) -> Result<(), MappingError>
145where
146 S: PixelTrait,
147 D: PixelTrait<CountOfComponents = S::CountOfComponents>,
148 <S as InnerPixel>::Component: IntoPixelComponent<<D as InnerPixel>::Component>,
149{
150 match (src_image.image_view::<S>(), dst_image.image_view_mut::<D>()) {
151 (Some(src_view), Some(mut dst_view)) => {
152 change_type_of_pixel_components_typed(&src_view, &mut dst_view).map_err(|e| e.into())
153 }
154 _ => Err(MappingError::UnsupportedCombinationOfImageTypes),
155 }
156}
157
158pub fn change_type_of_pixel_components_typed<S, D>(
159 src_image: &impl ImageView<Pixel = S>,
160 dst_image: &mut impl ImageViewMut<Pixel = D>,
161) -> Result<(), DifferentDimensionsError>
162where
163 S: InnerPixel,
164 D: InnerPixel<CountOfComponents = S::CountOfComponents>,
165 <S as InnerPixel>::Component: IntoPixelComponent<<D as InnerPixel>::Component>,
166{
167 if src_image.width() != dst_image.width() || src_image.height() != dst_image.height() {
168 return Err(DifferentDimensionsError);
169 }
170
171 for (s_row, d_row) in src_image.iter_rows(0).zip(dst_image.iter_rows_mut(0)) {
172 let s_components = S::components(s_row);
173 let d_components = D::components_mut(d_row);
174 for (&s_comp, d_comp) in s_components.iter().zip(d_components) {
175 *d_comp = s_comp.into_component();
176 }
177 }
178 Ok(())
179}