arithmetic_coding/encoder.rs
1//! The [`Encoder`] half of the arithmetic coding library.
2
3use std::{io, ops::Range};
4
5use bitstream_io::BitWrite;
6
7use crate::{
8 BitStore, Error, Model,
9 common::{self, assert_precision_sufficient},
10};
11
12// this algorithm is derived from this article - https://marknelson.us/posts/2014/10/19/data-compression-with-arithmetic-coding.html
13
14/// An arithmetic encoder
15///
16/// An arithmetic decoder converts a stream of symbols into a stream of bits,
17/// using a predictive [`Model`].
18#[derive(Debug)]
19pub struct Encoder<M, W>
20where
21 M: Model,
22 W: BitWrite,
23{
24 model: M,
25 state: State<M::B, W>,
26}
27
28impl<M, W> Encoder<M, W>
29where
30 M: Model,
31 W: BitWrite,
32{
33 /// Construct a new [`Encoder`].
34 ///
35 /// The 'precision' of the encoder is maximised, based on the number of bits
36 /// needed to represent the [`Model::denominator`]. 'precision' bits is
37 /// equal to [`BitStore::BITS`] - [`Model::denominator`] bits. If you need
38 /// to set the precision manually, use [`Encoder::with_precision`].
39 ///
40 /// # Panics
41 ///
42 /// The calculation of the number of bits used for 'precision' is subject to
43 /// the following constraints:
44 ///
45 /// - The total available bits is [`BitStore::BITS`]
46 /// - The precision must use at least 2 more bits than that needed to
47 /// represent [`Model::denominator`]
48 ///
49 /// If these constraints cannot be satisfied this method will panic in debug
50 /// builds
51 pub fn new(model: M, bitwriter: W) -> Self {
52 let frequency_bits = model.max_denominator().log2() + 1;
53 let precision = M::B::BITS - frequency_bits;
54 Self::with_precision(model, bitwriter, precision)
55 }
56
57 /// Construct a new [`Encoder`] with a custom precision.
58 ///
59 /// # Panics
60 ///
61 /// The calculation of the number of bits used for 'precision' is subject to
62 /// the following constraints:
63 ///
64 /// - The total available bits is [`BitStore::BITS`]
65 /// - The precision must use at least 2 more bits than that needed to
66 /// represent [`Model::denominator`]
67 ///
68 /// If these constraints cannot be satisfied this method will panic in debug
69 /// builds
70 pub fn with_precision(model: M, bitwriter: W, precision: u32) -> Self {
71 let state = State::new(precision, bitwriter);
72 Self::with_state(state, model)
73 }
74
75 /// Create an encoder from an existing [`State`].
76 ///
77 /// This is useful for manually chaining a shared buffer through multiple
78 /// encoders.
79 pub fn with_state(state: State<M::B, W>, model: M) -> Self {
80 #[cfg(debug_assertions)]
81 assert_precision_sufficient::<M>(model.max_denominator(), state.state.precision);
82 Self { model, state }
83 }
84
85 /// Encode a stream of symbols into the provided output.
86 ///
87 /// This method will encode all the symbols in the iterator, followed by EOF
88 /// (`None`), and then call [`Encoder::flush`].
89 ///
90 /// # Errors
91 ///
92 /// This method can fail if the underlying [`BitWrite`] cannot be written
93 /// to.
94 pub fn encode_all(
95 mut self,
96 symbols: impl IntoIterator<Item = M::Symbol>,
97 ) -> Result<(), Error<M::ValueError>> {
98 for symbol in symbols {
99 self.encode(Some(&symbol))?;
100 }
101 self.encode(None)?;
102 self.flush()?;
103 Ok(())
104 }
105
106 /// Encode a symbol into the provided output.
107 ///
108 /// When you finish encoding symbols, you must manually encode an EOF symbol
109 /// by calling [`Encoder::encode`] with `None`.
110 ///
111 /// The internal buffer must be manually flushed using [`Encoder::flush`].
112 ///
113 /// # Errors
114 ///
115 /// This method can fail if the underlying [`BitWrite`] cannot be written
116 /// to.
117 pub fn encode(&mut self, symbol: Option<&M::Symbol>) -> Result<(), Error<M::ValueError>> {
118 let p = self.model.probability(symbol).map_err(Error::ValueError)?;
119 let denominator = self.model.denominator();
120 debug_assert!(
121 denominator <= self.model.max_denominator(),
122 "denominator is greater than maximum!"
123 );
124
125 self.state.scale(p, denominator)?;
126 self.model.update(symbol);
127
128 Ok(())
129 }
130
131 /// Flush any pending bits from the buffer
132 ///
133 /// This method must be called when you finish writing symbols to a stream
134 /// of bits. This is called automatically when you use
135 /// [`Encoder::encode_all`].
136 ///
137 /// # Errors
138 ///
139 /// This method can fail if the underlying [`BitWrite`] cannot be written
140 /// to.
141 pub fn flush(self) -> io::Result<()> {
142 self.state.flush()
143 }
144
145 /// Return the internal model and state of the encoder.
146 pub fn into_inner(self) -> (M, State<M::B, W>) {
147 (self.model, self.state)
148 }
149
150 /// Reuse the internal state of the Encoder with a new model.
151 ///
152 /// Allows for chaining multiple sequences of symbols into a single stream
153 /// of bits
154 pub fn chain<X>(self, model: X) -> Encoder<X, W>
155 where
156 X: Model<B = M::B>,
157 {
158 Encoder::with_state(self.state, model)
159 }
160}
161
162/// A convenience struct which stores the internal state of an [`Encoder`].
163#[derive(Debug)]
164pub struct State<B, W>
165where
166 B: BitStore,
167 W: BitWrite,
168{
169 #[allow(clippy::struct_field_names)]
170 state: common::State<B>,
171 pending: u32,
172 output: W,
173}
174
175impl<B, W> State<B, W>
176where
177 B: BitStore,
178 W: BitWrite,
179{
180 /// Manually construct a [`State`].
181 ///
182 /// Normally this would be done automatically using the [`Encoder::new`]
183 /// method.
184 pub fn new(precision: u32, output: W) -> Self {
185 let state = common::State::new(precision);
186 let pending = 0;
187
188 Self {
189 state,
190 pending,
191 output,
192 }
193 }
194
195 fn scale(&mut self, p: Range<B>, denominator: B) -> io::Result<()> {
196 self.state.scale(p, denominator);
197 self.normalise()
198 }
199
200 fn normalise(&mut self) -> io::Result<()> {
201 while self.state.high < self.state.half() || self.state.low >= self.state.half() {
202 if self.state.high < self.state.half() {
203 self.emit(false)?;
204 self.state.high = (self.state.high << 1) + B::ONE;
205 self.state.low <<= 1;
206 } else {
207 self.emit(true)?;
208 self.state.low = (self.state.low - self.state.half()) << 1;
209 self.state.high = ((self.state.high - self.state.half()) << 1) + B::ONE;
210 }
211 }
212
213 while self.state.low >= self.state.quarter()
214 && self.state.high < (self.state.three_quarter())
215 {
216 self.pending += 1;
217 self.state.low = (self.state.low - self.state.quarter()) << 1;
218 self.state.high = ((self.state.high - self.state.quarter()) << 1) + B::ONE;
219 }
220
221 Ok(())
222 }
223
224 fn emit(&mut self, bit: bool) -> io::Result<()> {
225 self.output.write_bit(bit)?;
226 for _ in 0..self.pending {
227 self.output.write_bit(!bit)?;
228 }
229 self.pending = 0;
230 Ok(())
231 }
232
233 /// Flush the internal buffer and write all remaining bits to the output.
234 /// This method MUST be called when you finish writing symbols to ensure
235 /// they are fully written to the output.
236 ///
237 /// # Errors
238 ///
239 /// This method can fail if the output cannot be written to
240 pub fn flush(mut self) -> io::Result<()> {
241 self.pending += 1;
242 if self.state.low <= self.state.quarter() {
243 self.emit(false)?;
244 } else {
245 self.emit(true)?;
246 }
247
248 Ok(())
249 }
250}