fast_image_resize/
change_components_type.rs

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}