Creation of TIM Tool #15

Merged
jaby merged 32 commits from topic/jb/tim_tool/slint-test into main 2025-02-16 21:26:32 +00:00
1 changed files with 27 additions and 13 deletions
Showing only changes of commit 7a7b710ca4 - Show all commits

View File

@ -9,30 +9,35 @@ 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))})?;
let info = reader.info().clone(); let info = reader.info().clone();
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 bit_depth = frame_info.bit_depth; let bytes_per_pixel = info.bytes_per_pixel();
let mut image_data = SharedPixelBuffer::new(frame_info.width, frame_info.height); 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 { 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})
} }
} }