mirror of
https://github.com/G2-Games/lbee-utils.git
synced 2025-04-19 07:12:55 -05:00
Fixed CZ1/CZ3 compression
This commit is contained in:
parent
9da8d68683
commit
5b95687393
6 changed files with 122 additions and 14 deletions
|
@ -58,7 +58,7 @@ impl TryFrom<u8> for CzVersion {
|
|||
}
|
||||
|
||||
pub trait CzHeader {
|
||||
fn new<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Self, CzError>
|
||||
fn from_bytes<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Self, CzError>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
|
@ -122,8 +122,29 @@ pub struct CommonHeader {
|
|||
unknown: u8,
|
||||
}
|
||||
|
||||
impl CommonHeader {
|
||||
pub fn new(
|
||||
version: CzVersion,
|
||||
width: u16,
|
||||
height: u16,
|
||||
) -> Self {
|
||||
Self {
|
||||
version,
|
||||
length: 15,
|
||||
width,
|
||||
height,
|
||||
depth: 32,
|
||||
unknown: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_length(&mut self, length: u32) {
|
||||
self.length = length
|
||||
}
|
||||
}
|
||||
|
||||
impl CzHeader for CommonHeader {
|
||||
fn new<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Self, CzError>
|
||||
fn from_bytes<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Self, CzError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
|
@ -243,7 +264,37 @@ pub struct ExtendedHeader {
|
|||
}
|
||||
|
||||
impl ExtendedHeader {
|
||||
pub fn new<T: Seek + ReadBytesExt + Read>(
|
||||
pub fn new(
|
||||
crop_width: u16,
|
||||
crop_height: u16,
|
||||
bounds_width: u16,
|
||||
bounds_height: u16,
|
||||
) -> Self {
|
||||
ExtendedHeader {
|
||||
unknown_1: [0u8; 5],
|
||||
crop_width,
|
||||
crop_height,
|
||||
bounds_width,
|
||||
bounds_height,
|
||||
offset_width: None,
|
||||
offset_height: None,
|
||||
unknown_2: None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_offset(
|
||||
mut self,
|
||||
offset_width: u16,
|
||||
offset_height: u16
|
||||
) -> Self {
|
||||
self.offset_width = Some(offset_width);
|
||||
self.offset_height = Some(offset_height);
|
||||
self.unknown_2 = Some(0);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn from_bytes<T: Seek + ReadBytesExt + Read>(
|
||||
input: &mut T,
|
||||
common_header: &CommonHeader
|
||||
) -> Result<Self, CzError> {
|
||||
|
|
|
@ -334,7 +334,7 @@ pub fn compress(
|
|||
let mut part_data;
|
||||
|
||||
let mut offset = 0;
|
||||
let mut count = 0;
|
||||
let mut count;
|
||||
let mut last = Vec::new();
|
||||
|
||||
let mut output_buf: Vec<u8> = vec![];
|
||||
|
@ -362,6 +362,13 @@ pub fn compress(
|
|||
output_info.chunk_count += 1;
|
||||
}
|
||||
|
||||
if output_info.chunk_count == 0 {
|
||||
panic!("No chunks compressed!")
|
||||
} else if output_info.chunk_count != 1 {
|
||||
output_info.chunks[0].size_raw -= 1;
|
||||
output_info.chunks[output_info.chunk_count - 1].size_raw += 1;
|
||||
}
|
||||
|
||||
output_info.total_size_compressed = output_buf.len() / 2;
|
||||
|
||||
(output_buf, output_info)
|
||||
|
|
|
@ -33,15 +33,53 @@ impl DynamicCz {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn from_raw(
|
||||
version: CzVersion,
|
||||
width: u16,
|
||||
height: u16,
|
||||
bitmap: Vec<u8>,
|
||||
) -> Self {
|
||||
let header_common = CommonHeader::new(
|
||||
version,
|
||||
width,
|
||||
height
|
||||
);
|
||||
|
||||
Self {
|
||||
header_common,
|
||||
header_extended: None,
|
||||
palette: None,
|
||||
bitmap,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_header(mut self, header: CommonHeader) -> Self {
|
||||
self.header_common = header;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_extended_header(mut self, ext_header: ExtendedHeader) -> Self {
|
||||
if ext_header.offset_width.is_none() {
|
||||
self.header_common.set_length(28)
|
||||
} else {
|
||||
self.header_common.set_length(36)
|
||||
}
|
||||
|
||||
self.header_extended = Some(ext_header);
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
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 header_common = CommonHeader::from_bytes(input)?;
|
||||
let mut header_extended = None;
|
||||
if header_common.length() > 15 && header_common.version() != CzVersion::CZ2 {
|
||||
header_extended = Some(ExtendedHeader::new(input, &header_common)?);
|
||||
header_extended = Some(ExtendedHeader::from_bytes(input, &header_common)?);
|
||||
}
|
||||
input.seek(SeekFrom::Start(header_common.length() as u64))?;
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ pub fn encode<T: WriteBytesExt + Write>(
|
|||
output: &mut T,
|
||||
bitmap: &[u8]
|
||||
) -> Result<(), CzError> {
|
||||
let (compressed_data, compressed_info) = compress(bitmap, 65277);
|
||||
let (compressed_data, compressed_info) = compress(bitmap, 0xFEFD);
|
||||
|
||||
dbg!(&compressed_info);
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ pub fn encode<T: WriteBytesExt + Write, H: CzHeader>(
|
|||
) -> Result<(), CzError> {
|
||||
let bitmap = diff_line(header, bitmap);
|
||||
|
||||
let (compressed_data, compressed_info) = compress(&bitmap, 65277);
|
||||
let (compressed_data, compressed_info) = compress(&bitmap, 0xFEFD);
|
||||
|
||||
compressed_info.write_into(output)?;
|
||||
|
||||
|
|
|
@ -1,11 +1,23 @@
|
|||
use cz::dynamic::DynamicCz;
|
||||
use cz::{common::{CzVersion, ExtendedHeader}, dynamic::DynamicCz};
|
||||
|
||||
fn main() {
|
||||
let img = DynamicCz::open("font72.cz1").unwrap();
|
||||
let mio = image::open("mio_inverted.png").unwrap();
|
||||
let mio = mio.to_rgba8();
|
||||
|
||||
img.save_as_cz("test.cz1").unwrap();
|
||||
img.save_as_png("test1.png").unwrap();
|
||||
let cz_mio =
|
||||
DynamicCz::from_raw(
|
||||
CzVersion::CZ3,
|
||||
mio.width() as u16,
|
||||
mio.height() as u16,
|
||||
mio.into_raw()
|
||||
)
|
||||
.with_extended_header(
|
||||
ExtendedHeader::new(1280, 960, 1280, 960)
|
||||
);
|
||||
|
||||
let img2 = DynamicCz::open("test.cz1").unwrap();
|
||||
img2.save_as_png("test2.png").unwrap();
|
||||
cz_mio.save_as_cz("test1.cz3").unwrap();
|
||||
|
||||
let img = DynamicCz::open("test1.cz3").unwrap();
|
||||
|
||||
img.save_as_png("test.png").unwrap();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue