use std::io::Cursor;
use png::{BitDepth, ColorType, Decoder, Transformations};
use rgb::RGBA8;
use super::Loader;
use crate::assets::Id;
#[non_exhaustive]
pub struct PngLoader;
impl Loader<(u32, u32, Vec<RGBA8>)> for PngLoader {
const EXTENSION: &'static str = "png";
#[inline]
fn load(bytes: &[u8], id: &Id) -> (u32, u32, Vec<RGBA8>) {
let cursor = Cursor::new(bytes.to_vec());
let mut decoder = Decoder::new(cursor);
decoder.set_ignore_text_chunk(true);
decoder.ignore_checksums(true);
decoder
.set_transformations(Transformations::normalize_to_color8() | Transformations::ALPHA);
let mut reader = decoder.read_info().unwrap();
let (color_type, bits) = reader.output_color_type();
assert!(
color_type == ColorType::Rgba && bits == BitDepth::Eight,
"PNG of asset with ID '{id}' is not 8 bit RGB with an alpha channel"
);
let mut pixels = vec![
RGBA8::default();
reader
.output_buffer_size()
.expect("Image size does not fit in memory")
];
let info = reader
.next_frame(bytemuck::cast_slice_mut(&mut pixels))
.expect("Error reading image");
(info.width, info.height, pixels)
}
}