Skip to main content

arithmetic_coding/
decoder.rs

1//! The [`Decoder`] half of the arithmetic coding library.
2
3use std::{io, ops::Range};
4
5use bitstream_io::BitRead;
6
7use crate::{
8    BitStore, 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 decoder
15///
16/// An arithmetic decoder converts a stream of bytes into a stream of some
17/// output symbol, using a predictive [`Model`].
18#[derive(Debug)]
19pub struct Decoder<M, R>
20where
21    M: Model,
22    R: BitRead,
23{
24    model: M,
25    state: State<M::B, R>,
26}
27
28trait BitReadExt {
29    fn next_bit(&mut self) -> io::Result<Option<bool>>;
30}
31
32impl<R: BitRead> BitReadExt for R {
33    fn next_bit(&mut self) -> io::Result<Option<bool>> {
34        match self.read_bit() {
35            Ok(bit) => Ok(Some(bit)),
36            Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => Ok(None),
37            Err(e) => Err(e),
38        }
39    }
40}
41
42impl<M, R> Decoder<M, R>
43where
44    M: Model,
45    R: BitRead,
46{
47    /// Construct a new [`Decoder`]
48    ///
49    /// The 'precision' of the encoder is maximised, based on the number of bits
50    /// needed to represent the [`Model::denominator`]. 'precision' bits is
51    /// equal to [`u32::BITS`] - [`Model::denominator`] bits.
52    ///
53    /// # Panics
54    ///
55    /// The calculation of the number of bits used for 'precision' is subject to
56    /// the following constraints:
57    ///
58    /// - The total available bits is [`u32::BITS`]
59    /// - The precision must use at least 2 more bits than that needed to
60    ///   represent [`Model::denominator`]
61    ///
62    /// If these constraints cannot be satisfied this method will panic in debug
63    /// builds
64    pub fn new(model: M, input: R) -> Self {
65        let frequency_bits = model.max_denominator().log2() + 1;
66        let precision = M::B::BITS - frequency_bits;
67
68        Self::with_precision(model, input, precision)
69    }
70
71    /// Construct a new [`Decoder`] with a custom precision
72    ///
73    /// # Panics
74    ///
75    /// The calculation of the number of bits used for 'precision' is subject to
76    /// the following constraints:
77    ///
78    /// - The total available bits is [`BitStore::BITS`]
79    /// - The precision must use at least 2 more bits than that needed to
80    ///   represent [`Model::denominator`]
81    ///
82    /// If these constraints cannot be satisfied this method will panic in debug
83    /// builds
84    pub fn with_precision(model: M, input: R, precision: u32) -> Self {
85        let state = State::new(precision, input);
86        Self::with_state(state, model)
87    }
88
89    /// Create a decoder from an existing [`State`] and [`Model`].
90    ///
91    /// This is useful for manually chaining a shared buffer through multiple
92    /// decoders.
93    pub fn with_state(state: State<M::B, R>, model: M) -> Self {
94        #[cfg(debug_assertions)]
95        assert_precision_sufficient::<M>(model.max_denominator(), state.state.precision);
96
97        Self { model, state }
98    }
99
100    /// Return an iterator over the decoded symbols.
101    ///
102    /// The iterator will continue returning symbols until EOF is reached
103    pub const fn decode_all(&'_ mut self) -> DecodeIter<'_, M, R> {
104        DecodeIter { decoder: self }
105    }
106
107    /// Read the next symbol from the stream of bits
108    ///
109    /// This method will return `Ok(None)` when EOF is reached.
110    ///
111    /// # Errors
112    ///
113    /// This method can fail if the underlying [`BitRead`] cannot be read from.
114    #[allow(clippy::missing_panics_doc)]
115    pub fn decode(&mut self) -> io::Result<Option<M::Symbol>> {
116        self.state.initialise()?;
117
118        let denominator = self.model.denominator();
119        debug_assert!(
120            denominator <= self.model.max_denominator(),
121            "denominator is greater than maximum!"
122        );
123        let value = self.state.value(denominator);
124        let symbol = self.model.symbol(value);
125
126        let p = self
127            .model
128            .probability(symbol.as_ref())
129            .expect("this should not be able to fail. Check the implementation of the model.");
130
131        self.state.scale(p, denominator)?;
132        self.model.update(symbol.as_ref());
133
134        Ok(symbol)
135    }
136
137    /// Reuse the internal state of the Decoder with a new model.
138    ///
139    /// Allows for chaining multiple sequences of symbols from a single stream
140    /// of bits
141    pub fn chain<X>(self, model: X) -> Decoder<X, R>
142    where
143        X: Model<B = M::B>,
144    {
145        Decoder::with_state(self.state, model)
146    }
147
148    /// Return the internal model and state of the decoder.
149    pub fn into_inner(self) -> (M, State<M::B, R>) {
150        (self.model, self.state)
151    }
152}
153
154/// The iterator returned by the [`Model::decode_all`] method
155#[allow(missing_debug_implementations)]
156pub struct DecodeIter<'a, M, R>
157where
158    M: Model,
159    R: BitRead,
160{
161    decoder: &'a mut Decoder<M, R>,
162}
163
164impl<M, R> Iterator for DecodeIter<'_, M, R>
165where
166    M: Model,
167    R: BitRead,
168{
169    type Item = io::Result<M::Symbol>;
170
171    fn next(&mut self) -> Option<Self::Item> {
172        self.decoder.decode().transpose()
173    }
174}
175
176/// A convenience struct which stores the internal state of an [`Decoder`].
177#[derive(Debug)]
178pub struct State<B, R>
179where
180    B: BitStore,
181    R: BitRead,
182{
183    #[allow(clippy::struct_field_names)]
184    state: common::State<B>,
185    input: R,
186    x: B,
187    uninitialised: bool,
188}
189
190impl<B, R> State<B, R>
191where
192    B: BitStore,
193    R: BitRead,
194{
195    /// Create a new [`State`] from an input stream of bits with a given
196    /// precision.
197    pub fn new(precision: u32, input: R) -> Self {
198        let state = common::State::new(precision);
199        let x = B::ZERO;
200
201        Self {
202            state,
203            input,
204            x,
205            uninitialised: true,
206        }
207    }
208
209    fn normalise(&mut self) -> io::Result<()> {
210        while self.state.high < self.state.half() || self.state.low >= self.state.half() {
211            if self.state.high < self.state.half() {
212                self.state.high = (self.state.high << 1) + B::ONE;
213                self.state.low <<= 1;
214                self.x <<= 1;
215            } else {
216                // self.low >= self.half()
217                self.state.low = (self.state.low - self.state.half()) << 1;
218                self.state.high = ((self.state.high - self.state.half()) << 1) + B::ONE;
219                self.x = (self.x - self.state.half()) << 1;
220            }
221
222            if self.input.next_bit()? == Some(true) {
223                self.x += B::ONE;
224            }
225        }
226
227        while self.state.low >= self.state.quarter()
228            && self.state.high < (self.state.three_quarter())
229        {
230            self.state.low = (self.state.low - self.state.quarter()) << 1;
231            self.state.high = ((self.state.high - self.state.quarter()) << 1) + B::ONE;
232            self.x = (self.x - self.state.quarter()) << 1;
233
234            if self.input.next_bit()? == Some(true) {
235                self.x += B::ONE;
236            }
237        }
238
239        Ok(())
240    }
241
242    fn scale(&mut self, p: Range<B>, denominator: B) -> io::Result<()> {
243        self.state.scale(p, denominator);
244        self.normalise()
245    }
246
247    fn value(&self, denominator: B) -> B {
248        let range = self.state.high - self.state.low + B::ONE;
249        ((self.x - self.state.low + B::ONE) * denominator - B::ONE) / range
250    }
251
252    fn fill(&mut self) -> io::Result<()> {
253        for _ in 0..self.state.precision {
254            self.x <<= 1;
255            if self.input.next_bit()? == Some(true) {
256                self.x += B::ONE;
257            }
258        }
259        Ok(())
260    }
261
262    fn initialise(&mut self) -> io::Result<()> {
263        if self.uninitialised {
264            self.fill()?;
265            self.uninitialised = false;
266        }
267        Ok(())
268    }
269}