show_image/features/
image.rs1use std::ops::Deref;
4
5use crate::error::ImageDataError;
6use crate::Alpha;
7use crate::AsImageView;
8use crate::BoxImage;
9use crate::Image;
10use crate::ImageInfo;
11use crate::ImageView;
12use crate::PixelFormat;
13use crate::error::UnsupportedImageFormat;
14
15impl AsImageView for image::DynamicImage {
16 fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
17 let info = dynamic_image_info(self)?;
18 let data = dynamic_image_as_bytes(self);
19 Ok(ImageView::new(info, data))
20 }
21}
22
23impl AsImageView for &'_ image::DynamicImage {
24 fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
25 (*self).as_image_view()
26 }
27}
28
29impl From<image::DynamicImage> for Image {
30 fn from(other: image::DynamicImage) -> Self {
31 let info = match dynamic_image_info(&other) {
32 Ok(x) => x,
33 Err(e) => return Self::Invalid(e),
34 };
35 let data = dynamic_image_into_bytes(other);
36 BoxImage::new(info, data).into()
37 }
38}
39
40impl<P, Container> AsImageView for image::ImageBuffer<P, Container>
41where
42 P: image::Pixel<Subpixel = u8> + image::PixelWithColorType,
43 Container: Deref<Target = [u8]>,
44{
45 fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
46 let info = info(self)?;
47 let data = as_bytes(self);
48 Ok(ImageView::new(info, data))
49 }
50}
51
52impl<P, Container> AsImageView for &'_ image::ImageBuffer<P, Container>
53where
54 P: image::Pixel<Subpixel = u8> + image::PixelWithColorType,
55 Container: Deref<Target = [u8]>,
56{
57 fn as_image_view(&self) -> Result<ImageView, ImageDataError> {
58 (*self).as_image_view()
59 }
60}
61
62impl<P, Container> From<image::ImageBuffer<P, Container>> for Image
63where
64 P: image::Pixel<Subpixel = u8> + image::PixelWithColorType,
65 Container: Deref<Target = [u8]>,
66{
67 fn from(other: image::ImageBuffer<P, Container>) -> Self {
68 let info = match info(&other) {
69 Ok(x) => x,
70 Err(e) => return Self::Invalid(e),
71 };
72 let data = into_bytes(other);
73 BoxImage::new(info, data).into()
74 }
75}
76
77fn into_bytes<P, Container>(buffer: image::ImageBuffer<P, Container>) -> Box<[u8]>
79where
80 P: image::Pixel<Subpixel = u8> + image::PixelWithColorType,
81 Container: Deref<Target = [u8]>,
82{
83 Box::from(buffer.into_raw().deref())
86}
87
88fn dynamic_image_into_bytes(image: image::DynamicImage) -> Box<[u8]> {
89 match image {
90 image::DynamicImage::ImageLuma8(x) => into_bytes(x),
91 image::DynamicImage::ImageLumaA8(x) => into_bytes(x),
92 image::DynamicImage::ImageLuma16(_) => panic!("unsupported pixel format: Luma16"),
93 image::DynamicImage::ImageLumaA16(_) => panic!("unsupported pixel format: LumaA16"),
94 image::DynamicImage::ImageRgb8(x) => into_bytes(x),
95 image::DynamicImage::ImageRgba8(x) => into_bytes(x),
96 image::DynamicImage::ImageRgb16(_) => panic!("unsupported pixel format: Rgb16"),
97 image::DynamicImage::ImageRgba16(_) => panic!("unsupported pixel format: Rgba16"),
98 image::DynamicImage::ImageRgb32F(_) => panic!("unsupported pixel format: Rgb32F"),
99 image::DynamicImage::ImageRgba32F(_) => panic!("unsupported pixel format: Rgba32F"),
100 x => panic!("unsupported pixel format: {:?}", x),
101 }
102}
103
104fn as_bytes<P, Container>(buffer: &image::ImageBuffer<P, Container>) -> &[u8]
106where
107 P: image::Pixel<Subpixel = u8> + image::PixelWithColorType,
108 Container: Deref<Target = [u8]>,
109{
110 buffer
111}
112
113fn dynamic_image_as_bytes(image: &image::DynamicImage) -> &[u8] {
114 match image {
115 image::DynamicImage::ImageLuma8(x) => as_bytes(x),
116 image::DynamicImage::ImageLumaA8(x) => as_bytes(x),
117 image::DynamicImage::ImageLuma16(_) => panic!("unsupported pixel format: Luma16"),
118 image::DynamicImage::ImageLumaA16(_) => panic!("unsupported pixel format: LumaA16"),
119 image::DynamicImage::ImageRgb8(x) => as_bytes(x),
120 image::DynamicImage::ImageRgba8(x) => as_bytes(x),
121 image::DynamicImage::ImageRgb16(_) => panic!("unsupported pixel format: Rgb16"),
122 image::DynamicImage::ImageRgba16(_) => panic!("unsupported pixel format: Rgba16"),
123 image::DynamicImage::ImageRgb32F(_) => panic!("unsupported pixel format: Rgb32F"),
124 image::DynamicImage::ImageRgba32F(_) => panic!("unsupported pixel format: Rgba32F"),
125 x => panic!("unsupported pixel format: {:?}", x),
126 }
127}
128
129fn info<P, C>(image: &image::ImageBuffer<P, C>) -> Result<ImageInfo, ImageDataError>
131where
132 P: image::Pixel<Subpixel = u8> + image::PixelWithColorType,
133 C: std::ops::Deref<Target = [u8]>,
134{
135 Ok(ImageInfo {
136 pixel_format: pixel_format::<P>()?,
137 size: glam::UVec2::new(image.width(), image.height()),
138 stride: glam::UVec2::new(
139 image.sample_layout().width_stride as u32,
140 image.sample_layout().height_stride as u32,
141 ),
142 })
143}
144
145fn dynamic_image_info(image: &image::DynamicImage) -> Result<ImageInfo, ImageDataError> {
146 match image {
147 image::DynamicImage::ImageLuma8(x) => info(x),
148 image::DynamicImage::ImageLumaA8(x) => info(x),
149 image::DynamicImage::ImageRgb8(x) => info(x),
150 image::DynamicImage::ImageRgba8(x) => info(x),
151 x => Err(UnsupportedImageFormat { format: format!("{:?}", x) }.into()),
152 }
153}
154
155fn pixel_format<P: image::PixelWithColorType>() -> Result<PixelFormat, ImageDataError> {
157 match P::COLOR_TYPE {
158 image::ExtendedColorType::L8 => Ok(PixelFormat::Mono8),
159 image::ExtendedColorType::La8 => Ok(PixelFormat::MonoAlpha8(Alpha::Unpremultiplied)),
160 image::ExtendedColorType::Rgb8 => Ok(PixelFormat::Rgb8),
161 image::ExtendedColorType::Rgba8 => Ok(PixelFormat::Rgba8(Alpha::Unpremultiplied)),
162 x => Err(UnsupportedImageFormat { format: format!("{:?}", x) }.into()),
163 }
164}