mirror of
https://github.com/G2-Games/lbee-utils.git
synced 2025-04-19 07:12:55 -05:00
Cleaned up code, ran cargo fmt
This commit is contained in:
parent
5b95687393
commit
22db2ff571
11 changed files with 141 additions and 147 deletions
|
@ -17,14 +17,6 @@ impl BitIO {
|
|||
self.byte_offset
|
||||
}
|
||||
|
||||
pub fn bit_offset(&self) -> usize {
|
||||
self.bit_offset
|
||||
}
|
||||
|
||||
pub fn into_vec(self) -> Vec<u8> {
|
||||
self.data
|
||||
}
|
||||
|
||||
pub fn read_bit(&mut self, bit_len: usize) -> u64 {
|
||||
//print!("{}: ", bit_len);
|
||||
if bit_len > 8 * 8 {
|
||||
|
@ -37,8 +29,7 @@ impl BitIO {
|
|||
|
||||
let mut result = 0;
|
||||
for i in 0..bit_len {
|
||||
let bit_value =
|
||||
((self.data[self.byte_offset] as usize >> self.bit_offset) & 1) as u64;
|
||||
let bit_value = ((self.data[self.byte_offset] as usize >> self.bit_offset) & 1) as u64;
|
||||
self.bit_offset += 1;
|
||||
|
||||
if self.bit_offset == 8 {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
//! Shared types and traits between CZ# files
|
||||
|
||||
use std::{collections::HashMap, io::{self, Read, Seek, Write}};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
io::{self, Read, Seek, Write},
|
||||
};
|
||||
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use thiserror::Error;
|
||||
|
@ -66,7 +69,10 @@ pub trait CzHeader {
|
|||
fn common(&self) -> &CommonHeader;
|
||||
|
||||
/// Turn the header into bytes equivalent to the original header from the file
|
||||
fn write_into<T: Seek + WriteBytesExt + Write>(&self, output: &mut T) -> Result<usize, io::Error>;
|
||||
fn write_into<T: Seek + WriteBytesExt + Write>(
|
||||
&self,
|
||||
output: &mut T,
|
||||
) -> Result<usize, io::Error>;
|
||||
|
||||
/// The version of the image
|
||||
fn version(&self) -> CzVersion;
|
||||
|
@ -123,18 +129,14 @@ pub struct CommonHeader {
|
|||
}
|
||||
|
||||
impl CommonHeader {
|
||||
pub fn new(
|
||||
version: CzVersion,
|
||||
width: u16,
|
||||
height: u16,
|
||||
) -> Self {
|
||||
pub fn new(version: CzVersion, width: u16, height: u16) -> Self {
|
||||
Self {
|
||||
version,
|
||||
length: 15,
|
||||
width,
|
||||
height,
|
||||
depth: 32,
|
||||
unknown: 0
|
||||
unknown: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,29 +266,34 @@ pub struct ExtendedHeader {
|
|||
}
|
||||
|
||||
impl ExtendedHeader {
|
||||
pub fn new(
|
||||
crop_width: u16,
|
||||
crop_height: u16,
|
||||
bounds_width: u16,
|
||||
bounds_height: u16,
|
||||
) -> Self {
|
||||
pub fn new() -> Self {
|
||||
ExtendedHeader {
|
||||
unknown_1: [0u8; 5],
|
||||
crop_width,
|
||||
crop_height,
|
||||
bounds_width,
|
||||
bounds_height,
|
||||
crop_width: 0,
|
||||
crop_height: 0,
|
||||
bounds_width: 0,
|
||||
bounds_height: 0,
|
||||
offset_width: None,
|
||||
offset_height: None,
|
||||
unknown_2: None
|
||||
unknown_2: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_offset(
|
||||
mut self,
|
||||
offset_width: u16,
|
||||
offset_height: u16
|
||||
) -> Self {
|
||||
pub fn with_crop(mut self, crop_width: u16, crop_height: u16) -> Self {
|
||||
self.crop_width = crop_width;
|
||||
self.crop_height = crop_height;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_bounds(mut self, bounds_height: u16, bounds_width: u16) -> Self {
|
||||
self.bounds_width = bounds_width;
|
||||
self.bounds_height = bounds_height;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_offset(mut self, offset_width: u16, offset_height: u16) -> Self {
|
||||
self.offset_width = Some(offset_width);
|
||||
self.offset_height = Some(offset_height);
|
||||
self.unknown_2 = Some(0);
|
||||
|
@ -296,7 +303,7 @@ impl ExtendedHeader {
|
|||
|
||||
pub fn from_bytes<T: Seek + ReadBytesExt + Read>(
|
||||
input: &mut T,
|
||||
common_header: &CommonHeader
|
||||
common_header: &CommonHeader,
|
||||
) -> Result<Self, CzError> {
|
||||
let mut unknown_1 = [0u8; 5];
|
||||
input.read_exact(&mut unknown_1)?;
|
||||
|
@ -335,7 +342,7 @@ impl ExtendedHeader {
|
|||
|
||||
pub fn write_into<T: Seek + WriteBytesExt + Write>(
|
||||
&self,
|
||||
output: &mut T
|
||||
output: &mut T,
|
||||
) -> Result<usize, io::Error> {
|
||||
let pos = output.stream_position()?;
|
||||
|
||||
|
@ -355,6 +362,12 @@ impl ExtendedHeader {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for ExtendedHeader {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_palette<T: Seek + ReadBytesExt + Read>(
|
||||
input: &mut T,
|
||||
num_colors: usize,
|
||||
|
@ -370,10 +383,7 @@ pub fn get_palette<T: Seek + ReadBytesExt + Read>(
|
|||
Ok(colormap)
|
||||
}
|
||||
|
||||
pub fn apply_palette(
|
||||
input: &[u8],
|
||||
palette: &[[u8; 4]]
|
||||
) -> Result<Vec<u8>, CzError> {
|
||||
pub fn apply_palette(input: &[u8], palette: &[[u8; 4]]) -> Result<Vec<u8>, CzError> {
|
||||
let mut output_map = Vec::new();
|
||||
|
||||
for byte in input.iter() {
|
||||
|
@ -381,7 +391,7 @@ pub fn apply_palette(
|
|||
if let Some(color) = color {
|
||||
output_map.extend_from_slice(color);
|
||||
} else {
|
||||
return Err(CzError::PaletteError)
|
||||
return Err(CzError::PaletteError);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
collections::HashMap,
|
||||
io::{Read, Seek, Write},
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,7 @@ pub struct ChunkInfo {
|
|||
}
|
||||
|
||||
/// A CZ# file's information about compression chunks
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct CompressionInfo {
|
||||
/// Number of compression chunks
|
||||
pub chunk_count: usize,
|
||||
|
@ -36,18 +36,6 @@ pub struct CompressionInfo {
|
|||
pub length: usize,
|
||||
}
|
||||
|
||||
impl Default for CompressionInfo {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
chunk_count: 0,
|
||||
total_size_compressed: 0,
|
||||
total_size_raw: 0,
|
||||
chunks: Vec::new(),
|
||||
length: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CompressionInfo {
|
||||
pub fn write_into<T: WriteBytesExt + Write>(
|
||||
&self,
|
||||
|
@ -201,12 +189,7 @@ fn get_offset(input: &[u8], src: usize) -> usize {
|
|||
(((input[src] as usize) | (input[src + 1] as usize) << 8) - 0x101) * 2
|
||||
}
|
||||
|
||||
fn copy_range(
|
||||
bitmap: &mut Vec<u8>,
|
||||
input: &[u8],
|
||||
src: usize,
|
||||
dst: usize
|
||||
) -> usize {
|
||||
fn copy_range(bitmap: &mut Vec<u8>, input: &[u8], src: usize, dst: usize) -> usize {
|
||||
let mut dst = dst;
|
||||
let start_pos = dst;
|
||||
|
||||
|
@ -249,8 +232,7 @@ pub fn line_diff<T: CzHeader>(header: &T, data: &[u8]) -> Vec<u8> {
|
|||
let height = header.height() as u32;
|
||||
let mut output_buf = data.to_vec();
|
||||
|
||||
let block_height =
|
||||
(f32::ceil(height as f32 / 3.0) as u16) as usize;
|
||||
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;
|
||||
|
||||
|
@ -278,7 +260,7 @@ pub fn line_diff<T: CzHeader>(header: &T, data: &[u8]) -> Vec<u8> {
|
|||
curr_line[x],
|
||||
curr_line[x + 1],
|
||||
curr_line[x + 2],
|
||||
0xFF
|
||||
0xFF,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@ -295,8 +277,7 @@ pub fn diff_line<T: CzHeader>(header: &T, input: &[u8]) -> Vec<u8> {
|
|||
|
||||
let mut data = Vec::with_capacity(input.len());
|
||||
|
||||
let block_height =
|
||||
(f32::ceil(height as f32 / 3.0) as u16) as usize;
|
||||
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;
|
||||
|
||||
|
@ -308,8 +289,8 @@ pub fn diff_line<T: CzHeader>(header: &T, input: &[u8]) -> Vec<u8> {
|
|||
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];
|
||||
curr_line[x] = curr_line[x].wrapping_sub(prev_line[x]);
|
||||
prev_line[x] = prev_line[x].wrapping_add(curr_line[x]);
|
||||
}
|
||||
} else {
|
||||
prev_line.clone_from(&curr_line);
|
||||
|
@ -322,10 +303,7 @@ pub fn diff_line<T: CzHeader>(header: &T, input: &[u8]) -> Vec<u8> {
|
|||
data
|
||||
}
|
||||
|
||||
pub fn compress(
|
||||
data: &[u8],
|
||||
size: usize,
|
||||
) -> (Vec<u8>, CompressionInfo) {
|
||||
pub fn compress(data: &[u8], size: usize) -> (Vec<u8>, CompressionInfo) {
|
||||
let mut size = size;
|
||||
if size == 0 {
|
||||
size = 0xFEFD
|
||||
|
@ -346,17 +324,17 @@ pub fn compress(
|
|||
loop {
|
||||
(count, part_data, last) = compress_lzw(&data[offset..], size, last);
|
||||
if count == 0 {
|
||||
break
|
||||
break;
|
||||
}
|
||||
offset += count;
|
||||
|
||||
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 {
|
||||
size_compressed: part_data.len(),
|
||||
size_raw: count
|
||||
size_raw: count,
|
||||
});
|
||||
|
||||
output_info.chunk_count += 1;
|
||||
|
@ -383,7 +361,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 element = Vec::new();
|
||||
if last.len() != 0 {
|
||||
if !last.is_empty() {
|
||||
element = last
|
||||
}
|
||||
|
||||
|
@ -392,7 +370,7 @@ fn compress_lzw(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u16>, Ve
|
|||
let mut entry = element.clone();
|
||||
entry.push(*c);
|
||||
|
||||
if dictionary.get(&entry).is_some() {
|
||||
if dictionary.contains_key(&entry) {
|
||||
element = entry
|
||||
} else {
|
||||
compressed.push(*dictionary.get(&element).unwrap());
|
||||
|
@ -404,23 +382,23 @@ fn compress_lzw(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u16>, Ve
|
|||
count += 1;
|
||||
|
||||
if size > 0 && compressed.len() == size {
|
||||
break
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let last_element = element;
|
||||
if compressed.len() == 0 {
|
||||
if last_element.len() != 0 {
|
||||
if !compressed.is_empty() {
|
||||
if !last_element.is_empty() {
|
||||
for c in last_element {
|
||||
compressed.push(*dictionary.get(&vec![c]).unwrap());
|
||||
}
|
||||
}
|
||||
return (count, compressed, Vec::new())
|
||||
return (count, compressed, Vec::new());
|
||||
} else if compressed.len() < size {
|
||||
if last_element.len() != 0 {
|
||||
if !last_element.is_empty() {
|
||||
compressed.push(*dictionary.get(&last_element).unwrap());
|
||||
}
|
||||
return (count, compressed, Vec::new())
|
||||
return (count, compressed, Vec::new());
|
||||
}
|
||||
|
||||
(count, compressed, last_element)
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
use std::{
|
||||
fs::{self, File}, io::{BufReader, BufWriter, Read, Seek, SeekFrom, Write}, path::Path
|
||||
};
|
||||
use byteorder::ReadBytesExt;
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufReader, BufWriter, Read, Seek, SeekFrom, Write},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
common::{apply_palette, get_palette, rgba_to_indexed, CommonHeader, CzError, CzHeader, CzVersion, ExtendedHeader},
|
||||
common::{
|
||||
apply_palette, get_palette, rgba_to_indexed, CommonHeader, CzError, CzHeader, CzVersion,
|
||||
ExtendedHeader,
|
||||
},
|
||||
formats::{cz0, cz1, cz2, cz3, cz4},
|
||||
};
|
||||
|
||||
|
@ -22,14 +27,20 @@ impl DynamicCz {
|
|||
Self::decode(&mut img_file)
|
||||
}
|
||||
|
||||
pub fn save_as_png<P: ?Sized + AsRef<Path>>(&self, path: &P) -> Result<(), image::error::EncodingError> {
|
||||
pub fn save_as_png<P: ?Sized + AsRef<Path>>(
|
||||
&self,
|
||||
path: &P,
|
||||
) -> Result<(), image::error::EncodingError> {
|
||||
let image = image::RgbaImage::from_raw(
|
||||
self.header_common.width() as u32,
|
||||
self.header_common.height() as u32,
|
||||
self.bitmap.clone()
|
||||
).unwrap();
|
||||
self.bitmap.clone(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
image.save_with_format(path, image::ImageFormat::Png).unwrap();
|
||||
image
|
||||
.save_with_format(path, image::ImageFormat::Png)
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -38,13 +49,9 @@ impl DynamicCz {
|
|||
version: CzVersion,
|
||||
width: u16,
|
||||
height: u16,
|
||||
bitmap: Vec<u8>,
|
||||
bitmap: Vec<u8>
|
||||
) -> Self {
|
||||
let header_common = CommonHeader::new(
|
||||
version,
|
||||
width,
|
||||
height
|
||||
);
|
||||
let header_common = CommonHeader::new(version, width, height);
|
||||
|
||||
Self {
|
||||
header_common,
|
||||
|
@ -61,10 +68,10 @@ impl DynamicCz {
|
|||
}
|
||||
|
||||
pub fn with_extended_header(mut self, ext_header: ExtendedHeader) -> Self {
|
||||
if ext_header.offset_width.is_none() {
|
||||
self.header_common.set_length(28)
|
||||
} else {
|
||||
if ext_header.offset_width.is_some() {
|
||||
self.header_common.set_length(36)
|
||||
} else {
|
||||
self.header_common.set_length(28)
|
||||
}
|
||||
|
||||
self.header_extended = Some(ext_header);
|
||||
|
@ -104,7 +111,7 @@ impl DynamicCz {
|
|||
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
|
||||
return Err(CzError::Corrupt)
|
||||
return Err(CzError::Corrupt);
|
||||
}
|
||||
|
||||
if let Some(palette) = &palette {
|
||||
|
@ -119,8 +126,11 @@ impl DynamicCz {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn save_as_cz<T: Into<std::path::PathBuf>>(&self, path: T) -> Result<(), CzError> {
|
||||
let mut out_file = File::create(path.into())?;
|
||||
pub fn save_as_cz<T: Into<std::path::PathBuf>>(
|
||||
&self,
|
||||
path: T
|
||||
) -> Result<(), CzError> {
|
||||
let mut out_file = BufWriter::new(File::create(path.into())?);
|
||||
|
||||
self.header_common.write_into(&mut out_file)?;
|
||||
|
||||
|
@ -131,13 +141,13 @@ impl DynamicCz {
|
|||
let output_bitmap;
|
||||
match &self.palette {
|
||||
Some(pal) if self.header_common.depth() <= 8 => {
|
||||
output_bitmap = rgba_to_indexed(&self.bitmap(), &pal)?;
|
||||
output_bitmap = rgba_to_indexed(self.bitmap(), pal)?;
|
||||
|
||||
for rgba in pal {
|
||||
out_file.write_all(rgba)?;
|
||||
}
|
||||
},
|
||||
_ => output_bitmap = self.bitmap().clone()
|
||||
}
|
||||
_ => output_bitmap = self.bitmap().clone(),
|
||||
}
|
||||
|
||||
match self.header_common.version() {
|
||||
|
@ -161,7 +171,7 @@ impl DynamicCz {
|
|||
}
|
||||
|
||||
pub fn set_header(&mut self, header: &CommonHeader) {
|
||||
self.header_common = header.to_owned()
|
||||
header.clone_into(&mut self.header_common)
|
||||
}
|
||||
|
||||
pub fn bitmap(&self) -> &Vec<u8> {
|
||||
|
@ -174,7 +184,7 @@ impl DynamicCz {
|
|||
|
||||
pub fn set_bitmap(&mut self, bitmap: Vec<u8>, width: u16, height: u16) -> Result<(), CzError> {
|
||||
if bitmap.len() != width as usize * height as usize {
|
||||
return Err(CzError::BitmapFormat)
|
||||
return Err(CzError::BitmapFormat);
|
||||
}
|
||||
|
||||
self.bitmap = bitmap;
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
use std::io::{Read, Write, Seek};
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt};
|
||||
use std::io::{Read, Seek, Write};
|
||||
|
||||
use crate::common::CzError;
|
||||
|
||||
pub fn decode<T: Seek + ReadBytesExt + Read>(
|
||||
input: &mut T
|
||||
) -> Result<Vec<u8>, CzError> {
|
||||
pub fn decode<T: Seek + ReadBytesExt + Read>(input: &mut T) -> Result<Vec<u8>, CzError> {
|
||||
// Get the rest of the file, which is the bitmap
|
||||
let mut bitmap = vec![];
|
||||
input.read_to_end(&mut bitmap)?;
|
||||
|
@ -13,10 +11,7 @@ pub fn decode<T: Seek + ReadBytesExt + Read>(
|
|||
Ok(bitmap)
|
||||
}
|
||||
|
||||
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> {
|
||||
output.write_all(bitmap)?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -17,10 +17,7 @@ pub fn decode<T: Seek + ReadBytesExt + Read>(bytes: &mut T) -> Result<Vec<u8>, C
|
|||
Ok(bitmap)
|
||||
}
|
||||
|
||||
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) = compress(bitmap, 0xFEFD);
|
||||
|
||||
dbg!(&compressed_info);
|
||||
|
|
|
@ -4,9 +4,7 @@ use std::io::{Read, Seek, SeekFrom};
|
|||
use crate::common::CzError;
|
||||
use crate::compression::{decompress_2, 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> {
|
||||
let block_info = get_chunk_info(bytes)?;
|
||||
bytes.seek(SeekFrom::Start(block_info.length as u64))?;
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use std::io::{Read, Write, Seek, SeekFrom};
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt};
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
|
||||
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
|
||||
header: &CommonHeader,
|
||||
) -> Result<Vec<u8>, CzError> {
|
||||
let block_info = get_chunk_info(bytes)?;
|
||||
bytes.seek(SeekFrom::Start(block_info.length as u64))?;
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
use std::io::{Read, Seek, SeekFrom};
|
||||
use byteorder::ReadBytesExt;
|
||||
use image::RgbaImage;
|
||||
use std::io::{Read, Seek, SeekFrom};
|
||||
|
||||
use crate::common::{CommonHeader, CzError, CzHeader};
|
||||
use crate::compression::{decompress, get_chunk_info};
|
||||
|
||||
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))?;
|
||||
|
||||
|
@ -24,10 +27,7 @@ pub fn decode<T: Seek + ReadBytesExt + Read>(bytes: &mut T, header: &CommonHeade
|
|||
Ok(picture.into_raw())
|
||||
}
|
||||
|
||||
pub fn line_diff_cz4(
|
||||
picture: &mut RgbaImage,
|
||||
pixel_byte_count: usize, data: &[u8]
|
||||
) {
|
||||
pub fn line_diff_cz4(picture: &mut RgbaImage, pixel_byte_count: usize, data: &[u8]) {
|
||||
let width = picture.width();
|
||||
let height = picture.height();
|
||||
let block_height = (f32::ceil(height as f32 / 3.0) as u16) as u32;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
mod binio;
|
||||
mod compression;
|
||||
|
||||
pub mod dynamic;
|
||||
pub mod common;
|
||||
pub mod dynamic;
|
||||
|
||||
pub mod formats {
|
||||
pub mod cz0;
|
||||
|
|
|
@ -1,23 +1,38 @@
|
|||
use cz::{common::{CzVersion, ExtendedHeader}, dynamic::DynamicCz};
|
||||
use std::time::Instant;
|
||||
|
||||
use cz::{
|
||||
common::{CzVersion, ExtendedHeader},
|
||||
dynamic::DynamicCz,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let mio = image::open("mio_inverted.png").unwrap();
|
||||
let mio = mio.to_rgba8();
|
||||
let timer = Instant::now();
|
||||
let mio = image::open("mio_inverted.png").unwrap().to_rgba8();
|
||||
println!("Opening PNG took {:?}", timer.elapsed());
|
||||
|
||||
let cz_mio =
|
||||
DynamicCz::from_raw(
|
||||
CzVersion::CZ3,
|
||||
mio.width() as u16,
|
||||
mio.height() as u16,
|
||||
mio.into_raw()
|
||||
)
|
||||
.with_extended_header(
|
||||
ExtendedHeader::new(1280, 960, 1280, 960)
|
||||
);
|
||||
let timer = Instant::now();
|
||||
let cz_mio = DynamicCz::from_raw(
|
||||
CzVersion::CZ3,
|
||||
mio.width() as u16,
|
||||
mio.height() as u16,
|
||||
mio.into_raw(),
|
||||
)
|
||||
.with_extended_header(
|
||||
ExtendedHeader::new()
|
||||
.with_crop(1280, 960)
|
||||
.with_bounds(1280, 960),
|
||||
);
|
||||
println!("Constructing CZ3 took {:?}", timer.elapsed());
|
||||
|
||||
let timer = Instant::now();
|
||||
cz_mio.save_as_png("test_save.png").unwrap();
|
||||
println!("Saving CZ3 as PNG took {:?}", timer.elapsed());
|
||||
|
||||
let timer = Instant::now();
|
||||
cz_mio.save_as_cz("test1.cz3").unwrap();
|
||||
println!("Saving CZ3 as CZ3 took {:?}", timer.elapsed());
|
||||
|
||||
let timer = Instant::now();
|
||||
let img = DynamicCz::open("test1.cz3").unwrap();
|
||||
|
||||
img.save_as_png("test.png").unwrap();
|
||||
println!("Opening saved CZ3 took {:?}", timer.elapsed());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue