Creation of TIM Tool #15
|
@ -9,30 +9,35 @@ pub struct TIMInfo {
|
|||
|
||||
impl TIMInfo {
|
||||
pub fn from_image(path: &PathBuf) -> Result<TIMInfo, Error> {
|
||||
fn make_color(iter: &mut dyn std::iter::Iterator<Item = &u8>) -> Option<Rgba8Pixel> {
|
||||
fn make_color(iter: &mut dyn std::iter::Iterator<Item = &u8>, load_alpha: bool) -> Option<Rgba8Pixel> {
|
||||
Some(Rgba8Pixel::new(
|
||||
*iter.next()?, *iter.next()?, *iter.next()?,
|
||||
0xFF))
|
||||
if load_alpha {*iter.next()?} else {0xFF}))
|
||||
}
|
||||
|
||||
let mut reader = png::Decoder::new(File::open(path)?).read_info().or_else(|error| {Err(Error::from_error(error))})?;
|
||||
let info = reader.info().clone();
|
||||
|
||||
let mut buffer = vec![0; reader.output_buffer_size()];
|
||||
let frame_info = reader.next_frame(&mut buffer).or_else(|error| {Err(Error::from_error(error))})?;
|
||||
let bit_depth = frame_info.bit_depth;
|
||||
let mut image_data = SharedPixelBuffer::new(frame_info.width, frame_info.height);
|
||||
let mut buffer = vec![0; reader.output_buffer_size()];
|
||||
let frame_info = reader.next_frame(&mut buffer).or_else(|error| {Err(Error::from_error(error))})?;
|
||||
let bytes_per_pixel = info.bytes_per_pixel();
|
||||
let bit_depth = frame_info.bit_depth;
|
||||
let mut image_data = SharedPixelBuffer::new(frame_info.width, frame_info.height);
|
||||
let mut dst_pixels = image_data.make_mut_slice();
|
||||
|
||||
if bytes_per_pixel != 3 && bytes_per_pixel != 4 {
|
||||
return Err(Error::from_text(format!("Image has {} bytes per pixel, but only 3 and 4 bytes per pixel are supported", bytes_per_pixel)));
|
||||
}
|
||||
|
||||
if info.color_type == png::ColorType::Indexed {
|
||||
let palette = info.palette.ok_or(Error::from_str("Found indexed PNG without palette"))?;
|
||||
let mut palette_colors = Vec::new();
|
||||
let mut iter = palette.iter();
|
||||
|
||||
while let Some(color) = make_color(&mut iter) {
|
||||
while let Some(color) = make_color(&mut iter, false) {
|
||||
palette_colors.push(color);
|
||||
}
|
||||
|
||||
let mut dst_pixels = image_data.make_mut_slice();
|
||||
for byte in buffer.into_iter() {
|
||||
match bit_depth {
|
||||
png::BitDepth::Four => {
|
||||
|
@ -44,15 +49,24 @@ impl TIMInfo {
|
|||
dst_pixels[0] = palette_colors[byte as usize];
|
||||
dst_pixels = &mut dst_pixels[1..];
|
||||
},
|
||||
_ => {return Err(Error::from_str("Only 4 and 8bit color depth are supported"));}
|
||||
_ => {return Err(Error::from_str("Only 4 and 8bit color depth are supported for indexed color images"));}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(TIMInfo{image_data, palette: Some(palette_colors)})
|
||||
}
|
||||
|
||||
else {
|
||||
Err(Error::not_implemented("Support for non indexed images"))
|
||||
let mut byte_iter = buffer.iter();
|
||||
while let Some(color) = make_color(&mut byte_iter, bytes_per_pixel == 4) {
|
||||
match bit_depth {
|
||||
png::BitDepth::Eight => {
|
||||
dst_pixels[0] = color;
|
||||
dst_pixels = &mut dst_pixels[1..];
|
||||
}
|
||||
_ => {return Err(Error::from_str("Only 8bit color depth are supported for direct color images"));}
|
||||
}
|
||||
}
|
||||
Ok(TIMInfo{image_data, palette: None})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue