lzfse_rust 0.1.0

A pure Rust LZFSE library.
Documentation
use std::mem;
use std::ops::Range;

// Fixed constants. Do NOT change.
//
// Alterations may:
// * break guarantees relied upon by unsafe code.
// * break functionality.
// * break compatibility.
// * break security.
// * open Pandora's box.
//
// NB:
// L = literal_length
// M = match length
// D = match distance
// U = literal bytes (u8)
//
// V1 = version 1 header, with uncompressed weight tables (obsolete).
// V2 = version 2 header, with compressed weight tables.

pub const LMDS_PER_BLOCK: u32 = 10000;
pub const LITERALS_PER_BLOCK: u32 = 4 * LMDS_PER_BLOCK;

pub const L_SYMBOLS: u32 = 20;
pub const M_SYMBOLS: u32 = 20;
pub const D_SYMBOLS: u32 = 64;
pub const U_SYMBOLS: u32 = 256;

pub const MAX_L_BITS: u32 = 14;
pub const MAX_M_BITS: u32 = 17;
pub const MAX_D_BITS: u32 = 23;
pub const MAX_U_BITS: u32 = 10;

pub const L_STATES: u32 = 64;
pub const M_STATES: u32 = 64;
pub const D_STATES: u32 = 256;
pub const U_STATES: u32 = 1024;

pub const MAX_L_VALUE: u16 = 315;
pub const MAX_M_VALUE: u16 = 2_359;
pub const MAX_D_VALUE: u32 = 262_139;

pub const L_TOP: usize = L_SYMBOLS as usize;
pub const M_TOP: usize = L_TOP + M_SYMBOLS as usize;
pub const D_TOP: usize = M_TOP + D_SYMBOLS as usize;
pub const U_TOP: usize = D_TOP + U_SYMBOLS as usize;

pub const L_RANGE: Range<usize> = 0..L_TOP;
pub const M_RANGE: Range<usize> = L_TOP..M_TOP;
pub const D_RANGE: Range<usize> = M_TOP..D_TOP;
pub const U_RANGE: Range<usize> = D_TOP..U_TOP;

pub const V1_HEADER_SIZE: u32 = 0x32;
pub const V2_HEADER_SIZE: u32 = 0x20;

pub const N_WEIGHTS: usize = U_TOP;
pub const V1_WEIGHT_PAYLOAD_BYTES: u32 = N_WEIGHTS as u32 * mem::size_of::<u16>() as u32 + 2;
pub const V2_WEIGHT_PAYLOAD_BYTES_MAX: u32 = (N_WEIGHTS as u32 * MAX_W_BITS as u32 + 7) / 8;

pub const MAX_LMD_BITS: u32 = MAX_L_BITS + MAX_M_BITS + MAX_D_BITS;
pub const MAX_LMD_PAYLOAD: u32 = (MAX_LMD_BITS * LMDS_PER_BLOCK + 7) / 8 + 8;
pub const MAX_LITERAL_PAYLOAD: u32 = (MAX_U_BITS * LITERALS_PER_BLOCK + 7) / 8;

pub const V1_MAX_BLOCK_LEN: u32 =
    V1_HEADER_SIZE + V1_WEIGHT_PAYLOAD_BYTES + MAX_LITERAL_PAYLOAD + MAX_LMD_PAYLOAD;

pub const V2_MAX_BLOCK_LEN: u32 =
    V2_HEADER_SIZE + V2_WEIGHT_PAYLOAD_BYTES_MAX + MAX_LITERAL_PAYLOAD + MAX_LMD_PAYLOAD;

// Weights are encoded using Huffman type codes that represent an immediate or constructed value.
//
// The encodable weight range is 0..=1047.
//
// Index       Coding  Value
// 0               00  0
// 1              001  2
// 2               10  1
// 3            00011  4
// 4               00  0
// 5              101  3
// 6               10  1
// 7         XXXX0111  A*
// 8               00  0
// 9              001  2
// 10              10  1
// 11           01011  5
// 12              00  0
// 13             101  3
// 14              10  1
// 15 XXXXXX_XXXX1111  B*
// 16              00  0
// 17             001  2
// 18              10  1
// 19           10011  6
// 20              00  0
// 21             101  3
// 22              10  1
// 23        XXXX0111  A*
// 24              00  0
// 25             001  2
// 26              10  1
// 27           11011  7
// 28              00  0
// 29             101  3
// 30              10  1
// 31 XXXXXX_XXXX1111  B*
//
// *A  8 bit constructed value
// *B 14 bit constructed value

pub const MAX_W_BITS: usize = 14;

#[rustfmt::skip]
pub const WEIGHTS_BITS_TABLE: [u8; 32] = [
    2, 3, 2, 5, 2, 3, 2, 8, 2, 3, 2, 5, 2, 3, 2, 14,
    2, 3, 2, 5, 2, 3, 2, 8, 2, 3, 2, 5, 2, 3, 2, 14
];

