arithmetic_coding_core/model.rs
1use std::{error::Error, ops::Range};
2
3use crate::BitStore;
4
5pub mod fixed_length;
6pub mod max_length;
7pub mod one_shot;
8
9/// A [`Model`] is used to calculate the probability of a given symbol occuring
10/// in a sequence. The [`Model`] is used both for encoding and decoding.
11///
12/// The more accurately a [`Model`] is able to predict the next symbol, the
13/// greater the compression ratio will be.
14///
15/// # Example
16///
17/// ```
18/// # use std::convert::Infallible;
19/// use std::ops::Range;
20/// #
21/// # use arithmetic_coding_core::Model;
22///
23/// pub enum Symbol {
24/// A,
25/// B,
26/// C,
27/// }
28///
29/// pub struct MyModel;
30///
31/// impl Model for MyModel {
32/// type B = u32;
33/// type Symbol = Symbol;
34/// type ValueError = Infallible;
35///
36/// fn probability(&self, symbol: Option<&Self::Symbol>) -> Result<Range<u32>, Infallible> {
37/// Ok(match symbol {
38/// None => 0..1,
39/// Some(&Symbol::A) => 1..2,
40/// Some(&Symbol::B) => 2..3,
41/// Some(&Symbol::C) => 3..4,
42/// })
43/// }
44///
45/// fn symbol(&self, value: Self::B) -> Option<Self::Symbol> {
46/// match value {
47/// 0..1 => None,
48/// 1..2 => Some(Symbol::A),
49/// 2..3 => Some(Symbol::B),
50/// 3..4 => Some(Symbol::C),
51/// _ => unreachable!(),
52/// }
53/// }
54///
55/// fn max_denominator(&self) -> u32 {
56/// 4
57/// }
58/// }
59/// ```
60pub trait Model {
61 /// The type of symbol this [`Model`] describes
62 type Symbol;
63
64 /// Invalid symbol error
65 type ValueError: Error;
66
67 /// The internal representation to use for storing integers
68 type B: BitStore;
69
70 /// Given a symbol, return an interval representing the probability of that
71 /// symbol occurring.
72 ///
73 /// This is given as a range, over the denominator given by
74 /// [`Model::denominator`]. This range should in general include `EOF`,
75 /// which is denoted by `None`.
76 ///
77 /// For example, from the set {heads, tails}, the interval representing
78 /// heads could be `0..1`, and tails would be `1..2`, and `EOF` could be
79 /// `2..3` (with a denominator of `3`).
80 ///
81 /// This is the inverse of the [`Model::symbol`] method
82 ///
83 /// # Errors
84 ///
85 /// This returns a custom error if the given symbol is not valid
86 fn probability(
87 &self,
88 symbol: Option<&Self::Symbol>,
89 ) -> Result<Range<Self::B>, Self::ValueError>;
90
91 /// The denominator for probability ranges. See [`Model::probability`].
92 ///
93 /// By default this method simply returns the [`Model::max_denominator`],
94 /// which is suitable for non-adaptive models.
95 ///
96 /// In adaptive models this value may change, however it should never exceed
97 /// [`Model::max_denominator`], or it becomes possible for the
98 /// [`Encoder`](crate::Encoder) and [`Decoder`](crate::Decoder) to panic due
99 /// to overflow or underflow.
100 fn denominator(&self) -> Self::B {
101 self.max_denominator()
102 }
103
104 /// The maximum denominator used for probability ranges. See
105 /// [`Model::probability`].
106 ///
107 /// This value is used to calculate an appropriate precision for the
108 /// encoding, therefore this value must not change, and
109 /// [`Model::denominator`] must never exceed it.
110 fn max_denominator(&self) -> Self::B;
111
112 /// Given a value, return the symbol whose probability range it falls in.
113 ///
114 /// `None` indicates `EOF`
115 ///
116 /// This is the inverse of the [`Model::probability`] method
117 fn symbol(&self, value: Self::B) -> Option<Self::Symbol>;
118
119 /// Update the current state of the model with the latest symbol.
120 ///
121 /// This method only needs to be implemented for 'adaptive' models. It's a
122 /// no-op by default.
123 fn update(&mut self, _symbol: Option<&Self::Symbol>) {}
124}