mirror of
https://github.com/G2-Games/lbee-utils.git
synced 2025-04-19 23:32:55 -05:00
Fixed compression algorithm again
This commit is contained in:
parent
c33c54beeb
commit
0dc76206a4
3 changed files with 25 additions and 18 deletions
|
@ -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)
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue