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.
This commit is contained in:
parent
a9610a5762
commit
f902b16d3c
|
@ -544,15 +544,16 @@ where
|
||||||
// needing the table to be able to hold buffers containing u16's instead of just u8's.
|
// 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.
|
// this does mean that the size of the table is always 2 less than the number of created codes.
|
||||||
|
|
||||||
let mut table = HashMap::<LzwCode, Vec<u8>>::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 {
|
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 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;
|
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
|
// read the next code which should actually be the first "interesting" value of the code stream
|
||||||
code = match reader.read_code(src)? {
|
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) if code == end_of_info_code => return Ok(()),
|
||||||
Some(code) => code,
|
Some(code) => code,
|
||||||
None => return Err(LzwError::EncodingError(String::from("Unexpected end of code stream"))),
|
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!
|
// ok, now we're able to get started!
|
||||||
|
|
||||||
// simply write out the table string associated with the first code
|
// 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)?;
|
dest.write_all(string)?;
|
||||||
} else {
|
} else {
|
||||||
return Err(LzwError::EncodingError(format!("No table entry for code {}", code)));
|
return Err(LzwError::EncodingError(format!("No table entry for code {}", code)));
|
||||||
|
@ -572,6 +573,7 @@ where
|
||||||
'inner: loop {
|
'inner: loop {
|
||||||
// grab the next code
|
// grab the next code
|
||||||
code = match reader.read_code(src)? {
|
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 == end_of_info_code => break 'outer,
|
||||||
Some(code) if code == clear_code => {
|
Some(code) if code == clear_code => {
|
||||||
// reset the bit size and reader and then loop back to the outer loop which
|
// 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
|
// note: prev_code should always be present since we looked it up in the table during a
|
||||||
// previous loop iteration ...
|
// 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,
|
Some(prev_code_string) => prev_code_string,
|
||||||
None => {
|
None => {
|
||||||
return Err(LzwError::EncodingError(format!("Previous code {} not found in table", prev_code)));
|
return Err(LzwError::EncodingError(format!("Previous code {} not found in table", prev_code)));
|
||||||
|
@ -596,7 +598,7 @@ where
|
||||||
let new_code = next_code;
|
let new_code = next_code;
|
||||||
next_code += 1;
|
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
|
// write out the matching table string for the code just read
|
||||||
dest.write_all(string)?;
|
dest.write_all(string)?;
|
||||||
|
|
||||||
|
@ -604,7 +606,7 @@ where
|
||||||
let k = string.first().unwrap();
|
let k = string.first().unwrap();
|
||||||
let mut new_string = prev_code_string.clone();
|
let mut new_string = prev_code_string.clone();
|
||||||
new_string.push(*k);
|
new_string.push(*k);
|
||||||
table.insert(new_code, new_string);
|
table[new_code as usize] = Some(new_string);
|
||||||
} else {
|
} else {
|
||||||
// code is not yet present in the table.
|
// 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
|
// 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();
|
let mut new_string = prev_code_string.clone();
|
||||||
new_string.push(*k);
|
new_string.push(*k);
|
||||||
dest.write_all(&new_string)?;
|
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 {
|
if new_code == max_code_value_for_bit_size {
|
||||||
|
|
Loading…
Reference in a new issue