#[rustfmt::skip]
pub const WEIGHTS_VALUE_TABLE: [i8; 32] = [
    0, 2, 1, 4, 0, 3, 1, -1, 0, 2, 1, 5, 0, 3, 1, -1,
    0, 2, 1, 6, 0, 3, 1, -1, 0, 2, 1, 7, 0, 3, 1, -1
];

#[rustfmt::skip]
pub const L_EXTRA_BITS: [u8; L_SYMBOLS as usize] = [
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 8
];

#[rustfmt::skip]
pub const L_BASE_VALUE: [u32; L_SYMBOLS as usize] = [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 28, 60
];

#[rustfmt::skip]
pub const L_BASE_FROM_VALUE: [u8; MAX_L_VALUE as usize + 1] = [
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 16,
    16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19
];

#[rustfmt::skip]
pub const M_EXTRA_BITS: [u8; M_SYMBOLS as usize] = [
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11
];

#[rustfmt::skip]
pub const M_BASE_VALUE: [u32; M_SYMBOLS as usize] = [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 24, 56, 312
];

#[rustfmt::skip]
pub const M_BASE_FROM_VALUE: [u8; MAX_M_VALUE as usize + 1] = [
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 16,
    16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
    18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
    19, 19
];

#[rustfmt::skip]
pub const D_EXTRA_BITS: [u8; D_SYMBOLS as usize] = [
    0,  0,  0,  0,  1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,
    4,  4,  4,  4,  5,  5,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,
    8,  8,  8,  8,  9,  9,  9,  9,  10, 10, 10, 10, 11, 11, 11, 11,
    12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15
];

#[rustfmt::skip]
pub const D_BASE_VALUE: [u32; D_SYMBOLS as usize] = [
    0,       1,       2,       3,      4,      6,      8,      10,     12,     16,
    20,      24,      28,      36,     44,     52,     60,     76,     92,     108,
    124,     156,     188,     220,    252,    316,    380,    444,    508,    636,
    764,     892,     1020,    1276,   1532,   1788,   2044,   2556,   3068,   3580,
    4092,    5116,    6140,    7164,   8188,   10236,  12284,  14332,  16380,  20476,
    24572,   28668,   32764,   40956,  49148,  57340,  65532,  81916,  98300,  114_684,
    131_068, 163_836, 196_604, 229_372
];

#[rustfmt::skip]
pub const D_BASE_FROM_VALUE: [u8; 256] = [
    0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  8,  8,  9,  9,
    9,  9,  10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12,
    13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15,
    15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17, 18, 19, 20, 20, 21, 21,
    22, 22, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27,
    27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29,
    30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32,
    32, 32, 32, 33, 34, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 40, 40,
    41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44,
    44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46,
    47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 50, 51, 52, 52,
    53, 53, 54, 54, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58,
    59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61,
    61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63,
    0,  0,  0,  0
];

#[inline(always)]
pub fn d_index(v: usize) -> usize {
    debug_assert!(v <= MAX_D_VALUE as usize);
    let i = match v {
        v if v < 60 => v,
        v if v < 1_020 => ((v - 60) >> 4) + 64,
        v if v < 16_380 => ((v - 1_020) >> 8) + 128,
        _ => ((v - 16_380) >> 12) + 192,
    };
    debug_assert!(i < 256);
    i
}

/// Branchless alternative.
#[allow(dead_code)]
#[allow(clippy::manual_range_contains)]
fn d_index_alt(v: usize) -> usize {
    debug_assert!(v <= MAX_D_VALUE as usize);
    let v = v as isize;
    let mut i = 0;
    let mut k;
    k = (v < 60) as isize;
    i |= v & -k;
    k = (v >= 60 && v < 10_20) as isize;
    i |= (((v - 60) >> 4) + 64) & -k;
    k = (v >= 1_020 && v < 16_380) as isize;
    i |= (((v - 1020) >> 8) + 128) & -k;
    k = (v >= 16_380 && v < 262_140) as isize;
    i |= (((v - 16_380) >> 12) + 192) & -k;
    debug_assert!(i < 256);
    i as usize
}

#[cfg(test)]
mod tests {
    use super::*;

    // The LZFSE tables and associated constants are precisely constructed. Although we've taken
    // them verbatim from the LZFSE reference we still test them to satisfy ourselves that they are
    // correct. In particular, unsafe code relies on the fact that constant limits are correct and
    // that encoded/ decoded states/ values cannot violate their intended bounds.
    //
    // See the individual test code for details.

