zlib_rs/deflate/algorithm/
mod.rs

1use crate::{
2    deflate::{BlockState, DeflateStream, Strategy},
3    DeflateFlush,
4};
5
6use self::{huff::deflate_huff, rle::deflate_rle, stored::deflate_stored};
7
8mod fast;
9mod huff;
10mod medium;
11mod quick;
12mod rle;
13mod slow;
14mod stored;
15
16#[macro_export]
17macro_rules! flush_block {
18    ($stream:expr, $is_last_block:expr) => {
19        $crate::deflate::flush_block_only($stream, $is_last_block);
20
21        if $stream.avail_out == 0 {
22            return match $is_last_block {
23                true => BlockState::FinishStarted,
24                false => BlockState::NeedMore,
25            };
26        }
27    };
28}
29
30pub fn run(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockState {
31    match stream.state.strategy {
32        _ if stream.state.level == 0 => deflate_stored(stream, flush),
33        Strategy::HuffmanOnly => deflate_huff(stream, flush),
34        Strategy::Rle => deflate_rle(stream, flush),
35        Strategy::Default | Strategy::Filtered | Strategy::Fixed => {
36            (CONFIGURATION_TABLE[stream.state.level as usize].func)(stream, flush)
37        }
38    }
39}
40
41type CompressFunc = fn(&mut DeflateStream, flush: DeflateFlush) -> BlockState;
42
43pub struct Config {
44    pub good_length: u16, /* reduce lazy search above this match length */
45    pub max_lazy: u16,    /* do not perform lazy search above this match length */
46    pub nice_length: u16, /* quit search above this match length */
47    pub max_chain: u16,
48    pub func: CompressFunc,
49}
50
51impl Config {
52    const fn new(
53        good_length: u16,
54        max_lazy: u16,
55        nice_length: u16,
56        max_chain: u16,
57        func: CompressFunc,
58    ) -> Self {
59        Self {
60            good_length,
61            max_lazy,
62            nice_length,
63            max_chain,
64            func,
65        }
66    }
67}
68
69pub const CONFIGURATION_TABLE: [Config; 10] = {
70    [
71        Config::new(0, 0, 0, 0, stored::deflate_stored), // 0 /* store only */
72        Config::new(0, 0, 0, 0, quick::deflate_quick),   // 1
73        Config::new(4, 4, 8, 4, fast::deflate_fast),     // 2 /* max speed, no lazy matches */
74        Config::new(4, 6, 16, 6, medium::deflate_medium), // 3
75        Config::new(4, 12, 32, 24, medium::deflate_medium), // 4 /* lazy matches */
76        Config::new(8, 16, 32, 32, medium::deflate_medium), // 5
77        Config::new(8, 16, 128, 128, medium::deflate_medium), // 6
78        Config::new(8, 32, 128, 256, slow::deflate_slow), // 7
79        Config::new(32, 128, 258, 1024, slow::deflate_slow), // 8
80        Config::new(32, 258, 258, 4096, slow::deflate_slow), // 9 /* max compression */
81    ]
82};