mirror of
https://github.com/G2-Games/lbee-utils.git
synced 2025-04-19 07:12:55 -05:00
Added extended header struct
This commit is contained in:
parent
f4eb9ea1b3
commit
73184837af
3 changed files with 95 additions and 110 deletions
|
@ -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<u16>,
|
||||
|
||||
/// Offset height
|
||||
pub offset_height: Option<u16>,
|
||||
|
||||
unknown_2: Option<u32>,
|
||||
}
|
||||
|
||||
impl ExtendedHeader {
|
||||
pub fn new<T: Seek + ReadBytesExt + Read>(
|
||||
input: &mut T,
|
||||
common_header: &CommonHeader
|
||||
) -> Result<Self, CzError> {
|
||||
let mut unknown_1 = [0u8; 5];
|
||||
input.read_exact(&mut unknown_1)?;
|
||||
|
||||
let crop_width = input.read_u16::<LittleEndian>()?;
|
||||
let crop_height = input.read_u16::<LittleEndian>()?;
|
||||
|
||||
let bounds_width = input.read_u16::<LittleEndian>()?;
|
||||
let bounds_height = input.read_u16::<LittleEndian>()?;
|
||||
|
||||
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::<LittleEndian>()?);
|
||||
offset_height = Some(input.read_u16::<LittleEndian>()?);
|
||||
|
||||
unknown_2 = Some(input.read_u32::<LittleEndian>()?);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
unknown_1,
|
||||
|
||||
crop_width,
|
||||
crop_height,
|
||||
|
||||
bounds_width,
|
||||
bounds_height,
|
||||
|
||||
offset_width,
|
||||
offset_height,
|
||||
|
||||
unknown_2,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn as_bytes(&self) -> Result<Vec<u8>, io::Error> {
|
||||
let mut buf = vec![];
|
||||
|
||||
buf.write_all(&self.unknown_1)?;
|
||||
buf.write_u16::<LittleEndian>(self.crop_width)?;
|
||||
buf.write_u16::<LittleEndian>(self.crop_height)?;
|
||||
buf.write_u16::<LittleEndian>(self.bounds_width)?;
|
||||
buf.write_u16::<LittleEndian>(self.bounds_height)?;
|
||||
|
||||
if self.offset_width.is_some() {
|
||||
buf.write_u16::<LittleEndian>(self.offset_width.unwrap())?;
|
||||
buf.write_u16::<LittleEndian>(self.offset_height.unwrap())?;
|
||||
buf.write_u32::<LittleEndian>(self.unknown_2.unwrap())?;
|
||||
}
|
||||
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_palette<T: Seek + ReadBytesExt + Read>(
|
||||
input: &mut T,
|
||||
num_colors: usize,
|
||||
|
|
|
@ -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<ExtendedHeader>,
|
||||
palette: Option<Vec<[u8; 4]>>,
|
||||
bitmap: Vec<u8>,
|
||||
}
|
||||
|
@ -45,6 +46,10 @@ impl DynamicCz {
|
|||
pub fn decode<T: Seek + ReadBytesExt + Read>(input: &mut T) -> Result<Self, CzError> {
|
||||
// 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,
|
||||
})
|
||||
|
|
|
@ -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<u16>,
|
||||
|
||||
/// Offset height
|
||||
pub offset_height: Option<u16>,
|
||||
|
||||
unknown_2: Option<[u8; 4]>,
|
||||
}
|
||||
|
||||
impl Cz0Header {
|
||||
fn new<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Self, CzError>
|
||||
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::<LittleEndian>()?;
|
||||
let crop_height = bytes.read_u16::<LittleEndian>()?;
|
||||
|
||||
let bounds_width = bytes.read_u16::<LittleEndian>()?;
|
||||
let bounds_height = bytes.read_u16::<LittleEndian>()?;
|
||||
|
||||
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::<LittleEndian>()?);
|
||||
offset_height = Some(bytes.read_u16::<LittleEndian>()?);
|
||||
|
||||
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<Vec<u8>, io::Error> {
|
||||
let mut buf = vec![];
|
||||
|
||||
buf.write_all(&self.common.to_bytes()?)?;
|
||||
buf.write_all(&self.unknown_1)?;
|
||||
buf.write_u16::<LittleEndian>(self.crop_width)?;
|
||||
buf.write_u16::<LittleEndian>(self.crop_height)?;
|
||||
buf.write_u16::<LittleEndian>(self.bounds_width)?;
|
||||
buf.write_u16::<LittleEndian>(self.bounds_height)?;
|
||||
|
||||
if self.common.length() > 28 {
|
||||
buf.write_u16::<LittleEndian>(self.offset_width.unwrap())?;
|
||||
buf.write_u16::<LittleEndian>(self.offset_height.unwrap())?;
|
||||
buf.write_all(&self.unknown_2.unwrap())?;
|
||||
}
|
||||
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Cz0Image {
|
||||
header: Cz0Header,
|
||||
bitmap: Vec<u8>,
|
||||
}
|
||||
use crate::common::CzError;
|
||||
|
||||
pub fn decode<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Vec<u8>, CzError> {
|
||||
// Get the rest of the file, which is the bitmap
|
||||
|
|
Loading…
Reference in a new issue