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}