use crate::deflate::deflate_token::{DeflateHuffmanType, DeflateToken, DeflateTokenBlock};
pub struct PreflateStreamInfo {
pub token_count: u32,
pub literal_count: u32,
pub reference_count: u32,
pub max_dist: u32,
pub min_len: u32,
pub max_tokens_per_block: u32,
pub count_blocks: u32,
pub count_stored_blocks: u32,
pub count_huff_blocks: u32,
pub count_rle_blocks: u32,
pub count_static_huff_tree_blocks: u32,
pub max_dist_3_matches: u32,
}
fn process_tokens(tokens: &[DeflateToken], result: &mut PreflateStreamInfo) {
result.token_count += tokens.len() as u32;
result.max_tokens_per_block = std::cmp::max(result.max_tokens_per_block, tokens.len() as u32);
let mut block_max_dist = 0;
let mut block_min_len = u32::MAX;
for j in 0..tokens.len() {
match &tokens[j] {
DeflateToken::Literal(_) => {
result.literal_count += 1;
}
DeflateToken::Reference(t) => {
result.reference_count += 1;
block_max_dist = std::cmp::max(block_max_dist, t.dist());
block_min_len = std::cmp::min(block_min_len, t.len());
if t.len() == 3 {
result.max_dist_3_matches = std::cmp::max(result.max_dist_3_matches, t.dist());
}
}
}
}
result.max_dist = std::cmp::max(result.max_dist, block_max_dist);
result.min_len = std::cmp::min(result.min_len, block_min_len);
if block_max_dist == 0 {
result.count_huff_blocks += 1;
} else if block_max_dist == 1 {
result.count_rle_blocks += 1;
}
}
pub(crate) fn extract_preflate_info(blocks: &[DeflateTokenBlock]) -> PreflateStreamInfo {
let mut result: PreflateStreamInfo = PreflateStreamInfo {
count_blocks: blocks.len() as u32,
count_stored_blocks: 0,
count_static_huff_tree_blocks: 0,
token_count: 0,
max_tokens_per_block: 0,
literal_count: 0,
reference_count: 0,
min_len: u32::MAX,
max_dist: 0,
count_huff_blocks: 0,
count_rle_blocks: 0,
max_dist_3_matches: 0,
};
for i in 0..blocks.len() {
match &blocks[i] {
DeflateTokenBlock::Stored { .. } => {
result.count_stored_blocks += 1;
}
DeflateTokenBlock::Huffman {
tokens,
huffman_type,
} => {
if let DeflateHuffmanType::Static { .. } = huffman_type {
result.count_static_huff_tree_blocks += 1;
}
process_tokens(&tokens, &mut result);
}
}
}
result
}