pub fn encode(src: impl AsRef<[u8]>) -> Vec<u8> {
let mut bits: u64 = 0;
let mut bits_left = 40;
let mut dst = vec![];
for &byte in src.as_ref() {
let node = &ENCODE_TABLE[byte as usize];
bits |= node.code << (bits_left - node.len); bits_left -= node.len;
while bits_left <= 32 {
dst.push((bits >> 32) as u8);
bits <<= 8; bits_left += 8;
}
}
if bits_left != 40 { bits |= (1 << bits_left) - 1; dst.push((bits >> 32) as u8);
}
dst
}
struct HuffmanNode {
len: u8,
code: u64,
}
const ENCODE_TABLE: [HuffmanNode; 257] = [
HuffmanNode { len: 13, code: 0x1ff8 },
HuffmanNode { len: 23, code: 0x7fffd8 },
HuffmanNode { len: 28, code: 0xfffffe2 },
HuffmanNode { len: 28, code: 0xfffffe3 },
HuffmanNode { len: 28, code: 0xfffffe4 },
HuffmanNode { len: 28, code: 0xfffffe5 },
HuffmanNode { len: 28, code: 0xfffffe6 },
HuffmanNode { len: 28, code: 0xfffffe7 },
HuffmanNode { len: 28, code: 0xfffffe8 },
HuffmanNode { len: 24, code: 0xffffea },
HuffmanNode { len: 30, code: 0x3ffffffc },
HuffmanNode { len: 28, code: 0xfffffe9 },
HuffmanNode { len: 28, code: 0xfffffea },
HuffmanNode { len: 30, code: 0x3ffffffd },
HuffmanNode { len: 28, code: 0xfffffeb },
HuffmanNode { len: 28, code: 0xfffffec },
HuffmanNode { len: 28, code: 0xfffffed },
HuffmanNode { len: 28, code: 0xfffffee },
HuffmanNode { len: 28, code: 0xfffffef },
HuffmanNode { len: 28, code: 0xffffff0 },
HuffmanNode { len: 28, code: 0xffffff1 },
HuffmanNode { len: 28, code: 0xffffff2 },
HuffmanNode { len: 30, code: 0x3ffffffe },
HuffmanNode { len: 28, code: 0xffffff3 },
HuffmanNode { len: 28, code: 0xffffff4 },
HuffmanNode { len: 28, code: 0xffffff5 },
HuffmanNode { len: 28, code: 0xffffff6 },
HuffmanNode { len: 28, code: 0xffffff7 },
HuffmanNode { len: 28, code: 0xffffff8 },
HuffmanNode { len: 28, code: 0xffffff9 },
HuffmanNode { len: 28, code: 0xffffffa },
HuffmanNode { len: 28, code: 0xffffffb },
HuffmanNode { len: 6, code: 0x14 },
HuffmanNode { len: 10, code: 0x3f8 },
HuffmanNode { len: 10, code: 0x3f9 },
HuffmanNode { len: 12, code: 0xffa },
HuffmanNode { len: 13, code: 0x1ff9 },
HuffmanNode { len: 6, code: 0x15 },
HuffmanNode { len: 8, code: 0xf8 },
HuffmanNode { len: 11, code: 0x7fa },
HuffmanNode { len: 10, code: 0x3fa },
HuffmanNode { len: 10, code: 0x3fb },
HuffmanNode { len: 8, code: 0xf9 },
HuffmanNode { len: 11, code: 0x7fb },
HuffmanNode { len: 8, code: 0xfa },
HuffmanNode { len: 6, code: 0x16 },
HuffmanNode { len: 6, code: 0x17 },
HuffmanNode { len: 6, code: 0x18 },
HuffmanNode { len: 5, code: 0x00 },
HuffmanNode { len: 5, code: 0x01 },
HuffmanNode { len: 5, code: 0x02 },
HuffmanNode { len: 6, code: 0x19 },
HuffmanNode { len: 6, code: 0x1a },
HuffmanNode { len: 6, code: 0x1b },
HuffmanNode { len: 6, code: 0x1c },
HuffmanNode { len: 6, code: 0x1d },
HuffmanNode { len: 6, code: 0x1e },
HuffmanNode { len: 6, code: 0x1f },
HuffmanNode { len: 7, code: 0x5c },
HuffmanNode { len: 8, code: 0xfb },
HuffmanNode { len: 15, code: 0x7ffc },
HuffmanNode { len: 6, code: 0x20 },
HuffmanNode { len: 12, code: 0xffb },
HuffmanNode { len: 10, code: 0x3fc },
HuffmanNode { len: 13, code: 0x1ffa },
HuffmanNode { len: 6, code: 0x21 },
HuffmanNode { len: 7, code: 0x5d },
HuffmanNode { len: 7, code: 0x5e },
HuffmanNode { len: 7, code: 0x5f },
HuffmanNode { len: 7, code: 0x60 },
HuffmanNode { len: 7, code: 0x61 },
HuffmanNode { len: 7, code: 0x62 },
HuffmanNode { len: 7, code: 0x63 },
HuffmanNode { len: 7, code: 0x64 },
HuffmanNode { len: 7, code: 0x65 },
HuffmanNode { len: 7, code: 0x66 },
HuffmanNode { len: 7, code: 0x67 },
HuffmanNode { len: 7, code: 0x68 },
HuffmanNode { len: 7, code: 0x69 },
HuffmanNode { len: 7, code: 0x6a },
HuffmanNode { len: 7, code: 0x6b },
HuffmanNode { len: 7, code: 0x6c },
HuffmanNode { len: 7, code: 0x6d },
HuffmanNode { len: 7, code: 0x6e },
HuffmanNode { len: 7, code: 0x6f },
HuffmanNode { len: 7, code: 0x70 },
HuffmanNode { len: 7, code: 0x71 },
HuffmanNode { len: 7, code: 0x72 },
HuffmanNode { len: 8, code: 0xfc },
HuffmanNode { len: 7, code: 0x73 },
HuffmanNode { len: 8, code: 0xfd },
HuffmanNode { len: 13, code: 0x1ffb },
HuffmanNode { len: 19, code: 0x7fff0 },
HuffmanNode { len: 13, code: 0x1ffc },
HuffmanNode { len: 14, code: 0x3ffc },
HuffmanNode { len: 6, code: 0x22 },
HuffmanNode { len: 15, code: 0x7ffd },
HuffmanNode { len: 5, code: 0x03 },
HuffmanNode { len: 6, code: 0x23 },
HuffmanNode { len: 5, code: 0x04 },
HuffmanNode { len: 6, code: 0x24 },
HuffmanNode { len: 5, code: 0x05 },
HuffmanNode { len: 6, code: 0x25 },
HuffmanNode { len: 6, code: 0x26 },
HuffmanNode { len: 6, code: 0x27 },
HuffmanNode { len: 5, code: 0x06 },
HuffmanNode { len: 7, code: 0x74 },
HuffmanNode { len: 7, code: 0x75 },
HuffmanNode { len: 6, code: 0x28 },
HuffmanNode { len: 6, code: 0x29 },
HuffmanNode { len: 6, code: 0x2a },
HuffmanNode { len: 5, code: 0x07 },
HuffmanNode { len: 6, code: 0x2b },
HuffmanNode { len: 7, code: 0x76 },
HuffmanNode { len: 6, code: 0x2c },
HuffmanNode { len: 5, code: 0x08 },
HuffmanNode { len: 5, code: 0x09 },
HuffmanNode { len: 6, code: 0x2d },
HuffmanNode { len: 7, code: 0x77 },
HuffmanNode { len: 7, code: 0x78 },
HuffmanNode { len: 7, code: 0x79 },
HuffmanNode { len: 7, code: 0x7a },
HuffmanNode { len: 7, code: 0x7b },
HuffmanNode { len: 15, code: 0x7ffe },
HuffmanNode { len: 11, code: 0x7fc },
HuffmanNode { len: 14, code: 0x3ffd },
HuffmanNode { len: 13, code: 0x1ffd },
HuffmanNode { len: 28, code: 0xffffffc },
HuffmanNode { len: 20, code: 0xfffe6 },
HuffmanNode { len: 22, code: 0x3fffd2 },
HuffmanNode { len: 20, code: 0xfffe7 },
HuffmanNode { len: 20, code: 0xfffe8 },
HuffmanNode { len: 22, code: 0x3fffd3 },
HuffmanNode { len: 22, code: 0x3fffd4 },
HuffmanNode { len: 22, code: 0x3fffd5 },
HuffmanNode { len: 23, code: 0x7fffd9 },
HuffmanNode { len: 22, code: 0x3fffd6 },
HuffmanNode { len: 23, code: 0x7fffda },
HuffmanNode { len: 23, code: 0x7fffdb },
HuffmanNode { len: 23, code: 0x7fffdc },
HuffmanNode { len: 23, code: 0x7fffdd },
HuffmanNode { len: 23, code: 0x7fffde },
HuffmanNode { len: 24, code: 0xffffeb },
HuffmanNode { len: 23, code: 0x7fffdf },
HuffmanNode { len: 24, code: 0xffffec },
HuffmanNode { len: 24, code: 0xffffed },
HuffmanNode { len: 22, code: 0x3fffd7 },
HuffmanNode { len: 23, code: 0x7fffe0 },
HuffmanNode { len: 24, code: 0xffffee },
HuffmanNode { len: 23, code: 0x7fffe1 },
HuffmanNode { len: 23, code: 0x7fffe2 },
HuffmanNode { len: 23, code: 0x7fffe3 },
HuffmanNode { len: 23, code: 0x7fffe4 },
HuffmanNode { len: 21, code: 0x1fffdc },
HuffmanNode { len: 22, code: 0x3fffd8 },
HuffmanNode { len: 23, code: 0x7fffe5 },
HuffmanNode { len: 22, code: 0x3fffd9 },
HuffmanNode { len: 23, code: 0x7fffe6 },
HuffmanNode { len: 23, code: 0x7fffe7 },
HuffmanNode { len: 24, code: 0xffffef },
HuffmanNode { len: 22, code: 0x3fffda },
HuffmanNode { len: 21, code: 0x1fffdd },
HuffmanNode { len: 20, code: 0xfffe9 },
HuffmanNode { len: 22, code: 0x3fffdb },
HuffmanNode { len: 22, code: 0x3fffdc },
HuffmanNode { len: 23, code: 0x7fffe8 },
HuffmanNode { len: 23, code: 0x7fffe9 },
HuffmanNode { len: 21, code: 0x1fffde },
HuffmanNode { len: 23, code: 0x7fffea },
HuffmanNode { len: 22, code: 0x3fffdd },
HuffmanNode { len: 22, code: 0x3fffde },
HuffmanNode { len: 24, code: 0xfffff0 },
HuffmanNode { len: 21, code: 0x1fffdf },
HuffmanNode { len: 22, code: 0x3fffdf },
HuffmanNode { len: 23, code: 0x7fffeb },
HuffmanNode { len: 23, code: 0x7fffec },
HuffmanNode { len: 21, code: 0x1fffe0 },
HuffmanNode { len: 21, code: 0x1fffe1 },
HuffmanNode { len: 22, code: 0x3fffe0 },
HuffmanNode { len: 21, code: 0x1fffe2 },
HuffmanNode { len: 23, code: 0x7fffed },
HuffmanNode { len: 22, code: 0x3fffe1 },
HuffmanNode { len: 23, code: 0x7fffee },
HuffmanNode { len: 23, code: 0x7fffef },
HuffmanNode { len: 20, code: 0xfffea },
HuffmanNode { len: 22, code: 0x3fffe2 },
HuffmanNode { len: 22, code: 0x3fffe3 },
HuffmanNode { len: 22, code: 0x3fffe4 },
HuffmanNode { len: 23, code: 0x7ffff0 },
HuffmanNode { len: 22, code: 0x3fffe5 },
HuffmanNode { len: 22, code: 0x3fffe6 },
HuffmanNode { len: 23, code: 0x7ffff1 },
HuffmanNode { len: 26, code: 0x3ffffe0 },
HuffmanNode { len: 26, code: 0x3ffffe1 },
HuffmanNode { len: 20, code: 0xfffeb },
HuffmanNode { len: 19, code: 0x7fff1 },
HuffmanNode { len: 22, code: 0x3fffe7 },
HuffmanNode { len: 23, code: 0x7ffff2 },
HuffmanNode { len: 22, code: 0x3fffe8 },
HuffmanNode { len: 25, code: 0x1ffffec },
HuffmanNode { len: 26, code: 0x3ffffe2 },
HuffmanNode { len: 26, code: 0x3ffffe3 },
HuffmanNode { len: 26, code: 0x3ffffe4 },
HuffmanNode { len: 27, code: 0x7ffffde },
HuffmanNode { len: 27, code: 0x7ffffdf },
HuffmanNode { len: 26, code: 0x3ffffe5 },
HuffmanNode { len: 24, code: 0xfffff1 },
HuffmanNode { len: 25, code: 0x1ffffed },
HuffmanNode { len: 19, code: 0x7fff2 },
HuffmanNode { len: 21, code: 0x1fffe3 },
HuffmanNode { len: 26, code: 0x3ffffe6 },
HuffmanNode { len: 27, code: 0x7ffffe0 },
HuffmanNode { len: 27, code: 0x7ffffe1 },
HuffmanNode { len: 26, code: 0x3ffffe7 },
HuffmanNode { len: 27, code: 0x7ffffe2 },
HuffmanNode { len: 24, code: 0xfffff2 },
HuffmanNode { len: 21, code: 0x1fffe4 },
HuffmanNode { len: 21, code: 0x1fffe5 },
HuffmanNode { len: 26, code: 0x3ffffe8 },
HuffmanNode { len: 26, code: 0x3ffffe9 },
HuffmanNode { len: 28, code: 0xffffffd },
HuffmanNode { len: 27, code: 0x7ffffe3 },
HuffmanNode { len: 27, code: 0x7ffffe4 },
HuffmanNode { len: 27, code: 0x7ffffe5 },
HuffmanNode { len: 20, code: 0xfffec },
HuffmanNode { len: 24, code: 0xfffff3 },
HuffmanNode { len: 20, code: 0xfffed },
HuffmanNode { len: 21, code: 0x1fffe6 },
HuffmanNode { len: 22, code: 0x3fffe9 },
HuffmanNode { len: 21, code: 0x1fffe7 },
HuffmanNode { len: 21, code: 0x1fffe8 },
HuffmanNode { len: 23, code: 0x7ffff3 },
HuffmanNode { len: 22, code: 0x3fffea },
HuffmanNode { len: 22, code: 0x3fffeb },
HuffmanNode { len: 25, code: 0x1ffffee },
HuffmanNode { len: 25, code: 0x1ffffef },
HuffmanNode { len: 24, code: 0xfffff4 },
HuffmanNode { len: 24, code: 0xfffff5 },
HuffmanNode { len: 26, code: 0x3ffffea },
HuffmanNode { len: 23, code: 0x7ffff4 },
HuffmanNode { len: 26, code: 0x3ffffeb },
HuffmanNode { len: 27, code: 0x7ffffe6 },
HuffmanNode { len: 26, code: 0x3ffffec },
HuffmanNode { len: 26, code: 0x3ffffed },
HuffmanNode { len: 27, code: 0x7ffffe7 },
HuffmanNode { len: 27, code: 0x7ffffe8 },
HuffmanNode { len: 27, code: 0x7ffffe9 },
HuffmanNode { len: 27, code: 0x7ffffea },
HuffmanNode { len: 27, code: 0x7ffffeb },
HuffmanNode { len: 28, code: 0xffffffe },
HuffmanNode { len: 27, code: 0x7ffffec },
HuffmanNode { len: 27, code: 0x7ffffed },
HuffmanNode { len: 27, code: 0x7ffffee },
HuffmanNode { len: 27, code: 0x7ffffef },
HuffmanNode { len: 27, code: 0x7fffff0 },
HuffmanNode { len: 26, code: 0x3ffffee },
HuffmanNode { len: 30, code: 0x3fffffff }
];