Creation of TIM Tool #15
|
@ -9,10 +9,10 @@ pub struct TIMInfo {
|
||||||
|
|
||||||
impl TIMInfo {
|
impl TIMInfo {
|
||||||
pub fn from_image(path: &PathBuf) -> Result<TIMInfo, Error> {
|
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(
|
Some(Rgba8Pixel::new(
|
||||||
*iter.next()?, *iter.next()?, *iter.next()?,
|
*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 mut reader = png::Decoder::new(File::open(path)?).read_info().or_else(|error| {Err(Error::from_error(error))})?;
|
||||||
|
@ -20,19 +20,24 @@ impl TIMInfo {
|
||||||
|
|
||||||
let mut buffer = vec![0; reader.output_buffer_size()];
|
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 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 bit_depth = frame_info.bit_depth;
|
||||||
let mut image_data = SharedPixelBuffer::new(frame_info.width, frame_info.height);
|
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 {
|
if info.color_type == png::ColorType::Indexed {
|
||||||
let palette = info.palette.ok_or(Error::from_str("Found indexed PNG without palette"))?;
|
let palette = info.palette.ok_or(Error::from_str("Found indexed PNG without palette"))?;
|
||||||
let mut palette_colors = Vec::new();
|
let mut palette_colors = Vec::new();
|
||||||
let mut iter = palette.iter();
|
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);
|
palette_colors.push(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut dst_pixels = image_data.make_mut_slice();
|
|
||||||
for byte in buffer.into_iter() {
|
for byte in buffer.into_iter() {
|
||||||
match bit_depth {
|
match bit_depth {
|
||||||
png::BitDepth::Four => {
|
png::BitDepth::Four => {
|
||||||
|
@ -44,15 +49,24 @@ impl TIMInfo {
|
||||||
dst_pixels[0] = palette_colors[byte as usize];
|
dst_pixels[0] = palette_colors[byte as usize];
|
||||||
dst_pixels = &mut dst_pixels[1..];
|
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)})
|
Ok(TIMInfo{image_data, palette: Some(palette_colors)})
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
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