    #[allow(clippy::assertions_on_constants)]
    #[test]
    fn screen_l_items() {
        assert!(L_STATES <= 1024);
        assert!(L_STATES >= L_SYMBOLS);
        assert!(L_STATES.is_power_of_two());
        assert_eq!(L_EXTRA_BITS.len(), L_SYMBOLS as usize);
        assert_eq!(L_BASE_VALUE.len(), L_SYMBOLS as usize);
        assert_eq!(L_BASE_FROM_VALUE.len(), MAX_L_VALUE as usize + 1);
        let mut base_value = 0;
        let mut extra_bits = 0;
        for i in 0..L_SYMBOLS as usize {
            extra_bits = L_EXTRA_BITS[i] as usize;
            assert_eq!(L_BASE_VALUE[i] as usize, base_value);
            let n = 1 << extra_bits;
            for j in 0..n {
                assert_eq!(L_BASE_FROM_VALUE[base_value + j] as usize, i);
            }
            base_value += n;
        }
        assert_eq!(MAX_L_VALUE as usize, base_value - 1);
        let state_bits = L_STATES.trailing_zeros() as usize;
        assert_eq!(MAX_L_BITS as usize, extra_bits + state_bits);
    }

    #[allow(clippy::assertions_on_constants)]
    #[test]
    fn screen_m_items() {
        assert!(M_STATES <= 1024);
        assert!(M_STATES >= M_SYMBOLS);
        assert!(M_STATES.is_power_of_two());
        assert_eq!(M_EXTRA_BITS.len(), M_SYMBOLS as usize);
        assert_eq!(M_BASE_VALUE.len(), M_SYMBOLS as usize);
        assert_eq!(M_BASE_FROM_VALUE.len(), MAX_M_VALUE as usize + 1);
        let mut base_value = 0;
        let mut extra_bits = 0;
        for i in 0..M_SYMBOLS as usize {
            extra_bits = M_EXTRA_BITS[i] as usize;
            assert_eq!(M_BASE_VALUE[i] as usize, base_value);
            let n = 1 << extra_bits;
            for j in 0..n {
                assert_eq!(M_BASE_FROM_VALUE[base_value + j] as usize, i);
            }
            base_value += n;
        }
        assert_eq!(MAX_M_VALUE as usize, base_value - 1);
        let state_bits = M_STATES.trailing_zeros() as usize;
        assert_eq!(MAX_M_BITS as usize, extra_bits + state_bits);
    }

    #[allow(clippy::assertions_on_constants)]
    #[test]
    fn screen_d_items() {
        assert!(D_STATES <= 1024);
        assert!(D_STATES >= D_SYMBOLS);
        assert!(D_STATES.is_power_of_two());
        assert_eq!(D_EXTRA_BITS.len(), D_SYMBOLS as usize);
        assert_eq!(D_BASE_VALUE.len(), D_SYMBOLS as usize);
        assert_eq!(D_BASE_FROM_VALUE.len(), 256);
        let mut base_value = 0;
        let mut extra_bits = 0;
        for i in 0..D_SYMBOLS as usize {
            extra_bits = D_EXTRA_BITS[i] as usize;
            assert_eq!(D_BASE_VALUE[i] as usize, base_value);
            let n = 1 << extra_bits;
            for j in 0..n {
                let index = d_index(base_value + j);
                assert_eq!(D_BASE_FROM_VALUE[index] as usize, i);
            }
            base_value += n;
        }
        assert_eq!(MAX_D_VALUE as usize, base_value - 1);
        let state_bits = D_STATES.trailing_zeros() as usize;
        assert_eq!(MAX_D_BITS as usize, extra_bits + state_bits);
    }

    #[allow(clippy::assertions_on_constants)]
    #[test]
    fn screen_u_items() {
        assert_eq!(U_SYMBOLS, 256);
        assert!(U_STATES <= 1024);
        assert!(U_STATES >= U_SYMBOLS);
        assert!(U_STATES.is_power_of_two());
        let state_bits = U_STATES.trailing_zeros() as usize;
        assert_eq!(MAX_U_BITS as usize, state_bits);
    }

    #[allow(clippy::needless_range_loop)]
    #[test]
    fn screen_w_items() {
        assert_eq!(WEIGHTS_BITS_TABLE.len(), 32);
        assert_eq!(WEIGHTS_VALUE_TABLE.len(), 32);
        let mut max_bits = 0;
        for i in 0..32 {
            let bits = WEIGHTS_BITS_TABLE[i] as usize;
            assert!(bits < 16);
            assert!(WEIGHTS_VALUE_TABLE[bits] != -1);
            max_bits = max_bits.max(bits);
        }
        assert_eq!(MAX_W_BITS, max_bits);
    }

    #[test]
    fn d_index_d_index_alt_consistency() {
        for i in 0..=MAX_D_VALUE {
            assert_eq!(d_index(i as usize), d_index_alt(i as usize));
        }
    }
}