libribzip2 0.5.0

a bzip2 library written in pure rust
Documentation
use std::io::Write;

use crate::{
    bitwise::{bitreader::BitReader, bitwriter::convert_to_number},
    {
        bitwise::Bit,
        block::{
            bwt::bwt_inverse::inverse_bwt,
            code_table::ReadDelta,
            crc32::crc32,
            huffman::{reader::ReadSymbols, CodeTable, HuffmanSymbol},
            mtf::inverse_mtf,
            rle::inverse_rle,
            selectors::ReadUnary,
            symbol_map::GetSymbolTable,
            zle::{decode_zle, ZleSymbol},
        },
    },
};

pub fn decode_block(mut reader: impl BitReader, mut writer: impl Write) -> Result<(), ()> {
    let crc = convert_to_number(&reader.read_bits(32).unwrap())
        .try_into()
        .unwrap();
    let _randomized = matches!(reader.read_bits(1)?[..], [Bit::One]);
    let orig_ptr = convert_to_number(&reader.read_bits(24).unwrap());
    let symbols = reader.get_symbol_table().unwrap();
    let num_trees = convert_to_number(&reader.read_bits(3).unwrap());
    let num_selectors = convert_to_number(&reader.read_bits(15).unwrap());
    let selectors = reader.read_unary(num_selectors).unwrap();
    let selectors = inverse_mtf(
        &selectors,
        &(0u8..num_trees as u8).into_iter().collect::<Vec<_>>(),
    );
    let mut trees = vec![];
    for _ in 0..num_trees {
        trees.push(reader.read_delta(symbols.len() + 2).unwrap());
    }
    let mut code_tables = vec![];
    for tree in trees.iter() {
        code_tables.push(CodeTable::<HuffmanSymbol<ZleSymbol>>::from_weights(tree).canonicalize());
    }

    let mut zle_input = vec![];
    for selector in selectors {
        let table = &code_tables[usize::from(selector)];
        zle_input.append(&mut reader.read_symbols(table, 50).unwrap());
    }

    let mtf_input = decode_zle(&zle_input);

    let bwt_input = inverse_mtf(&mtf_input, &symbols);
    let rle_input = inverse_bwt(&bwt_input, orig_ptr);
    let decoded = inverse_rle(&rle_input);
    let computed_crc = crc32(&decoded);
    if computed_crc != crc {
        return Err(());
    }
    writer.write(&decoded).map_err(|_| ())?;
    Ok(())
}

#[cfg(test)]
mod test {}