See: https://moddingwiki.shikadi.net/wiki/Id_Software_RLEW_compression
(compressed_data: &[u8], magic_word: &[u8; 2])
| 439 | |
| 440 | /// See: https://moddingwiki.shikadi.net/wiki/Id_Software_RLEW_compression |
| 441 | fn rlew_decompress(compressed_data: &[u8], magic_word: &[u8; 2]) -> Vec<u8> { |
| 442 | let mut output = Vec::new(); |
| 443 | let mut word_i = 0; |
| 444 | let n_words_max = compressed_data.len() / 2; |
| 445 | |
| 446 | while word_i < n_words_max { |
| 447 | let offset = word_i * 2; |
| 448 | let word_bytes = &compressed_data[offset..(offset + 2)]; |
| 449 | if word_bytes == magic_word { |
| 450 | if word_i + 1 == n_words_max { |
| 451 | dbg!("malformed input?"); |
| 452 | break; |
| 453 | } |
| 454 | let count = u16::from_le_bytes( |
| 455 | compressed_data[(offset + 2)..(offset + 4)] |
| 456 | .try_into() |
| 457 | .unwrap(), |
| 458 | ) as usize; |
| 459 | let value = &compressed_data[(offset + 4)..(offset + 6)]; |
| 460 | output.extend(vec![value; count].concat()); |
| 461 | word_i += 3; |
| 462 | } else { |
| 463 | output.extend_from_slice(&compressed_data[offset..(offset + 2)]); |
| 464 | word_i += 1; |
| 465 | } |
| 466 | } |
| 467 | // TODO: remove/revisit this ugly and inefficient hack for testing... |
| 468 | output.into_iter().take(64 * 64 * 2).collect() |
| 469 | } |
| 470 | |
| 471 | /// See: https://moddingwiki.shikadi.net/wiki/Carmack_compression |
| 472 | fn carmack_decompress(compressed_data: &[u8]) -> Vec<u8> { |