Coverage Report

Created: 2026-06-18 07:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/image/src/imageops/affine.rs
Line
Count
Source
1
//! Functions for performing affine transformations.
2
3
use crate::error::{ImageError, ParameterError, ParameterErrorKind};
4
use crate::traits::Pixel;
5
use crate::{GenericImage, GenericImageView, ImageBuffer};
6
7
/// Rotate an image 90 degrees clockwise.
8
0
pub fn rotate90<I: GenericImageView>(
9
0
    image: &I,
10
0
) -> ImageBuffer<I::Pixel, Vec<<I::Pixel as Pixel>::Subpixel>> {
11
0
    let (width, height) = image.dimensions();
12
0
    let mut out = image.buffer_with_dimensions(height, width);
13
0
    let _ = rotate90_in(image, &mut out);
14
0
    out
15
0
}
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate90::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>
16
17
/// Rotate an image 180 degrees clockwise.
18
0
pub fn rotate180<I: GenericImageView>(
19
0
    image: &I,
20
0
) -> ImageBuffer<I::Pixel, Vec<<I::Pixel as Pixel>::Subpixel>> {
21
0
    let (width, height) = image.dimensions();
22
0
    let mut out = image.buffer_with_dimensions(width, height);
23
0
    let _ = rotate180_in(image, &mut out);
24
0
    out
25
0
}
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate180::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>
26
27
/// Rotate an image 270 degrees clockwise.
28
0
pub fn rotate270<I: GenericImageView>(
29
0
    image: &I,
30
0
) -> ImageBuffer<I::Pixel, Vec<<I::Pixel as Pixel>::Subpixel>> {
31
0
    let (width, height) = image.dimensions();
32
0
    let mut out = image.buffer_with_dimensions(height, width);
33
0
    let _ = rotate270_in(image, &mut out);
34
0
    out
35
0
}
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate270::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>
36
37
/// Rotate an image 90 degrees clockwise and put the result into the destination [`ImageBuffer`].
38
0
pub fn rotate90_in<I, Container>(
39
0
    image: &I,
40
0
    destination: &mut ImageBuffer<I::Pixel, Container>,
41
0
) -> crate::ImageResult<()>
42
0
where
43
0
    I: GenericImageView,
44
0
    Container: std::ops::DerefMut<Target = [<I::Pixel as Pixel>::Subpixel]>,
45
{
46
0
    let ((w0, h0), (w1, h1)) = (image.dimensions(), destination.dimensions());
47
0
    if w0 != h1 || h0 != w1 {
48
0
        return Err(ImageError::Parameter(ParameterError::from_kind(
49
0
            ParameterErrorKind::DimensionMismatch,
50
0
        )));
51
0
    }
52
53
0
    for y in 0..h0 {
54
0
        for x in 0..w0 {
55
0
            let p = image.get_pixel(x, y);
56
0
            destination.put_pixel(h0 - y - 1, x, p);
57
0
        }
58
    }
59
0
    Ok(())
60
0
}
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate90_in::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
61
62
/// Rotate an image 180 degrees clockwise and put the result into the destination [`ImageBuffer`].
63
0
pub fn rotate180_in<I, Container>(
64
0
    image: &I,
65
0
    destination: &mut ImageBuffer<I::Pixel, Container>,
66
0
) -> crate::ImageResult<()>
67
0
where
68
0
    I: GenericImageView,
69
0
    Container: std::ops::DerefMut<Target = [<I::Pixel as Pixel>::Subpixel]>,
70
{
71
0
    let ((w0, h0), (w1, h1)) = (image.dimensions(), destination.dimensions());
72
0
    if w0 != w1 || h0 != h1 {
73
0
        return Err(ImageError::Parameter(ParameterError::from_kind(
74
0
            ParameterErrorKind::DimensionMismatch,
75
0
        )));
76
0
    }
77
78
0
    for y in 0..h0 {
79
0
        for x in 0..w0 {
80
0
            let p = image.get_pixel(x, y);
81
0
            destination.put_pixel(w0 - x - 1, h0 - y - 1, p);
82
0
        }
83
    }
84
0
    Ok(())
85
0
}
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate180_in::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
86
87
/// Rotate an image 270 degrees clockwise and put the result into the destination [`ImageBuffer`].
88
0
pub fn rotate270_in<I, Container>(
89
0
    image: &I,
90
0
    destination: &mut ImageBuffer<I::Pixel, Container>,
91
0
) -> crate::ImageResult<()>
92
0
where
93
0
    I: GenericImageView,
94
0
    Container: std::ops::DerefMut<Target = [<I::Pixel as Pixel>::Subpixel]>,
