Skip to main content

grafix_toolbox/kit/opengl/utility/image/
loading.rs

1use super::*;
2use std::{io, path::Path};
3
4type Load<'s> = Res<&'s [u8]>;
5pub trait LoadArgs {
6	fn get(&self) -> Load;
7}
8impl LoadArgs for &[u8] {
9	fn get(&self) -> Load {
10		Ok(self)
11	}
12}
13impl<T: AsRef<[u8]>> LoadArgs for Res<T> {
14	fn get(&self) -> Load {
15		self.as_ref().map(<_>::as_ref).res()
16	}
17}
18
19impl<S: TexSize> uImage<S> {
20	pub fn load(data: impl LoadArgs) -> Res<Self> {
21		let img = data
22			.get()?
23			.pipe(io::Cursor::new)
24			.pipe(image::ImageReader::new)
25			.with_guessed_format()
26			.res()?
27			.decode()
28			.explain_err(|| "Cannot decode image")?;
29
30		let ((w, h), data) = match S::TYPE {
31			gl::RED => {
32				let img = img.into_luma8();
33				(img.dimensions(), img.pixels().flat_map(|image::Luma(p)| p).copied().collect())
34			}
35			gl::RGB => {
36				let img = img.into_rgb8();
37				(img.dimensions(), img.pixels().flat_map(|image::Rgb(p)| p).copied().collect())
38			}
39			gl::RGBA => {
40				let img = img.into_rgba8();
41				(img.dimensions(), img.pixels().flat_map(|image::Rgba(p)| p).copied().collect())
42			}
43			_ => ERROR!("Not impl"),
44		};
45		Self { w, h, data, s: Dummy }.pipe(Ok)
46	}
47	pub fn save(&self, name: impl AsRef<Path>) {
48		use image::ColorType::*;
49		let t = match S::SIZE {
50			1 => L8,
51			2 => La8,
52			3 => Rgb8,
53			4 => Rgba8,
54			_ => unreachable!(),
55		};
56		let Self { w, h, ref data, .. } = *self;
57		image::save_buffer(name, data, w, h, t).explain_err(|| "Cannot save image").warn();
58	}
59}
60
61#[cfg(feature = "hdr")]
62impl Image<RGB, f32> {
63	pub fn load(data: impl LoadArgs) -> Res<Self> {
64		let img = data
65			.get()?
66			.pipe(io::Cursor::new)
67			.pipe(io::BufReader::new)
68			.pipe(image::codecs::hdr::HdrDecoder::new)
69			.explain_err(|| "Cannot decode hdr image")?
70			.pipe(image::DynamicImage::from_decoder)
71			.explain_err(|| "Cannot decode hdr pixels")?
72			.tap(image::imageops::flip_vertical_in_place)
73			.into_rgb32f();
74
75		let ((w, h), data) = (img.dimensions(), img.pixels().flat_map(|image::Rgb(p)| p).copied().collect());
76		Self { w, h, data, s: Dummy }.pipe(Ok)
77	}
78}