1use crate::image::Sprite;
2use pagurus::failure::{Failure, OrFail};
3use pagurus::spatial::Size;
4use pagurus::Result;
5
6pub fn decode_sprite(png: &[u8]) -> Result<Sprite> {
7 let decoder = png::Decoder::new(png);
8 let mut reader = decoder.read_info().or_fail()?;
9 let mut buf = vec![0; reader.output_buffer_size()];
10 let info = reader.next_frame(&mut buf).or_fail()?;
11 let bytes = &buf[..info.buffer_size()];
12 let size = Size::from_wh(info.width, info.height);
13 (info.bit_depth == png::BitDepth::Eight)
14 .or_fail()
15 .map_err(|e| e.message(format!("unsupported PNG bit depth: {:?}", info.bit_depth)))?;
16
17 match info.color_type {
18 png::ColorType::Rgb => Sprite::from_rgb24_bytes(bytes, size).or_fail(),
19 png::ColorType::Rgba => Sprite::from_rgba32_bytes(bytes, size).or_fail(),
20 png::ColorType::Grayscale => Sprite::from_grayscale8_bytes(bytes, size).or_fail(),
21 png::ColorType::GrayscaleAlpha => {
22 Sprite::from_grayscale_alpha16_bytes(bytes, size).or_fail()
23 }
24 _ => {
25 Err(Failure::new()
26 .message(format!("unsupported PNG color type: {:?}", info.color_type)))
27 }
28 }
29}