95
{
96
0
    let ((w0, h0), (w1, h1)) = (image.dimensions(), destination.dimensions());
97
0
    if w0 != h1 || h0 != w1 {
98
0
        return Err(ImageError::Parameter(ParameterError::from_kind(
99
0
            ParameterErrorKind::DimensionMismatch,
100
0
        )));
101
0
    }
102
103
0
    for y in 0..h0 {
104
0
        for x in 0..w0 {
105
0
            let p = image.get_pixel(x, y);
106
0
            destination.put_pixel(y, w0 - x - 1, p);
107
0
        }
108
    }
109
0
    Ok(())
110
0
}
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::rotate270_in::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
111
112
/// Flip an image horizontally
113
0
pub fn flip_horizontal<I: GenericImageView>(
114
0
    image: &I,
115
0
) -> ImageBuffer<I::Pixel, Vec<<I::Pixel as Pixel>::Subpixel>> {
116
0
    let mut out = image.buffer_like();
117
0
    let _ = flip_horizontal_in(image, &mut out);
118
0
    out
119
0
}
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>
120
121
/// Flip an image vertically
122
0
pub fn flip_vertical<I: GenericImageView>(
123
0
    image: &I,
124
0
) -> ImageBuffer<I::Pixel, Vec<<I::Pixel as Pixel>::Subpixel>> {
125
0
    let mut out = image.buffer_like();
126
0
    let _ = flip_vertical_in(image, &mut out);
127
0
    out
128
0
}
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>
129
130
/// Flip an image horizontally and put the result into the destination [`ImageBuffer`].
131
0
pub fn flip_horizontal_in<I, Container>(
132
0
    image: &I,
133
0
    destination: &mut ImageBuffer<I::Pixel, Container>,
134
0
) -> crate::ImageResult<()>
135
0
where
136
0
    I: GenericImageView,
137
0
    Container: std::ops::DerefMut<Target = [<I::Pixel as Pixel>::Subpixel]>,
138
{
139
0
    let ((w0, h0), (w1, h1)) = (image.dimensions(), destination.dimensions());
140
0
    if w0 != w1 || h0 != h1 {
141
0
        return Err(ImageError::Parameter(ParameterError::from_kind(
142
0
            ParameterErrorKind::DimensionMismatch,
143
0
        )));
144
0
    }
145
146
0
    for y in 0..h0 {
147
0
        for x in 0..w0 {
148
0
            let p = image.get_pixel(x, y);
149
0
            destination.put_pixel(w0 - x - 1, y, p);
150
0
        }
151
    }
152
0
    Ok(())
153
0
}
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
154
155
/// Flip an image vertically and put the result into the destination [`ImageBuffer`].
156
0
pub fn flip_vertical_in<I, Container>(
157
0
    image: &I,
158
0
    destination: &mut ImageBuffer<I::Pixel, Container>,
159
0
) -> crate::ImageResult<()>
160
0
where
161
0
    I: GenericImageView,
162
0
    Container: std::ops::DerefMut<Target = [<I::Pixel as Pixel>::Subpixel]>,
