use super::*; use std::{io, path::Path}; type Load<'s> = Res<&'s [u8]>; pub trait LoadArgs { fn get(&self) -> Load<'_>; } impl LoadArgs for &[u8] { fn get(&self) -> Load<'_> { Ok(self) } } impl> LoadArgs for Res { fn get(&self) -> Load<'_> { match self.as_ref() { Ok(f) => Ok(f.as_ref()), Err(e) => Err(e.clone()), } } } impl uImage { pub fn load(data: impl LoadArgs) -> Res { let mut img = { Res(image::ImageReader::new(io::Cursor::new(data.get()?)).with_guessed_format())? .decode() .explain_err(|| "Cannot decode image")? }; image::imageops::flip_vertical_in_place(&mut img); let ((w, h), data) = match S::TYPE { gl::RED => { let img = img.into_luma8(); (img.dimensions(), img.pixels().flat_map(|image::Luma(p)| p).copied().collect()) } gl::RGB => { let img = img.into_rgb8(); (img.dimensions(), img.pixels().flat_map(|image::Rgb(p)| p).copied().collect()) } gl::RGBA => { let img = img.into_rgba8(); (img.dimensions(), img.pixels().flat_map(|image::Rgba(p)| p).copied().collect()) } _ => ERROR!("Not impl"), }; Ok(Self { w, h, data, s: Dummy }) } pub fn save(&self, name: impl AsRef) { use image::ColorType::*; let t = match S::SIZE { 1 => L8, 2 => La8, 3 => Rgb8, 4 => Rgba8, _ => unreachable!(), }; if let Err(e) = image::save_buffer(name, &self.data, self.w, self.h, t) { FAIL!("Cannot save image {e:?}"); } } } #[cfg(feature = "hdr")] impl Image { pub fn load(data: impl LoadArgs) -> Res { let img = io::BufReader::new(io::Cursor::new(data.get()?)); let img = image::codecs::hdr::HdrDecoder::new(img).explain_err(|| format!("Cannot decode hdr image"))?; let mut img = image::DynamicImage::from_decoder(img).explain_err(|| format!("Cannot decode hdr pixels"))?; image::imageops::flip_vertical_in_place(&mut img); let img = img.into_rgb32f(); let ((w, h), data) = (img.dimensions(), img.pixels().flat_map(|image::Rgb(p)| p).copied().collect()); Ok(Self { w, h, data, s: Dummy }) } }