mirror of
https://github.com/G2-Games/lbee-utils.git
synced 2025-04-19 15:22:53 -05:00
Cleaned up code, fixed clippy warnings
This commit is contained in:
parent
c4c7e8b9da
commit
c9126a688d
7 changed files with 64 additions and 94 deletions
|
@ -1,7 +1,7 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"cz", "font",
|
"cz",
|
||||||
"utils",
|
"utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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,34 +121,32 @@ 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()
|
)?;
|
||||||
)?;
|
|
||||||
|
|
||||||
output_bitmap = result.0;
|
output_bitmap = result.0;
|
||||||
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 => {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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>(
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
mod font_generation;
|
|
||||||
|
|
||||||
use cz::{
|
use cz::{
|
||||||
common::{CzHeader, CzVersion},
|
common::{CzHeader, CzVersion},
|
||||||
dynamic::DynamicCz
|
dynamic::DynamicCz
|
||||||
|
|
Loading…
Reference in a new issue