redux/model/mod.rs
1//! Symbol frequency distribution models.
2
3mod adaptive_linear;
4mod adaptive_tree;
5#[cfg(test)]
6mod tests;
7
8use super::Error;
9use super::Result;
10
11pub use self::adaptive_linear::AdaptiveLinearModel;
12pub use self::adaptive_tree::AdaptiveTreeModel;
13
14/// Trait for the probability models behind arithmetic coding.
15/// Possible implementations may include static models with fixed probabilities
16/// or and adaptive model that continuously updates cumulative frequencies.
17pub trait Model {
18 /// Returns the arithmetic compression parameters.
19 fn parameters<'a>(&'a self) -> &'a Parameters;
20 /// Returns the maximum cumulative frequency.
21 fn total_frequency(&self) -> u64;
22 /// Returns the cumulative frequency range for the given input symbol.
23 fn get_frequency(&mut self, symbol: usize) -> Result<(u64, u64)>;
24 /// Returns the symbol that corresponds to the given cumulative frequency.
25 fn get_symbol(&mut self, value: u64) -> Result<(usize, u64, u64)>;
26 /// Returns the cumulative frequency table for debugging purposes.
27 #[cfg(debug_assertions)]
28 fn get_freq_table(&self) -> Vec<(u64, u64)>;
29}
30
31/// Model parameters that specifies the common property of the models.
32#[derive(Clone)]
33pub struct Parameters {
34 /// Bit width of the symbols being encoded.
35 /// Usually 8 for byte oriented inputs.
36 pub symbol_bits: usize,
37 /// Code for the EOF symbol.
38 /// This is the next symbol code after the valid symbols to encode.
39 pub symbol_eof: usize,
40 /// Number of possible symbols including the EOF symbol.
41 pub symbol_count: usize,
42 /// Number of bits representing symbol frequencies.
43 pub freq_bits: usize,
44 /// Maximum cumulated frequency value for symbols.
45 pub freq_max: u64,
46 /// Number of bits representing the current code ranges.
47 pub code_bits: usize,
48 /// Minimum value for code range.
49 /// This is always zero.
50 pub code_min: u64,
51 /// Delimiter for the one fourth of the valid code range.
52 pub code_one_fourth: u64,
53 /// Delimiter for the half of the valid code range.
54 pub code_half: u64,
55 /// Delimiter for the three fourths of the valid code range.
56 pub code_three_fourths: u64,
57 /// Upper limit of the valid code range.
58 pub code_max: u64,
59}
60
61impl Parameters {
62 /// Calculates all parameter values based on the `symbol`, `frequency` and `code` width.
63 pub fn new(symbol: usize, frequency: usize, code: usize) -> Result<Parameters> {
64 if symbol < 1 || frequency < symbol + 2 || code < frequency + 2 || 64 < code + frequency {
65 Err(Error::InvalidInput)
66 } else {
67 Ok(Parameters {
68 symbol_bits: symbol,
69 symbol_eof: 1 << symbol,
70 symbol_count: (1 << symbol) + 1,
71 freq_bits: frequency,
72 freq_max: (1 << frequency) - 1,
73 code_bits: code,
74 code_min: 0,
75 code_one_fourth: 1 << (code - 2),
76 code_half: 2 << (code - 2),
77 code_three_fourths: 3 << (code - 2),
78 code_max: (1 << code) - 1,
79 })
80 }
81 }
82}