Start reading in indexed PNG file

This commit is contained in:
jaby 2022-09-25 19:32:58 +02:00
parent d931cd7a61
commit 530fd10662
3 changed files with 68 additions and 26 deletions

View File

@ -0,0 +1,52 @@
use tool_helper::Error;
use super::types::Color;
pub enum OutputType {
TwoIndex,
OneIndex,
}
pub struct IndexedImage {
palette: Vec<Color>,
data: Vec<u8>,
bit_depth: png::BitDepth,
output_type: OutputType,
width: u16,
height: u16,
}
impl IndexedImage {
pub fn new<R: std::io::Read>(mut reader: png::Reader<R>, output_type: OutputType) -> Result<IndexedImage, Error> {
let action_name = "Creating IndexedImage";
let mut buffer = vec![0; reader.output_buffer_size()];
match reader.next_frame(&mut buffer) {
Ok(info) => {
let width = info.width as u16;
let height = info.height as u16;
let bit_depth = info.bit_depth;
if info.color_type != png::ColorType::Indexed {
return Err(Error::from_str("PNG file must be indexed").with_action(action_name));
}
if bit_depth != png::BitDepth::Four && bit_depth != png::BitDepth::Eight {
Err(Error::from_str("Only 4 and 8bit color depth are supported").with_action(action_name))
}
else {
Ok(IndexedImage{palette: Self::make_palette(), data: buffer, bit_depth, output_type, width, height})
}
}
Err(err) => {
Err(Error::from_error(err).with_action(action_name))
}
}
}
fn make_palette() -> Vec<Color> {
Vec::new()
}
}

View File

@ -1,11 +1,13 @@
use clap::{Args, ValueEnum};
use image::{DynamicImage, io::Reader as ImageReader};
use color_clut::IndexedImage;
use color_full16::{RgbaImage, RgbImage};
use std::io::Cursor;
use tool_helper::{Error, Input, Output};
use types::{Header, PSXImageConverter};
mod types;
mod color_clut;
mod color_full16;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
@ -75,34 +77,17 @@ fn convert_full16(input: Input, output: Output) -> Result<(), Error> {
}
}
fn convert_palette_based(input: Input, _: Output, _: ColorType) -> Result<(), Error> {
fn convert_palette_based(input: Input, _: Output, color_type: ColorType) -> Result<(), Error> {
match png::Decoder::new(input).read_info() {
Ok(mut reader) => {
let mut buf = vec![0; reader.output_buffer_size()];
loop {
match reader.next_frame(&mut buf) {
Ok(_) => {
println!("Frame: {}", buf.len());
for byte in &buf {
print!("[{}] ", byte);
}
println!("");
}
Err(err) => {
println!("Wuff: {}", err);
break;
}
Ok(reader) => {
let output_type = {
match color_type {
ColorType::Clut4 => color_clut::OutputType::TwoIndex,
ColorType::Clut8 => color_clut::OutputType::OneIndex,
_ => return Err(Error::from_str("ColorType not supported"))
}
}
let info = reader.info();
println!("picture: {} - {}, ({:?}, {:?}) ", info.width, info.height, info.color_type, info.bit_depth);
if let Some(pal) = &info.palette {
println!("Size of PAL: {}", pal.len());
}
};
let _image = IndexedImage::new(reader, output_type)?;
Err(Error::from_str("Under construction"))
},

View File

@ -49,6 +49,11 @@ impl Error {
pub fn ok_or_new<T, F>(option: Option<T>, error_text: F) -> Result<T, Error> where F: Fn () -> String{
Ok(option.ok_or(Error::from_callback(error_text))?)
}
pub fn with_action(mut self, action: &str) -> Error {
self.action = action.to_owned();
self
}
}
impl std::fmt::Display for Error {