use alloc::vec::Vec;
use super::block_split::BlockSplit;
use super::constants::{NUM_COMMAND_SYMBOLS, NUM_LITERAL_SYMBOLS};
use super::histogram::{
HistogramCommand, HistogramDistance, HistogramLiteral, optimize_huffman_counts_for_rle,
};
pub(crate) const LITERAL_CONTEXT_BITS: usize = 6;
pub(crate) const DISTANCE_CONTEXT_BITS: usize = 2;
#[derive(Default)]
pub(crate) struct MetaBlockSplit {
pub(crate) literal_split: BlockSplit,
pub(crate) command_split: BlockSplit,
pub(crate) distance_split: BlockSplit,
pub(crate) literal_context_map: Vec<u32>,
pub(crate) distance_context_map: Vec<u32>,
pub(crate) literal_histograms: Vec<HistogramLiteral>,
pub(crate) command_histograms: Vec<HistogramCommand>,
pub(crate) distance_histograms: Vec<HistogramDistance>,
}
impl MetaBlockSplit {
pub(crate) fn clear(&mut self) {
for split in [
&mut self.literal_split,
&mut self.command_split,
&mut self.distance_split,
] {
split.num_types = 0;
split.num_blocks = 0;
split.types.clear();
split.lengths.clear();
}
self.literal_context_map.clear();
self.distance_context_map.clear();
self.literal_histograms.clear();
self.command_histograms.clear();
self.distance_histograms.clear();
}
pub(crate) fn retained_bytes(&self) -> usize {
let splits = [
&self.literal_split,
&self.command_split,
&self.distance_split,
];
splits
.iter()
.map(|split| split.types.capacity() + split.lengths.capacity() * size_of::<u32>())
.sum::<usize>()
+ (self.literal_context_map.capacity() + self.distance_context_map.capacity())
* size_of::<u32>()
+ self.literal_histograms.capacity() * size_of::<HistogramLiteral>()
+ self.command_histograms.capacity() * size_of::<HistogramCommand>()
+ self.distance_histograms.capacity() * size_of::<HistogramDistance>()
}
}
pub(crate) fn optimize_histograms(num_distance_codes: usize, mb: &mut MetaBlockSplit) {
let mut good_for_rle = [0u8; NUM_COMMAND_SYMBOLS];
for histogram in &mut mb.literal_histograms {
optimize_huffman_counts_for_rle(
NUM_LITERAL_SYMBOLS,
&mut histogram.data,
&mut good_for_rle,
);
}
for histogram in &mut mb.command_histograms {
optimize_huffman_counts_for_rle(
NUM_COMMAND_SYMBOLS,
&mut histogram.data,
&mut good_for_rle,
);
}
for histogram in &mut mb.distance_histograms {
optimize_huffman_counts_for_rle(num_distance_codes, &mut histogram.data, &mut good_for_rle);
}
}