163
{
164
0
    let ((w0, h0), (w1, h1)) = (image.dimensions(), destination.dimensions());
165
0
    if w0 != w1 || h0 != h1 {
166
0
        return Err(ImageError::Parameter(ParameterError::from_kind(
167
0
            ParameterErrorKind::DimensionMismatch,
168
0
        )));
169
0
    }
170
171
0
    for y in 0..h0 {
172
0
        for x in 0..w0 {
173
0
            let p = image.get_pixel(x, y);
174
0
            destination.put_pixel(x, h0 - 1 - y, p);
175
0
        }
176
    }
177
0
    Ok(())
178
0
}
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>, alloc::vec::Vec<f32>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>, alloc::vec::Vec<u8>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>, alloc::vec::Vec<u16>>
179
180
/// Rotate an image 180 degrees clockwise in place.
181
1
pub fn rotate180_in_place<I: GenericImage>(image: &mut I) {
182
1
    let (width, height) = image.dimensions();
183
184
1
    for y in 0..height / 2 {
185
0
        for x in 0..width {
186
0
            let p = image.get_pixel(x, y);
187
0
188
0
            let x2 = width - x - 1;
189
0
            let y2 = height - y - 1;
190
0
191
0
            let p2 = image.get_pixel(x2, y2);
192
0
            image.put_pixel(x, y, p2);
193
0
            image.put_pixel(x2, y2, p);
194
0
        }
195
    }
196
197
1
    if height % 2 != 0 {
198
1
        let middle = height / 2;
199
200
1
        for x in 0..width / 2 {
201
1
            let p = image.get_pixel(x, middle);
202
1
            let x2 = width - x - 1;
203
1
204
1
            let p2 = image.get_pixel(x2, middle);
205
1
            image.put_pixel(x, middle, p2);
206
1
            image.put_pixel(x2, middle, p);
207
1
        }
208
0
    }
209
1
}
Unexecuted instantiation: image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>
image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>
Line
Count
Source
181
1
pub fn rotate180_in_place<I: GenericImage>(image: &mut I) {
182
1
    let (width, height) = image.dimensions();
183
184
1
    for y in 0..height / 2 {
185
0
        for x in 0..width {
186
0
            let p = image.get_pixel(x, y);
187
0
188
0
            let x2 = width - x - 1;
189
0
            let y2 = height - y - 1;
190
0
191
0
            let p2 = image.get_pixel(x2, y2);
192
0
            image.put_pixel(x, y, p2);
193
0
            image.put_pixel(x2, y2, p);
194
0
        }
195
    }
196
197
1
    if height % 2 != 0 {
198
1
        let middle = height / 2;
199
200
1
        for x in 0..width / 2 {
201
1
            let p = image.get_pixel(x, middle);
202
1
            let x2 = width - x - 1;
203
1
204
1
            let p2 = image.get_pixel(x2, middle);
205
1
            image.put_pixel(x, middle, p2);
206
1
            image.put_pixel(x2, middle, p);
207
1
        }
208
0
    }
209
1
}
Unexecuted instantiation: image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::rotate180_in_place::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>
210
211
/// Flip an image horizontally in place.
212
0
pub fn flip_horizontal_in_place<I: GenericImage>(image: &mut I) {
213
0
    let (width, height) = image.dimensions();
214
215
0
    for y in 0..height {
216
0
        for x in 0..width / 2 {
217
0
            let x2 = width - x - 1;
218
0
            let p2 = image.get_pixel(x2, y);
219
0
            let p = image.get_pixel(x, y);
220
0
            image.put_pixel(x2, y, p);
221
0
            image.put_pixel(x, y, p2);
222
0
        }
223
    }
224
0
}
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_horizontal_in_place::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>
225
226
/// Flip an image vertically in place.
227
0
pub fn flip_vertical_in_place<I: GenericImage>(image: &mut I) {
228
0
    let (width, height) = image.dimensions();
229
230
0
    for y in 0..height / 2 {
231
0
        for x in 0..width {
232
0
            let y2 = height - y - 1;
233
0
            let p2 = image.get_pixel(x, y2);
234
0
            let p = image.get_pixel(x, y);
235
0
            image.put_pixel(x, y2, p);
236
0
            image.put_pixel(x, y, p2);
237
0
        }
238
    }
239
0
}
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>
Unexecuted instantiation: image::imageops::affine::flip_vertical_in_place::<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>
240
241
#[cfg(test)]
242
mod test {
243
    use super::{
244
        flip_horizontal, flip_horizontal_in_place, flip_vertical, flip_vertical_in_place,
245
        rotate180, rotate180_in_place, rotate270, rotate90,
246
    };
247
248
    use crate::traits::Pixel;
249
    use crate::{GenericImage, GrayImage, ImageBuffer};
250
251
    macro_rules! assert_pixels_eq {
252
        ($actual:expr, $expected:expr) => {{
253
            let actual_dim = $actual.dimensions();
254
            let expected_dim = $expected.dimensions();
255
256
            if actual_dim != expected_dim {
257
                panic!(
258
                    "dimensions do not match. \
259
                     actual: {:?}, expected: {:?}",
260
                    actual_dim, expected_dim
261
                )
262
            }
263
264
            let diffs = pixel_diffs($actual, $expected);
265
266
            if !diffs.is_empty() {
267
                let mut err = "".to_string();
268
269
                let diff_messages = diffs
270
                    .iter()
271
                    .take(5)
272
                    .map(|d| format!("\nactual: {:?}, expected {:?} ", d.0, d.1))
273
                    .collect::<Vec<_>>()
274
                    .join("");
275
276
                err.push_str(&diff_messages);
277
                panic!("pixels do not match. {:?}", err)
278
            }
279
        }};
280
    }
281
282
    #[test]
283
    fn test_rotate90() {
284
        let image: GrayImage =
285
            ImageBuffer::from_raw(3, 2, vec![0u8, 1u8, 2u8, 10u8, 11u8, 12u8]).unwrap();
286
287
        let expected: GrayImage =
288
            ImageBuffer::from_raw(2, 3, vec![10u8, 0u8, 11u8, 1u8, 12u8, 2u8]).unwrap();
289
290
        assert_pixels_eq!(&rotate90(&image), &expected);
291
    }
292
293
    #[test]
294
    fn test_rotate180() {
295
        let image: GrayImage =
296
            ImageBuffer::from_raw(3, 2, vec![0u8, 1u8, 2u8, 10u8, 11u8, 12u8]).unwrap();
297
298
        let expected: GrayImage =
299
            ImageBuffer::from_raw(3, 2, vec![12u8, 11u8, 10u8, 2u8, 1u8, 0u8]).unwrap();
300
301
        assert_pixels_eq!(&rotate180(&image), &expected);
302
    }
303
304
    #[test]
305
    fn test_rotate270() {
306
        let image: GrayImage =
307
            ImageBuffer::from_raw(3, 2, vec![0u8, 1u8, 2u8, 10u8, 11u8, 12u8]).unwrap();
308
309
        let expected: GrayImage =
310
            ImageBuffer::from_raw(2, 3, vec![2u8, 12u8, 1u8, 11u8, 0u8, 10u8]).unwrap();
311
312
        assert_pixels_eq!(&rotate270(&image), &expected);
313
    }
314
315
    #[test]
316
    fn test_rotate180_in_place() {
317
        let mut image: GrayImage =
318
            ImageBuffer::from_raw(3, 2, vec![0u8, 1u8, 2u8, 10u8, 11u8, 12u8]).unwrap();
319
320
        let expected: GrayImage =
321
            ImageBuffer::from_raw(3, 2, vec![12u8, 11u8, 10u8, 2u8, 1u8, 0u8]).unwrap();
322
323
        rotate180_in_place(&mut image);
324
325
        assert_pixels_eq!(&image, &expected);
326
    }
327
328
    #[test]
329
    fn test_flip_horizontal() {
330
        let image: GrayImage =
331
            ImageBuffer::from_raw(3, 2, vec![0u8, 1u8, 2u8, 10u8, 11u8, 12u8]).unwrap();
332
333
        let expected: GrayImage =
334
            ImageBuffer::from_raw(3, 2, vec![2u8, 1u8, 0u8, 12u8, 11u8, 10u8]).unwrap();
335
336
        assert_pixels_eq!(&flip_horizontal(&image), &expected);
337
    }
338
339
    #[test]
340
    fn test_flip_vertical() {
341
        let image: GrayImage =
342
            ImageBuffer::from_raw(3, 2, vec![0u8, 1u8, 2u8, 10u8, 11u8, 12u8]).unwrap();
343
344
        let expected: GrayImage =
345
            ImageBuffer::from_raw(3, 2, vec![10u8, 11u8, 12u8, 0u8, 1u8, 2u8]).unwrap();
346
347
        assert_pixels_eq!(&flip_vertical(&image), &expected);
348
    }
349
350
    #[test]
351
    fn test_flip_horizontal_in_place() {
352
        let mut image: GrayImage =
353
            ImageBuffer::from_raw(3, 2, vec![0u8, 1u8, 2u8, 10u8, 11u8, 12u8]).unwrap();
354
355
        let expected: GrayImage =
356
            ImageBuffer::from_raw(3, 2, vec![2u8, 1u8, 0u8, 12u8, 11u8, 10u8]).unwrap();
357
358
        flip_horizontal_in_place(&mut image);
359
360
        assert_pixels_eq!(&image, &expected);
361
    }
362
363
    #[test]
364
    fn test_flip_vertical_in_place() {
365
        let mut image: GrayImage =
366
            ImageBuffer::from_raw(3, 2, vec![0u8, 1u8, 2u8, 10u8, 11u8, 12u8]).unwrap();
367
368
        let expected: GrayImage =
369
            ImageBuffer::from_raw(3, 2, vec![10u8, 11u8, 12u8, 0u8, 1u8, 2u8]).unwrap();
370
371
        flip_vertical_in_place(&mut image);
372
373
        assert_pixels_eq!(&image, &expected);
374
    }
375
376
    #[allow(clippy::type_complexity)]
377
    fn pixel_diffs<I, J, P>(left: &I, right: &J) -> Vec<((u32, u32, P), (u32, u32, P))>
378
    where
379
        I: GenericImage<Pixel = P>,
380
        J: GenericImage<Pixel = P>,
381
        P: Pixel + Eq,
382
    {
383
        left.pixels()
384
            .zip(right.pixels())
385
            .filter(|&(p, q)| p != q)
386
            .collect::<Vec<_>>()
387
    }
388
}