grafix_toolbox/kit/opengl/utility/image/
loading.rs1use 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}