From f902b16d3cf66038a04b22b6ed42b1bde6b397ce Mon Sep 17 00:00:00 2001 From: gered Date: Sun, 1 Jan 2023 13:01:10 -0500 Subject: [PATCH] during lzw decoding, use a vector instead of a hashmap for the table since the keys for the previously used hashmap all corresponded with an index, this can obviously just be a vector where the element index corresponds to the lzw code. simple. --- libretrogd/src/utils/lzwgif.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libretrogd/src/utils/lzwgif.rs b/libretrogd/src/utils/lzwgif.rs index 48ad717..4013fd3 100644 --- a/libretrogd/src/utils/lzwgif.rs +++ b/libretrogd/src/utils/lzwgif.rs @@ -544,15 +544,16 @@ where // needing the table to be able to hold buffers containing u16's instead of just u8's. // this does mean that the size of the table is always 2 less than the number of created codes. - let mut table = HashMap::>::with_capacity(initial_table_size + 2); + let mut table = vec![None; 1usize.wrapping_shl(MAX_BITS as u32)]; for i in 0..initial_table_size { - table.insert(i as LzwCode, vec![i as u8]); + table[i] = Some(vec![i as u8]); } let mut max_code_value_for_bit_size = get_max_code_value_for_bits(current_bit_size); let mut next_code = initial_table_size as LzwCode + 2; // read the next code which should actually be the first "interesting" value of the code stream code = match reader.read_code(src)? { + Some(code) if code > MAX_CODE_VALUE => return Err(LzwError::EncodingError(format!("Encountered code that is too large: {}", code))), Some(code) if code == end_of_info_code => return Ok(()), Some(code) => code, None => return Err(LzwError::EncodingError(String::from("Unexpected end of code stream"))), @@ -561,7 +562,7 @@ where // ok, now we're able to get started! // simply write out the table string associated with the first code - if let Some(string) = table.get(&code) { + if let Some(string) = table.get(code as usize).unwrap() { dest.write_all(string)?; } else { return Err(LzwError::EncodingError(format!("No table entry for code {}", code))); @@ -572,6 +573,7 @@ where 'inner: loop { // grab the next code code = match reader.read_code(src)? { + Some(code) if code > MAX_CODE_VALUE => return Err(LzwError::EncodingError(format!("Encountered code that is too large: {}", code))), Some(code) if code == end_of_info_code => break 'outer, Some(code) if code == clear_code => { // reset the bit size and reader and then loop back to the outer loop which @@ -586,7 +588,7 @@ where // note: prev_code should always be present since we looked it up in the table during a // previous loop iteration ... - let prev_code_string = match table.get(&prev_code) { + let prev_code_string = match table.get(prev_code as usize).unwrap() { Some(prev_code_string) => prev_code_string, None => { return Err(LzwError::EncodingError(format!("Previous code {} not found in table", prev_code))); @@ -596,7 +598,7 @@ where let new_code = next_code; next_code += 1; - if let Some(string) = table.get(&code) { + if let Some(string) = table.get(code as usize).unwrap() { // write out the matching table string for the code just read dest.write_all(string)?; @@ -604,7 +606,7 @@ where let k = string.first().unwrap(); let mut new_string = prev_code_string.clone(); new_string.push(*k); - table.insert(new_code, new_string); + table[new_code as usize] = Some(new_string); } else { // code is not yet present in the table. // add prev_code string + the code we just read to the table and also write it out @@ -612,7 +614,7 @@ where let mut new_string = prev_code_string.clone(); new_string.push(*k); dest.write_all(&new_string)?; - table.insert(new_code, new_string); + table[new_code as usize] = Some(new_string); } if new_code == max_code_value_for_bit_size {