Added CZ3 encoding

This commit is contained in:
G2-Games 2024-05-09 21:19:00 -05:00
parent c363692efd
commit 9da8d68683
3 changed files with 57 additions and 11 deletions

View file

@ -289,6 +289,38 @@ pub fn line_diff<T: CzHeader>(header: &T, data: &[u8]) -> Vec<u8> {
output_buf
}
pub fn diff_line<T: CzHeader>(header: &T, input: &[u8]) -> Vec<u8> {
let width = header.width() as u32;
let height = header.height() as u32;
let mut data = Vec::with_capacity(input.len());
let block_height =
(f32::ceil(height as f32 / 3.0) as u16) as usize;
let pixel_byte_count = header.depth() >> 3;
let line_byte_count = (width * pixel_byte_count as u32) as usize;
let mut curr_line;
let mut prev_line: Vec<u8> = Vec::with_capacity(line_byte_count);
let mut i = 0;
for y in 0..height {
curr_line = input[i..i + line_byte_count].to_vec();
if y % block_height as u32 != 0 {
for x in 0..line_byte_count {
curr_line[x] -= prev_line[x];
prev_line[x] += curr_line[x];
}
} else {
prev_line.clone_from(&curr_line);
}
data.extend_from_slice(&curr_line);
i += line_byte_count;
}
data
}
pub fn compress(
data: &[u8],

View file

@ -63,9 +63,6 @@ impl DynamicCz {
CzVersion::CZ5 => unimplemented!(),
};
let mut file = File::create("raw1").unwrap();
file.write_all(&bitmap).unwrap();
let image_size = header_common.width() as usize * header_common.height() as usize;
if bitmap.len() != image_size * (header_common.depth() >> 3) as usize {
// If the bitmap is smaller or larger than the image size, it is likely wrong
@ -109,7 +106,7 @@ impl DynamicCz {
CzVersion::CZ0 => cz0::encode(&mut out_file, &output_bitmap)?,
CzVersion::CZ1 => cz1::encode(&mut out_file, &output_bitmap)?,
CzVersion::CZ2 => todo!(),
CzVersion::CZ3 => todo!(),
CzVersion::CZ3 => cz3::encode(&mut out_file, &output_bitmap, &self.header_common)?,
CzVersion::CZ4 => todo!(),
CzVersion::CZ5 => todo!(),
}

View file

@ -1,12 +1,13 @@
use std::io::{Read, Seek, SeekFrom};
use byteorder::ReadBytesExt;
use std::io::{Read, Write, Seek, SeekFrom};
use byteorder::{ReadBytesExt, WriteBytesExt};
use crate::common::{CommonHeader, CzError};
use crate::compression::{decompress, line_diff, get_chunk_info};
use crate::common::{CommonHeader, CzError, CzHeader};
use crate::compression::{compress, decompress, diff_line, get_chunk_info, line_diff};
pub fn decode<T: Seek + ReadBytesExt + Read>(bytes: &mut T, header: &CommonHeader)
-> Result<Vec<u8>, CzError>
{
pub fn decode<T: Seek + ReadBytesExt + Read>(
bytes: &mut T,
header: &CommonHeader
) -> Result<Vec<u8>, CzError> {
let block_info = get_chunk_info(bytes)?;
bytes.seek(SeekFrom::Start(block_info.length as u64))?;
@ -15,3 +16,19 @@ pub fn decode<T: Seek + ReadBytesExt + Read>(bytes: &mut T, header: &CommonHeade
Ok(bitmap)
}
pub fn encode<T: WriteBytesExt + Write, H: CzHeader>(
output: &mut T,
bitmap: &[u8],
header: &H,
) -> Result<(), CzError> {
let bitmap = diff_line(header, bitmap);
let (compressed_data, compressed_info) = compress(&bitmap, 65277);
compressed_info.write_into(output)?;
output.write_all(&compressed_data)?;
Ok(())
}