mirror of
https://github.com/G2-Games/lbee-utils.git
synced 2025-06-23 07:02:53 -05:00
Compare commits
3 commits
a9ed206b72
...
77365cf089
Author | SHA1 | Date | |
---|---|---|---|
77365cf089 | |||
a4bb11aeb4 | |||
9f7e39a8a3 |
6 changed files with 11 additions and 32 deletions
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "cz"
|
name = "cz"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
description="""
|
description="""
|
||||||
An encoder/decoder for CZ# image files used in the LUCA System engine by
|
An encoder/decoder for CZ# image files used in the LUCA System engine by
|
||||||
Prototype Ltd.
|
Prototype Ltd.
|
||||||
|
|
|
@ -312,9 +312,7 @@ fn compress_lzw(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u16>, Ve
|
||||||
(count, compressed, last_element)
|
(count, compressed, last_element)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compress2(data: &[u8], size: usize) -> (Vec<u8>, CompressionInfo) {
|
pub fn compress2(data: &[u8]) -> (Vec<u8>, CompressionInfo) {
|
||||||
let size = if size == 0 { 0x87BDF } else { size };
|
|
||||||
|
|
||||||
let mut part_data;
|
let mut part_data;
|
||||||
|
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
|
@ -328,7 +326,7 @@ pub fn compress2(data: &[u8], size: usize) -> (Vec<u8>, CompressionInfo) {
|
||||||
};
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
(count, part_data, last) = compress_lzw2(&data[offset..], size, last);
|
(count, part_data, last) = compress_lzw2(&data[offset..], last);
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -346,20 +344,13 @@ pub fn compress2(data: &[u8], size: usize) -> (Vec<u8>, CompressionInfo) {
|
||||||
|
|
||||||
if output_info.chunk_count == 0 {
|
if output_info.chunk_count == 0 {
|
||||||
panic!("No chunks compressed!")
|
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();
|
output_info.total_size_compressed = output_buf.len();
|
||||||
(output_buf, output_info)
|
(output_buf, output_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compress_lzw2(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u8>, Vec<u8>) {
|
fn compress_lzw2(data: &[u8], last: Vec<u8>) -> (usize, Vec<u8>, Vec<u8>) {
|
||||||
let mut data = data.to_vec();
|
|
||||||
if !data.is_empty() {
|
|
||||||
data[0] = 0;
|
|
||||||
}
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
let mut dictionary = HashMap::new();
|
let mut dictionary = HashMap::new();
|
||||||
for i in 0..=255 {
|
for i in 0..=255 {
|
||||||
|
@ -372,7 +363,7 @@ fn compress_lzw2(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u8>, Ve
|
||||||
element = last
|
element = last
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut bit_io = BitIo::new(vec![0u8; size + 2]);
|
let mut bit_io = BitIo::new(vec![0u8; 0xF0000]);
|
||||||
let write_bit = |bit_io: &mut BitIo, code: u64| {
|
let write_bit = |bit_io: &mut BitIo, code: u64| {
|
||||||
if code > 0x7FFF {
|
if code > 0x7FFF {
|
||||||
bit_io.write_bit(1, 1);
|
bit_io.write_bit(1, 1);
|
||||||
|
@ -398,9 +389,9 @@ fn compress_lzw2(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u8>, Ve
|
||||||
|
|
||||||
count += 1;
|
count += 1;
|
||||||
|
|
||||||
if size > 0 && bit_io.byte_size() >= size {
|
if dictionary_count >= 0x3FFFE {
|
||||||
count -= 1;
|
count -= 1;
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,7 +403,7 @@ fn compress_lzw2(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u8>, Ve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (count, bit_io.bytes(), Vec::new());
|
return (count, bit_io.bytes(), Vec::new());
|
||||||
} else if bit_io.byte_size() < size {
|
} else if bit_io.byte_size() < 0x87BDF {
|
||||||
if !last_element.is_empty() {
|
if !last_element.is_empty() {
|
||||||
write_bit(&mut bit_io, *dictionary.get(&last_element).unwrap());
|
write_bit(&mut bit_io, *dictionary.get(&last_element).unwrap());
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::compression::{compress2, decompress2, get_chunk_info};
|
||||||
|
|
||||||
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 information about the compressed chunks
|
// Get information about the compressed chunks
|
||||||
let block_info = get_chunk_info(bytes).unwrap();
|
let block_info = get_chunk_info(bytes)?;
|
||||||
bytes.seek(SeekFrom::Start(block_info.length as u64))?;
|
bytes.seek(SeekFrom::Start(block_info.length as u64))?;
|
||||||
|
|
||||||
// Get the bitmap
|
// Get the bitmap
|
||||||
|
@ -16,7 +16,7 @@ pub fn decode<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Vec<u8>, C
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encode<T: WriteBytesExt + Write>(output: &mut T, bitmap: &[u8]) -> Result<(), CzError> {
|
pub fn encode<T: WriteBytesExt + Write>(output: &mut T, bitmap: &[u8]) -> Result<(), CzError> {
|
||||||
let (compressed_data, compressed_info) = compress2(bitmap, 0x87BDF);
|
let (compressed_data, compressed_info) = compress2(&bitmap);
|
||||||
|
|
||||||
compressed_info.write_into(output)?;
|
compressed_info.write_into(output)?;
|
||||||
|
|
||||||
|
|
|
@ -23,13 +23,9 @@ pub fn encode<T: WriteBytesExt + Write>(
|
||||||
bitmap: &[u8],
|
bitmap: &[u8],
|
||||||
header: &CommonHeader,
|
header: &CommonHeader,
|
||||||
) -> Result<(), CzError> {
|
) -> Result<(), CzError> {
|
||||||
let timer = std::time::Instant::now();
|
|
||||||
let bitmap = diff_line(header, bitmap);
|
let bitmap = diff_line(header, bitmap);
|
||||||
println!("diff_line took {:?}", timer.elapsed());
|
|
||||||
|
|
||||||
let timer = std::time::Instant::now();
|
|
||||||
let (compressed_data, compressed_info) = compress(&bitmap, 0xFEFD);
|
let (compressed_data, compressed_info) = compress(&bitmap, 0xFEFD);
|
||||||
println!("Compression took {:?}", timer.elapsed());
|
|
||||||
|
|
||||||
compressed_info.write_into(output)?;
|
compressed_info.write_into(output)?;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "utils"
|
name = "utils"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
|
|
|
@ -219,14 +219,6 @@ fn main() {
|
||||||
Error::raw(ErrorKind::ValueValidation, "Replacement must be a file\n").exit()
|
Error::raw(ErrorKind::ValueValidation, "Replacement must be a file\n").exit()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !output.is_file() {
|
|
||||||
Error::raw(
|
|
||||||
ErrorKind::ValueValidation,
|
|
||||||
"Replacement output must be a file\n",
|
|
||||||
)
|
|
||||||
.exit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace the input file with the new image
|
// Replace the input file with the new image
|
||||||
replace_cz(&input, &output, &replacement, version, depth).unwrap();
|
replace_cz(&input, &output, &replacement, version, depth).unwrap();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue