Cleaned up code, fixed clippy warnings

This commit is contained in:
G2-Games 2024-05-22 02:24:07 -05:00
parent c4c7e8b9da
commit c9126a688d
7 changed files with 64 additions and 94 deletions

View file

@ -1,7 +1,7 @@
[workspace] [workspace]
resolver = "2" resolver = "2"
members = [ members = [
"cz", "font", "cz",
"utils", "utils",
] ]

View file

@ -62,48 +62,22 @@ impl TryFrom<u8> for CzVersion {
} }
} }
pub trait CzHeader { impl TryFrom<char> for CzVersion {
fn from_bytes<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Self, CzError> type Error = &'static str;
where
Self: Sized;
/// The [CommonHeader] header from the image fn try_from(value: char) -> Result<Self, Self::Error> {
fn common(&self) -> &CommonHeader; let value = match value {
'0' => Self::CZ0,
'1' => Self::CZ1,
'2' => Self::CZ2,
'3' => Self::CZ3,
'4' => Self::CZ4,
'5' => Self::CZ5,
_ => return Err("Value is not a valid CZ version"),
};
/// Turn the header into bytes equivalent to the original header from the file Ok(value)
fn write_into<T: Seek + WriteBytesExt + Write>( }
&self,
output: &mut T,
) -> Result<usize, io::Error>;
/// The version of the image
fn version(&self) -> CzVersion;
/// Set the version of the image
fn set_version(&mut self, version: CzVersion);
/// The length of the header in bytes
fn length(&self) -> usize;
/// The width of the image
fn width(&self) -> u16;
/// Set the width of the image
fn set_width(&mut self, width: u16);
/// The height of the image
fn height(&self) -> u16;
/// Set the height of the image
fn set_height(&mut self, height: u16);
/// The bit depth of the image (BPP)
fn depth(&self) -> u16;
fn set_depth(&mut self, depth: u16);
/// An unknown value?
fn color_block(&self) -> u8;
} }
/// The common first part of a header of a CZ# file /// The common first part of a header of a CZ# file
@ -145,8 +119,8 @@ impl CommonHeader {
} }
} }
impl CzHeader for CommonHeader { impl CommonHeader {
fn from_bytes<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Self, CzError> pub fn from_bytes<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Self, CzError>
where where
Self: Sized, Self: Sized,
{ {
@ -181,51 +155,51 @@ impl CzHeader for CommonHeader {
Ok(header) Ok(header)
} }
fn common(&self) -> &CommonHeader { pub fn common(&self) -> &CommonHeader {
self self
} }
fn version(&self) -> CzVersion { pub fn version(&self) -> CzVersion {
self.version self.version
} }
fn set_version(&mut self, version: CzVersion) { pub fn set_version(&mut self, version: CzVersion) {
self.version = version self.version = version
} }
fn length(&self) -> usize { pub fn length(&self) -> usize {
self.length as usize self.length as usize
} }
fn width(&self) -> u16 { pub fn width(&self) -> u16 {
self.width self.width
} }
fn set_width(&mut self, width: u16) { pub fn set_width(&mut self, width: u16) {
self.width = width self.width = width
} }
fn height(&self) -> u16 { pub fn height(&self) -> u16 {
self.height self.height
} }
fn set_height(&mut self, height: u16) { pub fn set_height(&mut self, height: u16) {
self.height = height self.height = height
} }
fn depth(&self) -> u16 { pub fn depth(&self) -> u16 {
self.depth self.depth
} }
fn set_depth(&mut self, depth: u16) { pub fn set_depth(&mut self, depth: u16) {
self.depth = depth self.depth = depth
} }
fn color_block(&self) -> u8 { pub fn color_block(&self) -> u8 {
self.unknown self.unknown
} }
fn write_into<T: Seek + WriteBytesExt + Write>( pub fn write_into<T: Seek + WriteBytesExt + Write>(
&self, &self,
output: &mut T, output: &mut T,
) -> Result<usize, io::Error> { ) -> Result<usize, io::Error> {

View file

@ -256,7 +256,7 @@ pub fn compress(
offset += count; offset += count;
for d in &part_data { for d in &part_data {
output_buf.write(&d.to_le_bytes()).unwrap(); output_buf.write_all(&d.to_le_bytes()).unwrap();
} }
output_info.chunks.push(ChunkInfo { output_info.chunks.push(ChunkInfo {
@ -288,7 +288,7 @@ fn compress_lzw(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u16>, Ve
let mut dictionary_count = (dictionary.len() + 1) as u16; let mut dictionary_count = (dictionary.len() + 1) as u16;
let mut element = Vec::new(); let mut element = Vec::new();
if last.len() != 0 { if last.is_empty() {
element = last element = last
} }
@ -297,7 +297,7 @@ fn compress_lzw(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u16>, Ve
let mut entry = element.clone(); let mut entry = element.clone();
entry.push(*c); entry.push(*c);
if dictionary.get(&entry).is_some() { if dictionary.contains_key(&entry){
element = entry element = entry
} else { } else {
compressed.push(*dictionary.get(&element).unwrap()); compressed.push(*dictionary.get(&element).unwrap());
@ -314,15 +314,15 @@ fn compress_lzw(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u16>, Ve
} }
let last_element = element; let last_element = element;
if compressed.len() == 0 { if compressed.is_empty() {
if last_element.len() != 0 { if last_element.is_empty() {
for c in last_element { for c in last_element {
compressed.push(*dictionary.get(&vec![c]).unwrap()); compressed.push(*dictionary.get(&vec![c]).unwrap());
} }
} }
return (count, compressed, Vec::new()) return (count, compressed, Vec::new())
} else if compressed.len() < size { } else if compressed.len() < size {
if last_element.len() != 0 { if last_element.is_empty() {
compressed.push(*dictionary.get(&last_element).unwrap()); compressed.push(*dictionary.get(&last_element).unwrap());
} }
return (count, compressed, Vec::new()) return (count, compressed, Vec::new())

View file

@ -9,7 +9,7 @@ use std::{
use crate::{ use crate::{
common::{ common::{
apply_palette, get_palette, indexed_gen_palette, apply_palette, get_palette, indexed_gen_palette,
rgba_to_indexed, CommonHeader, CzError, CzHeader, rgba_to_indexed, CommonHeader, CzError,
CzVersion, ExtendedHeader CzVersion, ExtendedHeader
}, },
formats::{cz0, cz1, cz2, cz3, cz4}, formats::{cz0, cz1, cz2, cz3, cz4},
@ -121,19 +121,19 @@ impl DynamicCz {
let output_bitmap; let output_bitmap;
match self.header_common.depth() { match self.header_common.depth() {
4 => { 4 => {
eprintln!("Files with a bit depth of 4 are not yet supported");
todo!() todo!()
} }
8 => { 8 => {
match &self.palette { if let Some(pal) = &self.palette {
Some(pal) if self.header_common.depth() <= 8 => { // Use the existing palette to palette the image
output_bitmap = rgba_to_indexed(self.bitmap(), pal)?; output_bitmap = rgba_to_indexed(self.bitmap(), pal)?;
for rgba in pal { for rgba in pal {
out_file.write_all(&rgba.0)?; out_file.write_all(&rgba.0)?;
} }
}, } else {
// Generate a palette if there is none // Generate a palette and corresponding indexed bitmap if there is none
None if self.header_common.depth() <= 8 => {
let result = indexed_gen_palette( let result = indexed_gen_palette(
self.bitmap(), self.bitmap(),
self.header() self.header()
@ -143,12 +143,10 @@ impl DynamicCz {
let palette = result.1; let palette = result.1;
for rgba in palette { for rgba in palette {
let mut rgba_clone = rgba.0.clone(); let mut rgba_clone = rgba.0;
rgba_clone[0..3].reverse(); rgba_clone[0..3].reverse();
out_file.write_all(&rgba_clone)?; out_file.write_all(&rgba_clone)?;
} }
},
_ => output_bitmap = self.bitmap().clone(),
} }
}, },
24 => { 24 => {

View file

@ -1,7 +1,7 @@
use byteorder::{ReadBytesExt, WriteBytesExt}; use byteorder::{ReadBytesExt, WriteBytesExt};
use std::io::{Read, Seek, SeekFrom, Write}; use std::io::{Read, Seek, SeekFrom, Write};
use crate::common::{CommonHeader, CzError, CzHeader}; use crate::common::{CommonHeader, CzError};
use crate::compression::{compress, decompress, get_chunk_info}; use crate::compression::{compress, decompress, get_chunk_info};
pub fn decode<T: Seek + ReadBytesExt + Read>( pub fn decode<T: Seek + ReadBytesExt + Read>(
@ -17,10 +17,10 @@ pub fn decode<T: Seek + ReadBytesExt + Read>(
Ok(bitmap) Ok(bitmap)
} }
pub fn encode<T: WriteBytesExt + Write, H: CzHeader>( pub fn encode<T: WriteBytesExt + Write>(
output: &mut T, output: &mut T,
bitmap: &[u8], bitmap: &[u8],
header: &H, header: &CommonHeader,
) -> Result<(), CzError> { ) -> Result<(), CzError> {
let bitmap = diff_line(header, bitmap); let bitmap = diff_line(header, bitmap);
@ -37,7 +37,7 @@ pub fn encode<T: WriteBytesExt + Write, H: CzHeader>(
/// ///
/// Uses the previous line to determine the characterisitcs of the /// Uses the previous line to determine the characterisitcs of the
/// following lines /// following lines
fn line_diff<T: CzHeader>(header: &T, data: &[u8]) -> Vec<u8> { fn line_diff(header: &CommonHeader, data: &[u8]) -> Vec<u8> {
let width = header.width() as u32; let width = header.width() as u32;
let height = header.height() as u32; let height = header.height() as u32;
let mut output_buf = data.to_vec(); let mut output_buf = data.to_vec();
@ -74,10 +74,10 @@ fn line_diff<T: CzHeader>(header: &T, data: &[u8]) -> Vec<u8> {
]) ])
} }
} else if pixel_byte_count == 1 { } else if pixel_byte_count == 1 {
for x in 0..line_byte_count { for (x, rgba) in curr_line.iter().enumerate().take(line_byte_count) {
let loc = (y * width) as usize + x; let loc = (y * width) as usize + x;
output_buf[loc] = curr_line[x]; output_buf[loc] = *rgba;
} }
} }
@ -90,7 +90,7 @@ fn line_diff<T: CzHeader>(header: &T, data: &[u8]) -> Vec<u8> {
/// Function to encode data into the CZ3 format before compression /// Function to encode data into the CZ3 format before compression
/// ///
/// Read more in [`line_diff`] /// Read more in [`line_diff`]
fn diff_line<T: CzHeader>(header: &T, input: &[u8]) -> Vec<u8> { fn diff_line(header: &CommonHeader, input: &[u8]) -> Vec<u8> {
let width = header.width() as u32; let width = header.width() as u32;
let height = header.height() as u32; let height = header.height() as u32;

View file

@ -2,7 +2,7 @@ use byteorder::ReadBytesExt;
use image::RgbaImage; use image::RgbaImage;
use std::io::{Read, Seek, SeekFrom}; use std::io::{Read, Seek, SeekFrom};
use crate::common::{CommonHeader, CzError, CzHeader}; use crate::common::{CommonHeader, CzError};
use crate::compression::{decompress, get_chunk_info}; use crate::compression::{decompress, get_chunk_info};
pub fn decode<T: Seek + ReadBytesExt + Read>( pub fn decode<T: Seek + ReadBytesExt + Read>(

View file

@ -1,5 +1,3 @@
mod font_generation;
use cz::{ use cz::{
common::{CzHeader, CzVersion}, common::{CzHeader, CzVersion},
dynamic::DynamicCz dynamic::DynamicCz