Fixed compression algorithm again

This commit is contained in:
G2-Games 2024-05-21 23:08:08 -05:00
parent c33c54beeb
commit 0dc76206a4
3 changed files with 25 additions and 18 deletions

View file

@ -227,7 +227,10 @@ fn copy_one(input: &[u8], src: usize) -> u8 {
} }
} }
pub fn compress(data: &[u8], size: usize) -> (Vec<u8>, CompressionInfo) { pub fn compress(
data: &[u8],
size: usize,
) -> (Vec<u8>, CompressionInfo) {
let mut size = size; let mut size = size;
if size == 0 { if size == 0 {
size = 0xFEFD size = 0xFEFD
@ -248,17 +251,17 @@ pub fn compress(data: &[u8], size: usize) -> (Vec<u8>, CompressionInfo) {
loop { loop {
(count, part_data, last) = compress_lzw(&data[offset..], size, last); (count, part_data, last) = compress_lzw(&data[offset..], size, last);
if count == 0 { if count == 0 {
break; break
} }
offset += count; offset += count;
for d in &part_data { for d in &part_data {
output_buf.write_all(&d.to_le_bytes()).unwrap(); output_buf.write(&d.to_le_bytes()).unwrap();
} }
output_info.chunks.push(ChunkInfo { output_info.chunks.push(ChunkInfo {
size_compressed: part_data.len(), size_compressed: part_data.len(),
size_raw: count, size_raw: count
}); });
output_info.chunk_count += 1; output_info.chunk_count += 1;
@ -278,22 +281,23 @@ pub fn compress(data: &[u8], size: usize) -> (Vec<u8>, CompressionInfo) {
fn compress_lzw(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u16>, Vec<u8>) { fn compress_lzw(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u16>, Vec<u8>) {
let mut count = 0; let mut count = 0;
let mut dictionary = HashMap::with_capacity(size); let mut dictionary = HashMap::new();
for i in 0..=255 { for i in 0..=255 {
dictionary.insert(vec![i], i as u16); dictionary.insert(vec![i], i as u16);
} }
let mut dictionary_count = (dictionary.len() + 1) as u16; let mut dictionary_count = (dictionary.len() + 1) as u16;
let mut element = Vec::with_capacity(512); let mut element = Vec::new();
if !last.is_empty() { if last.len() != 0 {
element = last element = last
} }
let mut compressed = Vec::new(); let mut compressed = Vec::with_capacity(size);
for c in data { for c in data {
let mut entry = element.clone(); let mut entry = element.clone();
entry.push(*c); entry.push(*c);
if dictionary.contains_key(&entry) {
if dictionary.get(&entry).is_some() {
element = entry element = entry
} else { } else {
compressed.push(*dictionary.get(&element).unwrap()); compressed.push(*dictionary.get(&element).unwrap());
@ -305,23 +309,23 @@ fn compress_lzw(data: &[u8], size: usize, last: Vec<u8>) -> (usize, Vec<u16>, Ve
count += 1; count += 1;
if size > 0 && compressed.len() == size { if size > 0 && compressed.len() == size {
break; break
} }
} }
let last_element = element; let last_element = element;
if !compressed.is_empty() { if compressed.len() == 0 {
if !last_element.is_empty() { if last_element.len() != 0 {
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.is_empty() { if last_element.len() != 0 {
compressed.push(*dictionary.get(&last_element).unwrap()); compressed.push(*dictionary.get(&last_element).unwrap());
} }
return (count, compressed, Vec::new()); return (count, compressed, Vec::new())
} }
(count, compressed, last_element) (count, compressed, last_element)

View file

@ -143,7 +143,9 @@ impl DynamicCz {
let palette = result.1; let palette = result.1;
for rgba in palette { for rgba in palette {
out_file.write_all(&rgba.0)?; let mut rgba_clone = rgba.0.clone();
rgba_clone[0..3].reverse();
out_file.write_all(&rgba_clone)?;
} }
}, },
_ => output_bitmap = self.bitmap().clone(), _ => output_bitmap = self.bitmap().clone(),

View file

@ -24,7 +24,7 @@ pub fn encode<T: WriteBytesExt + Write, H: CzHeader>(
) -> Result<(), CzError> { ) -> Result<(), CzError> {
let bitmap = diff_line(header, bitmap); let bitmap = diff_line(header, bitmap);
let (compressed_data, compressed_info) = compress(&bitmap, 0xFEFD); let (compressed_data, compressed_info) = compress(&bitmap, 0xA000);
compressed_info.write_into(output)?; compressed_info.write_into(output)?;
@ -42,7 +42,8 @@ fn line_diff<T: CzHeader>(header: &T, data: &[u8]) -> Vec<u8> {
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();
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 pixel_byte_count = header.depth() >> 3;
let line_byte_count = (width * pixel_byte_count as u32) as usize; let line_byte_count = (width * pixel_byte_count as u32) as usize;