pagurus_game_std/
png.rs

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}