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>(
|
pub fn get_palette<T: Seek + ReadBytesExt + Read>(
|
||||||
input: &mut T,
|
input: &mut T,
|
||||||
num_colors: usize,
|
num_colors: usize,
|
||||||
|
|
|
@ -5,12 +5,13 @@ use std::{
|
||||||
use byteorder::ReadBytesExt;
|
use byteorder::ReadBytesExt;
|
||||||
|
|
||||||
use crate::{
|
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},
|
formats::{cz0, cz1, cz2, cz3, cz4},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct DynamicCz {
|
pub struct DynamicCz {
|
||||||
header_common: CommonHeader,
|
header_common: CommonHeader,
|
||||||
|
header_extended: Option<ExtendedHeader>,
|
||||||
palette: Option<Vec<[u8; 4]>>,
|
palette: Option<Vec<[u8; 4]>>,
|
||||||
bitmap: Vec<u8>,
|
bitmap: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
@ -45,6 +46,10 @@ impl DynamicCz {
|
||||||
pub fn decode<T: Seek + ReadBytesExt + Read>(input: &mut T) -> Result<Self, CzError> {
|
pub fn decode<T: Seek + ReadBytesExt + Read>(input: &mut T) -> Result<Self, CzError> {
|
||||||
// Get the header common to all CZ images
|
// Get the header common to all CZ images
|
||||||
let header_common = CommonHeader::new(input)?;
|
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))?;
|
input.seek(SeekFrom::Start(header_common.length() as u64))?;
|
||||||
|
|
||||||
// Get the color palette if the bit depth is 8 or less
|
// Get the color palette if the bit depth is 8 or less
|
||||||
|
@ -77,6 +82,7 @@ impl DynamicCz {
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
header_common,
|
header_common,
|
||||||
|
header_extended,
|
||||||
palette,
|
palette,
|
||||||
bitmap,
|
bitmap,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,113 +1,7 @@
|
||||||
use std::io::{self, Read, Seek, Write};
|
use std::io::{Read, Seek};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::ReadBytesExt;
|
||||||
|
|
||||||
use crate::common::{CommonHeader, CzError, CzHeader, CzVersion};
|
use crate::common::CzError;
|
||||||
|
|
||||||
#[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>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decode<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Vec<u8>, 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
|
// Get the rest of the file, which is the bitmap
|
||||||
|
|
Loading…
Reference in a new issue