Added docmentation and fixes

This commit is contained in:
G2-Games 2024-05-07 16:27:18 -05:00
parent 8945b80065
commit aa03498fd0
10 changed files with 50 additions and 51 deletions

View file

@ -11,3 +11,4 @@ A encoder/decoder for CZ# image files used in
byteorder = "1.5.0"
thiserror = "1.0.59"
png = "0.17.13"
image = "0.25.1"

View file

@ -19,7 +19,7 @@ pub enum CzError {
#[error("File is not a CZ image")]
NotCzFile,
#[error("Failed to read/write input/output")]
#[error("Failed to read/write input/output: {}", 0)]
IoError(#[from] io::Error),
#[error("Problem while decoding file")]
@ -166,7 +166,7 @@ pub trait CzImage {
fn into_bitmap(self) -> Vec<u8>;
/// Set the bitmap the image contains
fn set_bitmap(&mut self, bitmap: &[u8], header: &Self::Header);
fn set_bitmap(&mut self, bitmap: &[u8], width: u16, height: u16);
}
pub fn parse_colormap<T: Seek + ReadBytesExt + Read>(

View file

@ -7,17 +7,29 @@ use std::{
use crate::binio::BitIO;
use crate::common::{CzError, CzHeader};
/// The size of compressed data in each chunk
#[derive(Debug, Clone, Copy)]
pub struct ChunkInfo {
/// The size of the data when compressed
pub size_compressed: usize,
/// The size of the original uncompressed data
pub size_raw: usize,
}
/// A CZ# file's information about compression chunks
#[derive(Debug, Clone)]
pub struct CompressionInfo {
/// Number of compression chunks
pub chunk_count: usize,
/// Total size of the data when compressed
pub total_size_compressed: usize,
/// Total size of the original uncompressed data
pub total_size_raw: usize,
/// The compression chunk information
pub chunks: Vec<ChunkInfo>,
/// Length of the compression chunk info
@ -25,6 +37,9 @@ pub struct CompressionInfo {
}
/// Get info about the compression chunks
///
/// These are defined by a length value, followed by the number of data chunks
/// that length value says split into compressed and original size u32 values
pub fn parse_chunk_info<T: Seek + ReadBytesExt + Read>(
bytes: &mut T,
) -> Result<CompressionInfo, CzError> {

View file

@ -33,7 +33,7 @@ impl DynamicCz {
encoder.set_depth(png::BitDepth::Eight);
let mut writer = encoder.write_header()?;
writer.write_image_data(&self.bitmap())?; // Save
writer.write_image_data(&self.bitmap())?;
Ok(())
}
@ -59,7 +59,13 @@ impl CzImage for DynamicCz {
}
fn save_as_cz<T: Into<std::path::PathBuf>>(&self, path: T) -> Result<(), CzError> {
todo!()
match self {
DynamicCz::CZ0(img) => img.save_as_cz(path),
DynamicCz::CZ1(_) => unimplemented!(),
DynamicCz::CZ2(_) => unimplemented!(),
DynamicCz::CZ3(_) => unimplemented!(),
DynamicCz::CZ4(_) => unimplemented!(),
}
}
fn header(&self) -> &Self::Header {
@ -96,7 +102,7 @@ impl CzImage for DynamicCz {
}
}
fn set_bitmap(&mut self, bitmap: &[u8], header: &Self::Header) {
todo!()
fn set_bitmap(&mut self, bitmap: &[u8], width: u16, height: u16) {
unimplemented!()
}
}

View file

@ -189,10 +189,11 @@ impl CzImage for Cz0Image {
self.bitmap
}
fn set_bitmap(&mut self, bitmap: &[u8], header: &Self::Header) {
fn set_bitmap(&mut self, bitmap: &[u8], width: u16, height: u16) {
self.bitmap = bitmap.to_vec();
self.header = *header;
self.header.common.width = width;
self.header.common.height = height;
}
}

View file

@ -21,13 +21,19 @@ impl CzImage for Cz1Image {
fn decode<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Self, CzError> {
// Get the header from the input
let header = CommonHeader::new(bytes).unwrap();
let mut header = CommonHeader::new(bytes).unwrap();
bytes.seek(SeekFrom::Start(header.length() as u64))?;
if header.version() != 1 {
return Err(CzError::VersionMismatch(1, header.version()));
}
// Lock the color depth to 8 if it's over 32
// This is obviously wrong, but why is it wrong?
if header.depth() > 32 {
header.depth = 8
}
// The color palette, gotten for 8 and 4 BPP images
let mut palette = None;
if header.depth() == 8 || header.depth() == 4 {
@ -83,7 +89,7 @@ impl CzImage for Cz1Image {
Ok(())
}
fn set_bitmap(&mut self, bitmap: &[u8], header: &Self::Header) {
fn set_bitmap(&mut self, bitmap: &[u8], width: u16, height: u16) {
todo!()
}
}

View file

@ -139,7 +139,7 @@ impl CzImage for Cz2Image {
Ok(())
}
fn set_bitmap(&mut self, bitmap: &[u8], header: &Self::Header) {
fn set_bitmap(&mut self, bitmap: &[u8], width: u16, height: u16) {
todo!()
}
}

View file

@ -148,7 +148,7 @@ impl CzImage for Cz3Image {
todo!()
}
fn set_bitmap(&mut self, bitmap: &[u8], header: &Self::Header) {
fn set_bitmap(&mut self, bitmap: &[u8], width: u16, height: u16) {
todo!()
}
}

View file

@ -76,7 +76,11 @@ impl CzImage for Cz4Image {
let block_info = parse_chunk_info(bytes)?;
bytes.seek(SeekFrom::Start(block_info.length as u64))?;
let pcount = header.width() as usize * header.height() as usize;
let bitmap = decompress(bytes, &block_info)?;
let data2 = bitmap[pcount * 3..].to_vec();
let bitmap = line_diff_cz4(&header, &bitmap);
let bitmap = line_diff_cz4(&header, &bitmap);
@ -103,7 +107,7 @@ impl CzImage for Cz4Image {
todo!()
}
fn set_bitmap(&mut self, bitmap: &[u8], header: &Self::Header) {
fn set_bitmap(&mut self, bitmap: &[u8], width: u16, height: u16) {
todo!()
}
}

View file

@ -1,43 +1,9 @@
use cz::{dynamic::DynamicCz, CzImage};
use cz::{dynamic::DynamicCz, Cz0Image, CzImage};
use std::fs;
use walkdir::WalkDir;
fn main() {
if let Err(err) = fs::DirBuilder::new().create("test/") {
println!("{}", err);
}
let mut file = fs::File::open("TEXTBOX.CZ3").unwrap();
let img = DynamicCz::decode(&mut file).unwrap();
let mut success = 0;
let mut failure = 0;
for entry in WalkDir::new("../../test_files") {
let entry = entry.unwrap();
if entry.path().is_dir() {
continue;
}
let mut input = match fs::File::open(entry.path()) {
Ok(file) => file,
Err(_) => continue,
};
let img_file = match DynamicCz::decode(&mut input) {
Ok(file) => file,
Err(err) => {
println!(
"{}: {}",
entry.path().file_name().unwrap().to_string_lossy(),
err,
);
failure += 1;
continue;
},
};
success += 1;
img_file.save_as_png(
&format!("test/z-{}.png", entry.path().file_stem().unwrap().to_string_lossy())
).unwrap();
}
img.save_as_png("test.png").unwrap();
}