From 1673d6ef2c5585fdfd34a6ae95a2ecf187d7ff29 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 22 Dec 2024 21:48:17 +0100 Subject: [PATCH] Support 3 step writing --- src/Tools/psxfileconv/src/images/mod.rs | 12 ++++--- .../psxfileconv/src/images/reduced_tim/mod.rs | 6 ++-- .../src/images/reduced_tim/types.rs | 31 ++++++++++++------- src/Tools/psxfileconv/src/images/types.rs | 6 +++- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/Tools/psxfileconv/src/images/mod.rs b/src/Tools/psxfileconv/src/images/mod.rs index 378bd4cd..478b4fbc 100644 --- a/src/Tools/psxfileconv/src/images/mod.rs +++ b/src/Tools/psxfileconv/src/images/mod.rs @@ -36,7 +36,7 @@ fn modify_palette(mut image: IndexedImage, clut_align: ClutAlignment, semi_trans image } -fn encode(header_conv: &dyn HeaderEncoder, image: T, color_depth: ColorType, clut_align: ClutAlignment, output: &mut dyn Write) -> Result<(), Error> { +fn encode(header_conv: &mut dyn HeaderEncoder, image: T, color_depth: ColorType, clut_align: ClutAlignment, output: &mut dyn Write) -> Result<(), Error> { let (width, height) = { fn return_error(clut_type: u32, div: u32, width: u16, height: u16) -> Result<(u16, u16), Error> { return Err(Error::from_callback(|| {format!("CLUT {} images require a width divideable by {} (found width: {}/{}={}, height: {})", clut_type, div, width, div, (width as f32/div as f32), height)})); @@ -93,9 +93,10 @@ fn encode(header_conv: &dyn HeaderEncoder, image: T, color } }; - let header_raw = header_conv.encode(width, height, pal_width, pal_height)?; + header_conv.encode_settings(width, height, pal_width, pal_height)?; - output.write(&header_raw)?; + header_conv.write_header(output)?; + header_conv.write_clut_header(output)?; if let Some(palette) = palette { let mut color_count = pal_width*pal_height; for color in palette { @@ -109,6 +110,7 @@ fn encode(header_conv: &dyn HeaderEncoder, image: T, color } } + header_conv.write_pixel_header(output)?; for color in image { tool_helper::raw::write_raw(output, &color)?; } @@ -116,7 +118,7 @@ fn encode(header_conv: &dyn HeaderEncoder, image: T, color Ok(()) } -fn convert_full16(header_conv: &dyn HeaderEncoder, input: Input, output: &mut dyn Write) -> Result<(), Error> { +fn convert_full16(header_conv: &mut dyn HeaderEncoder, input: Input, output: &mut dyn Write) -> Result<(), Error> { match ImageReader::new(Cursor::new(tool_helper::input_to_vec(input)?)).with_guessed_format()?.decode() { Ok(image) => { match image { @@ -130,7 +132,7 @@ fn convert_full16(header_conv: &dyn HeaderEncoder, input: Input, output: &mut dy } } -fn convert_palette_based(header_conv: &dyn HeaderEncoder, input: Input, output: &mut dyn Write, color_type: ColorType, clut_align: ClutAlignment, semi_transparent: bool, transparent_palette: bool) -> Result<(), Error> { +fn convert_palette_based(header_conv: &mut dyn HeaderEncoder, input: Input, output: &mut dyn Write, color_type: ColorType, clut_align: ClutAlignment, semi_transparent: bool, transparent_palette: bool) -> Result<(), Error> { match png::Decoder::new(input).read_info() { Ok(reader) => { let output_type = { diff --git a/src/Tools/psxfileconv/src/images/reduced_tim/mod.rs b/src/Tools/psxfileconv/src/images/reduced_tim/mod.rs index 6dc4c4b4..f1e08d38 100644 --- a/src/Tools/psxfileconv/src/images/reduced_tim/mod.rs +++ b/src/Tools/psxfileconv/src/images/reduced_tim/mod.rs @@ -8,9 +8,9 @@ use tool_helper::{Error, Input}; pub type Arguments = super::args::Arguments; pub fn convert(args: Arguments, input: Input, output: &mut dyn Write) -> Result<(), Error> { - let header_conv = Header::default(); + let mut header_conv = Header::default(); match args.color_depth { - ColorType::Full16 => super::convert_full16(&header_conv, input, output), - _ => super::convert_palette_based(&header_conv, input, output, args.color_depth, args.clut_align, args.semi_transparent, args.transparent_palette), + ColorType::Full16 => super::convert_full16(&mut header_conv, input, output), + _ => super::convert_palette_based(&mut header_conv, input, output, args.color_depth, args.clut_align, args.semi_transparent, args.transparent_palette), } } \ No newline at end of file diff --git a/src/Tools/psxfileconv/src/images/reduced_tim/types.rs b/src/Tools/psxfileconv/src/images/reduced_tim/types.rs index bd783ae0..25190040 100644 --- a/src/Tools/psxfileconv/src/images/reduced_tim/types.rs +++ b/src/Tools/psxfileconv/src/images/reduced_tim/types.rs @@ -1,4 +1,5 @@ use super::super::types::{HeaderEncoder, set_member_value}; +use std::io::Write; use tool_helper::{bits::BitRange, raw::RawConversion, Error}; #[repr(packed(1))] @@ -7,14 +8,21 @@ pub struct Header { value: u32 } -#[allow(dead_code)] impl Header { const TEX_WIDTH_BIT_RANGE: BitRange = BitRange::from_to(0, 8); const TEX_HEIGHT_BIT_RANGE: BitRange = BitRange::from_to(9, 16); const CLUT_WIDTH_BIT_RANGE: BitRange = BitRange::from_to(17, 22); const CLUT_HEIGHT_BIT_RANGE: BitRange = BitRange::from_to(23, 31); +} - pub fn from(tex_width: u16, tex_height: u16, clut_width: u16, clut_height: u16) -> Result { +impl Default for Header { + fn default() -> Self { + Header{value: 0} + } +} + +impl HeaderEncoder for Header { + fn encode_settings(&mut self, tex_width: u16, tex_height: u16, clut_width: u16, clut_height: u16) -> Result<(), Error> { if tex_width & 1 == 1 || tex_height & 1 == 1 { Err(Error::from_text(format!("Image size (width: {}, height: {}) needs to be even", tex_width, tex_height))) } @@ -26,20 +34,21 @@ impl Header { clut_width, 4, u32), clut_height, 0, u32); - Ok(Header{value}) + self.value = value; + Ok(()) } } -} -impl Default for Header { - fn default() -> Self { - Header{value: 0} + fn write_header(&self, output: &mut dyn Write) -> Result { + Ok(output.write(&self.convert_to_raw())?) } -} -impl HeaderEncoder for Header { - fn encode(&self, tex_width: u16, tex_height: u16, clut_width: u16, clut_height: u16) -> Result, Error> { - Ok(Header::from(tex_width, tex_height, clut_width, clut_height)?.convert_to_raw().to_vec()) + fn write_clut_header(&self, _output: &mut dyn Write) -> Result { + Ok(0) + } + + fn write_pixel_header(&self, _output: &mut dyn Write) -> Result { + Ok(0) } } diff --git a/src/Tools/psxfileconv/src/images/types.rs b/src/Tools/psxfileconv/src/images/types.rs index b4ec0d72..42ef9597 100644 --- a/src/Tools/psxfileconv/src/images/types.rs +++ b/src/Tools/psxfileconv/src/images/types.rs @@ -1,3 +1,4 @@ +use std::io::Write; use tool_helper::{*, bits::BitRange, raw::RawConversion}; macro_rules! set_member_value { @@ -121,7 +122,10 @@ impl RawConversion<2> for Color { } pub trait HeaderEncoder { - fn encode(&self, tex_width: u16, tex_height: u16, clut_width: u16, clut_height: u16) -> Result, Error>; + fn encode_settings(&mut self, tex_width: u16, tex_height: u16, clut_width: u16, clut_height: u16) -> Result<(), Error>; + fn write_header(&self, output: &mut dyn Write) -> Result; + fn write_clut_header(&self, output: &mut dyn Write) -> Result; + fn write_pixel_header(&self, output: &mut dyn Write) -> Result; } pub trait PSXImageConverter: std::iter::Iterator {