use png::{BitDepth, ColorType, Decoder, DecodingError};
use std::fs::File;
use crate::tracer::Color;
#[derive(Clone)]
pub struct Image {
pub buffer: Vec<Color>,
pub width: u32,
pub height: u32,
}
impl Image {
pub fn from_path(path: &str) -> Result<Self, DecodingError> {
println!("Decoding \"{}\"", path);
Self::from_file(File::open(path)?)
}
pub fn from_file(file: File) -> Result<Self, DecodingError> {
let decoder = Decoder::new(file);
let mut reader = decoder.read_info()?;
let mut bytes = vec![0; reader.output_buffer_size()];
let info = reader.next_frame(&mut bytes)?;
assert!(info.bit_depth == BitDepth::Eight);
let buffer = match info.color_type {
ColorType::Rgb => {
bytes[..info.buffer_size()]
.chunks(3)
.map(|rgb| Color::new(rgb[0], rgb[1], rgb[2]))
.collect()
}
ColorType::Rgba => {
bytes[..info.buffer_size()]
.chunks(4)
.map(|rgba| Color::new(rgba[0], rgba[1], rgba[2]))
.collect()
}
_ => panic!("unsupported image type {:?}", info.color_type),
};
let width = info.width;
let height = info.height;
println!("Decoded succesfully");
Ok(Self {
buffer,
width,
height,
})
}
}