Integrate all the progress into master #6
|
@ -36,7 +36,7 @@ fn modify_palette(mut image: IndexedImage, clut_align: ClutAlignment, semi_trans
|
|||
image
|
||||
}
|
||||
|
||||
fn encode<T: PSXImageConverter>(header_conv: &dyn HeaderEncoder, image: T, color_depth: ColorType, clut_align: ClutAlignment, output: &mut dyn Write) -> Result<(), Error> {
|
||||
fn encode<T: PSXImageConverter>(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<T: PSXImageConverter>(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<T: PSXImageConverter>(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<T: PSXImageConverter>(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 = {
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
|
@ -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<Header, Error> {
|
||||
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<usize, Error> {
|
||||
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<std::vec::Vec<u8>, 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<usize, Error> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn write_pixel_header(&self, _output: &mut dyn Write) -> Result<usize, Error> {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<std::vec::Vec<u8>, 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<usize, Error>;
|
||||
fn write_clut_header(&self, output: &mut dyn Write) -> Result<usize, Error>;
|
||||
fn write_pixel_header(&self, output: &mut dyn Write) -> Result<usize, Error>;
|
||||
}
|
||||
|
||||
pub trait PSXImageConverter: std::iter::Iterator<Item = Color> {
|
||||
|
|
Loading…
Reference in New Issue