From 73184837af02668200fdea23f0dac8e768c99b21 Mon Sep 17 00:00:00 2001 From: G2-Games Date: Wed, 8 May 2024 12:24:03 -0500 Subject: [PATCH] Added extended header struct --- cz/src/common.rs | 85 ++++++++++++++++++++++++++++++++ cz/src/dynamic.rs | 8 ++- cz/src/formats/cz0.rs | 112 ++---------------------------------------- 3 files changed, 95 insertions(+), 110 deletions(-) diff --git a/cz/src/common.rs b/cz/src/common.rs index 4e3d6e3..edb96ab 100644 --- a/cz/src/common.rs +++ b/cz/src/common.rs @@ -213,6 +213,91 @@ impl CzHeader for CommonHeader { } } +#[derive(Debug, Clone, Copy)] +pub struct ExtendedHeader { + /// Unknown bytes + unknown_1: [u8; 5], + + /// Width of cropped image area + pub crop_width: u16, + + /// Height of cropped image area + pub crop_height: u16, + + /// Bounding box width + pub bounds_width: u16, + + /// Bounding box height + pub bounds_height: u16, + + /// Offset width + pub offset_width: Option, + + /// Offset height + pub offset_height: Option, + + unknown_2: Option, +} + +impl ExtendedHeader { + pub fn new( + input: &mut T, + common_header: &CommonHeader + ) -> Result { + let mut unknown_1 = [0u8; 5]; + input.read_exact(&mut unknown_1)?; + + let crop_width = input.read_u16::()?; + let crop_height = input.read_u16::()?; + + let bounds_width = input.read_u16::()?; + let bounds_height = input.read_u16::()?; + + let mut offset_width = None; + let mut offset_height = None; + let mut unknown_2 = None; + if common_header.length() > 28 { + offset_width = Some(input.read_u16::()?); + offset_height = Some(input.read_u16::()?); + + unknown_2 = Some(input.read_u32::()?); + } + + Ok(Self { + unknown_1, + + crop_width, + crop_height, + + bounds_width, + bounds_height, + + offset_width, + offset_height, + + unknown_2, + }) + } + + pub fn as_bytes(&self) -> Result, io::Error> { + let mut buf = vec![]; + + buf.write_all(&self.unknown_1)?; + buf.write_u16::(self.crop_width)?; + buf.write_u16::(self.crop_height)?; + buf.write_u16::(self.bounds_width)?; + buf.write_u16::(self.bounds_height)?; + + if self.offset_width.is_some() { + buf.write_u16::(self.offset_width.unwrap())?; + buf.write_u16::(self.offset_height.unwrap())?; + buf.write_u32::(self.unknown_2.unwrap())?; + } + + Ok(buf) + } +} + pub fn get_palette( input: &mut T, num_colors: usize, diff --git a/cz/src/dynamic.rs b/cz/src/dynamic.rs index 9b573d6..094657d 100644 --- a/cz/src/dynamic.rs +++ b/cz/src/dynamic.rs @@ -5,12 +5,13 @@ use std::{ use byteorder::ReadBytesExt; use crate::{ - common::{apply_palette, get_palette, CommonHeader, CzError, CzHeader, CzVersion}, + common::{apply_palette, get_palette, CommonHeader, CzError, CzHeader, CzVersion, ExtendedHeader}, formats::{cz0, cz1, cz2, cz3, cz4}, }; pub struct DynamicCz { header_common: CommonHeader, + header_extended: Option, palette: Option>, bitmap: Vec, } @@ -45,6 +46,10 @@ impl DynamicCz { pub fn decode(input: &mut T) -> Result { // Get the header common to all CZ images let header_common = CommonHeader::new(input)?; + let mut header_extended = None; + if header_common.length() > 15 && header_common.version() != CzVersion::CZ2 { + header_extended = Some(ExtendedHeader::new(input, &header_common)?); + } input.seek(SeekFrom::Start(header_common.length() as u64))?; // Get the color palette if the bit depth is 8 or less @@ -77,6 +82,7 @@ impl DynamicCz { Ok(Self { header_common, + header_extended, palette, bitmap, }) diff --git a/cz/src/formats/cz0.rs b/cz/src/formats/cz0.rs index 8b1f71a..f39acb1 100644 --- a/cz/src/formats/cz0.rs +++ b/cz/src/formats/cz0.rs @@ -1,113 +1,7 @@ -use std::io::{self, Read, Seek, Write}; -use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; +use std::io::{Read, Seek}; +use byteorder::ReadBytesExt; -use crate::common::{CommonHeader, CzError, CzHeader, CzVersion}; - -#[derive(Debug, Clone, Copy)] -pub struct Cz0Header { - /// Common CZ# header - pub common: CommonHeader, - - /// Unknown bytes - unknown_1: [u8; 5], - - /// Width of cropped image area - pub crop_width: u16, - - /// Height of cropped image area - pub crop_height: u16, - - /// Bounding box width - pub bounds_width: u16, - - /// Bounding box height - pub bounds_height: u16, - - /// Offset width - pub offset_width: Option, - - /// Offset height - pub offset_height: Option, - - unknown_2: Option<[u8; 4]>, -} - -impl Cz0Header { - fn new(bytes: &mut T) -> Result - where - Self: Sized, - { - let common = CommonHeader::new(bytes)?; - - if common.version() != CzVersion::CZ0 { - return Err(CzError::VersionMismatch(common.version() as u8, 0)); - } - - let mut unknown_1 = [0u8; 5]; - bytes.read_exact(&mut unknown_1)?; - - let crop_width = bytes.read_u16::()?; - let crop_height = bytes.read_u16::()?; - - let bounds_width = bytes.read_u16::()?; - let bounds_height = bytes.read_u16::()?; - - let mut offset_width = None; - let mut offset_height = None; - let mut unknown_2 = None; - if common.length() > 28 { - offset_width = Some(bytes.read_u16::()?); - offset_height = Some(bytes.read_u16::()?); - - let mut un_2 = [0u8; 4]; - bytes.read_exact(&mut un_2)?; - - unknown_2 = Some(un_2); - } - - Ok(Self { - common, - - unknown_1, - - crop_width, - crop_height, - - bounds_width, - bounds_height, - - offset_width, - offset_height, - - unknown_2, - }) - } - - fn to_bytes(&self) -> Result, io::Error> { - let mut buf = vec![]; - - buf.write_all(&self.common.to_bytes()?)?; - buf.write_all(&self.unknown_1)?; - buf.write_u16::(self.crop_width)?; - buf.write_u16::(self.crop_height)?; - buf.write_u16::(self.bounds_width)?; - buf.write_u16::(self.bounds_height)?; - - if self.common.length() > 28 { - buf.write_u16::(self.offset_width.unwrap())?; - buf.write_u16::(self.offset_height.unwrap())?; - buf.write_all(&self.unknown_2.unwrap())?; - } - - Ok(buf) - } -} - -#[derive(Debug)] -pub struct Cz0Image { - header: Cz0Header, - bitmap: Vec, -} +use crate::common::CzError; pub fn decode(bytes: &mut T) -> Result, CzError> { // Get the rest of the file, which is the bitmap