1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
mod adaptive_linear;
mod adaptive_tree;
#[cfg(test)]
mod tests;
use super::Error;
use super::Result;
pub use self::adaptive_linear::AdaptiveLinearModel;
pub use self::adaptive_tree::AdaptiveTreeModel;
pub trait Model {
fn parameters<'a>(&'a self) -> &'a Parameters;
fn total_frequency(&self) -> u64;
fn get_frequency(&mut self, symbol: usize) -> Result<(u64, u64)>;
fn get_symbol(&mut self, value: u64) -> Result<(usize, u64, u64)>;
#[cfg(debug_assertions)]
fn get_freq_table(&self) -> Vec<(u64, u64)>;
}
#[derive(Clone)]
pub struct Parameters {
pub symbol_bits: usize,
pub symbol_eof: usize,
pub symbol_count: usize,
pub freq_bits: usize,
pub freq_max: u64,
pub code_bits: usize,
pub code_min: u64,
pub code_one_fourth: u64,
pub code_half: u64,
pub code_three_fourths: u64,
pub code_max: u64,
}
impl Parameters {
pub fn new(symbol: usize, frequency: usize, code: usize) -> Result<Parameters> {
if symbol < 1 || frequency < symbol + 2 || code < frequency + 2 || 64 < code + frequency {
Err(Error::InvalidInput)
} else {
Ok(Parameters {
symbol_bits: symbol,
symbol_eof: 1 << symbol,
symbol_count: (1 << symbol) + 1,
freq_bits: frequency,
freq_max: (1 << frequency) - 1,
code_bits: code,
code_min: 0,
code_one_fourth: 1 << (code - 2),
code_half: 2 << (code - 2),
code_three_fourths: 3 << (code - 2),
code_max: (1 << code) - 1,
})
}
}
}