Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precompute fixed huffman tables #39

Merged
merged 4 commits into from
Nov 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions src/decompress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use simd_adler32::Adler32;
use crate::{
huffman::{self, build_table},
tables::{
self, CLCL_ORDER, DIST_SYM_TO_DIST_BASE, DIST_SYM_TO_DIST_EXTRA, FIXED_CODE_LENGTHS,
LEN_SYM_TO_LEN_BASE, LEN_SYM_TO_LEN_EXTRA, LITLEN_TABLE_ENTRIES,
self, CLCL_ORDER, DIST_SYM_TO_DIST_BASE, DIST_SYM_TO_DIST_EXTRA, FIXED_DIST_TABLE,
FIXED_LITLEN_TABLE, LEN_SYM_TO_LEN_BASE, LEN_SYM_TO_LEN_EXTRA, LITLEN_TABLE_ENTRIES,
},
};

Expand Down Expand Up @@ -62,13 +62,12 @@ pub const EXCEPTIONAL_ENTRY: u32 = 0x4000;
pub const SECONDARY_TABLE_ENTRY: u32 = 0x2000;

/// The Decompressor state for a compressed block.
#[repr(align(64))]
#[derive(Eq, PartialEq, Debug)]
struct CompressedBlock {
litlen_table: [u32; 4096],
litlen_table: Box<[u32; 4096]>,
secondary_table: Vec<u16>,

dist_table: [u32; 512],
dist_table: Box<[u32; 512]>,
dist_secondary_table: Vec<u16>,

eof_code: u16,
Expand Down Expand Up @@ -123,8 +122,8 @@ impl Decompressor {
buffer: 0,
nbits: 0,
compression: CompressedBlock {
litlen_table: [0; 4096],
dist_table: [0; 512],
litlen_table: Box::new([0; 4096]),
dist_table: Box::new([0; 512]),
secondary_table: Vec::new(),
dist_secondary_table: Vec::new(),
eof_code: 0,
Expand Down Expand Up @@ -237,7 +236,12 @@ impl Decompressor {
// Build decoding tables if the previous block wasn't also a fixed block.
if !self.fixed_table {
self.fixed_table = true;
Self::build_tables(288, &FIXED_CODE_LENGTHS, &mut self.compression)?;
for chunk in self.compression.litlen_table.chunks_exact_mut(512) {
chunk.copy_from_slice(&FIXED_LITLEN_TABLE);
}
for chunk in self.compression.dist_table.chunks_exact_mut(32) {
chunk.copy_from_slice(&FIXED_DIST_TABLE);
}
}

self.state = State::CompressedData;
Expand Down Expand Up @@ -405,7 +409,7 @@ impl Decompressor {
&code_lengths[..hlit],
&LITLEN_TABLE_ENTRIES,
&mut codes[..hlit],
&mut compression.litlen_table,
&mut *compression.litlen_table,
&mut compression.secondary_table,
false,
true,
Expand All @@ -427,7 +431,7 @@ impl Decompressor {
lengths,
&tables::DISTANCE_TABLE_ENTRIES,
&mut dist_codes,
&mut compression.dist_table,
&mut *compression.dist_table,
&mut compression.dist_secondary_table,
true,
false,
Expand Down Expand Up @@ -1154,6 +1158,23 @@ mod tests {
}
}

#[test]
fn fixed_tables() {
let mut compression = CompressedBlock {
litlen_table: Box::new([0; 4096]),
dist_table: Box::new([0; 512]),
secondary_table: Vec::new(),
dist_secondary_table: Vec::new(),
eof_code: 0,
eof_mask: 0,
eof_bits: 0,
};
Decompressor::build_tables(288, &FIXED_CODE_LENGTHS, &mut compression).unwrap();

assert_eq!(compression.litlen_table[..512], FIXED_LITLEN_TABLE);
assert_eq!(compression.dist_table[..32], FIXED_DIST_TABLE);
}

#[test]
fn it_works() {
roundtrip(b"Hello world!");
Expand Down Expand Up @@ -1259,6 +1280,7 @@ mod tests {
}

mod test_utils;
use tables::FIXED_CODE_LENGTHS;
use test_utils::{decompress_by_chunks, TestDecompressionError};

fn verify_no_sensitivity_to_input_chunking(
Expand Down
65 changes: 65 additions & 0 deletions src/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,72 @@ pub(crate) const DISTANCE_TABLE_ENTRIES: [u32; 32] = {
entries
};

pub(crate) const FIXED_LITLEN_TABLE: [u32; 512] = [
16391, 5275912, 1081608, 7537672, 2032135, 7373064, 3178760, 12615945, 655367, 6324488,
2130184, 10518793, 33032, 8421640, 4227336, 14713097, 393223, 5800200, 1605896, 9470217,
3867399, 7897352, 3703048, 13664521, 1114375, 6848776, 2654472, 11567369, 557320, 8945928,
4751624, 15761673, 262151, 5538056, 1343752, 14877960, 2818823, 7635208, 3440904, 13140233,
852231, 6586632, 2392328, 11043081, 295176, 8683784, 4489480, 15237385, 524295, 6062344,
1868040, 9994505, 5440519, 8159496, 3965192, 14188809, 1507847, 7110920, 2916616, 12091657,
819464, 9208072, 5013768, 16285961, 196615, 5406984, 1212680, 10683656, 2294535, 7504136,
3309832, 12878089, 721159, 6455560, 2261256, 10780937, 164104, 8552712, 4358408, 14975241,
458759, 5931272, 1736968, 9732361, 4391943, 8028424, 3834120, 13926665, 1245703, 6979848,
2785544, 11829513, 688392, 9077000, 4882696, 16023817, 327687, 5669128, 1474824, 16392,
3343111, 7766280, 3571976, 13402377, 983303, 6717704, 2523400, 11305225, 426248, 8814856,
4620552, 15499529, 589831, 6193416, 1999112, 10256649, 6489095, 8290568, 4096264, 14450953,
1769991, 7241992, 3047688, 12353801, 950536, 9339144, 5144840, 16548105, 16391, 5341448,
1147144, 8586504, 2032135, 7438600, 3244296, 12747017, 655367, 6390024, 2195720, 10649865,
98568, 8487176, 4292872, 14844169, 393223, 5865736, 1671432, 9601289, 3867399, 7962888,
3768584, 13795593, 1114375, 6914312, 2720008, 11698441, 622856, 9011464, 4817160, 15892745,
262151, 5603592, 1409288, 16908296, 2818823, 7700744, 3506440, 13271305, 852231, 6652168,
2457864, 11174153, 360712, 8749320, 4555016, 15368457, 524295, 6127880, 1933576, 10125577,
5440519, 8225032, 4030728, 14319881, 1507847, 7176456, 2982152, 12222729, 885000, 9273608,
5079304, 16417033, 196615, 5472520, 1278216, 12780808, 2294535, 7569672, 3375368, 13009161,
721159, 6521096, 2326792, 10912009, 229640, 8618248, 4423944, 15106313, 458759, 5996808,
1802504, 9863433, 4391943, 8093960, 3899656, 14057737, 1245703, 7045384, 2851080, 11960585,
753928, 9142536, 4948232, 16154889, 327687, 5734664, 1540360, 16392, 3343111, 7831816, 3637512,
13533449, 983303, 6783240, 2588936, 11436297, 491784, 8880392, 4686088, 15630601, 589831,
6258952, 2064648, 10387721, 6489095, 8356104, 4161800, 14582025, 1769991, 7307528, 3113224,
12484873, 1016072, 9404680, 5210376, 16679177, 16391, 5275912, 1081608, 7537672, 2032135,
7373064, 3178760, 12681481, 655367, 6324488, 2130184, 10584329, 33032, 8421640, 4227336,
14778633, 393223, 5800200, 1605896, 9535753, 3867399, 7897352, 3703048, 13730057, 1114375,
6848776, 2654472, 11632905, 557320, 8945928, 4751624, 15827209, 262151, 5538056, 1343752,
14877960, 2818823, 7635208, 3440904, 13205769, 852231, 6586632, 2392328, 11108617, 295176,
8683784, 4489480, 15302921, 524295, 6062344, 1868040, 10060041, 5440519, 8159496, 3965192,
14254345, 1507847, 7110920, 2916616, 12157193, 819464, 9208072, 5013768, 16351497, 196615,
5406984, 1212680, 10683656, 2294535, 7504136, 3309832, 12943625, 721159, 6455560, 2261256,
10846473, 164104, 8552712, 4358408, 15040777, 458759, 5931272, 1736968, 9797897, 4391943,
8028424, 3834120, 13992201, 1245703, 6979848, 2785544, 11895049, 688392, 9077000, 4882696,
16089353, 327687, 5669128, 1474824, 16392, 3343111, 7766280, 3571976, 13467913, 983303,
6717704, 2523400, 11370761, 426248, 8814856, 4620552, 15565065, 589831, 6193416, 1999112,
10322185, 6489095, 8290568, 4096264, 14516489, 1769991, 7241992, 3047688, 12419337, 950536,
9339144, 5144840, 16613641, 16391, 5341448, 1147144, 8586504, 2032135, 7438600, 3244296,
12812553, 655367, 6390024, 2195720, 10715401, 98568, 8487176, 4292872, 14909705, 393223,
5865736, 1671432, 9666825, 3867399, 7962888, 3768584, 13861129, 1114375, 6914312, 2720008,
11763977, 622856, 9011464, 4817160, 15958281, 262151, 5603592, 1409288, 16908296, 2818823,
7700744, 3506440, 13336841, 852231, 6652168, 2457864, 11239689, 360712, 8749320, 4555016,
15433993, 524295, 6127880, 1933576, 10191113, 5440519, 8225032, 4030728, 14385417, 1507847,
7176456, 2982152, 12288265, 885000, 9273608, 5079304, 16482569, 196615, 5472520, 1278216,
12780808, 2294535, 7569672, 3375368, 13074697, 721159, 6521096, 2326792, 10977545, 229640,
8618248, 4423944, 15171849, 458759, 5996808, 1802504, 9928969, 4391943, 8093960, 3899656,
14123273, 1245703, 7045384, 2851080, 12026121, 753928, 9142536, 4948232, 16220425, 327687,
5734664, 1540360, 16392, 3343111, 7831816, 3637512, 13598985, 983303, 6783240, 2588936,
11501833, 491784, 8880392, 4686088, 15696137, 589831, 6258952, 2064648, 10453257, 6489095,
8356104, 4161800, 14647561, 1769991, 7307528, 3113224, 12550409, 1016072, 9404680, 5210376,
16744713,
];

pub(crate) const FIXED_DIST_TABLE: [u32; 32] = [
98309, 16877317, 1147653, 268536581, 360709, 67209477, 4293893, 1073843461, 229381, 33654789,
2196485, 536972293, 623109, 134318597, 8488453, 5, 163845, 25265925, 1671941, 402754309,
491781, 100763909, 6391045, 1610714373, 294917, 50432005, 3245061, 805407749, 885253,
201427461, 12682757, 5,
];

#[cfg(test)]
pub(crate) const FIXED_CODE_LENGTHS: [u8; 320] = make_fixed_code_lengths();

#[cfg(test)]
const fn make_fixed_code_lengths() -> [u8; 320] {
let mut i = 0;
let mut lengths = [0; 320];
Expand Down