Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion arithmetic-coding-core/src/model/fixed_length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ pub trait Model {
/// no-op by default.
fn update(&mut self, _symbol: &Self::Symbol) {}

/// The total number of symbols to encode
/// The total number of symbols to encode.
///
/// This must not change during encoding/decoding.
fn length(&self) -> usize;
}

Expand Down
19 changes: 19 additions & 0 deletions examples/fixed_length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ use arithmetic_coding::fixed_length;

mod common;

/// The possible symbols
#[derive(Debug)]
pub enum Symbol {
A,
B,
C,
}

/// A model for encoding/decoding a set of 3 symbols from {A, B, C}
#[derive(Clone)]
pub struct MyModel;

Expand All @@ -19,6 +21,11 @@ impl fixed_length::Model for MyModel {
type Symbol = Symbol;
type ValueError = Infallible;

/// Given a symbol, return a unique interval representing the probability of
/// that symbol occurring.
///
/// Since the number of symbols in the message is fixed, no 'stop' symbol is
/// needed.
fn probability(&self, symbol: &Self::Symbol) -> Result<Range<u32>, Self::ValueError> {
match symbol {
Symbol::A => Ok(0..1),
Expand All @@ -27,6 +34,7 @@ impl fixed_length::Model for MyModel {
}
}

/// For decoding, for each possible value, a symbol is returned.
fn symbol(&self, value: u32) -> Self::Symbol {
match value {
0..1 => Symbol::A,
Expand All @@ -36,10 +44,21 @@ impl fixed_length::Model for MyModel {
}
}

/// The maximum denominator used for probability ranges.
///
/// The trait also includes a 'denominator' method, which is allowed to vary
/// for each symbol, but must never exceed `max_denominator`.
/// For non-adaptive models, this value is the same as `max_denominator`
/// (and this is the default value of the trait method).
fn max_denominator(&self) -> u32 {
3
}

/// The total number of symbols to encode.
///
/// Because the number of symbols is known ahead of time, we can take
/// advantage of this to optimise the compression by removing the need
/// for a 'stop' symbol.
fn length(&self) -> usize {
3
}
Expand Down
17 changes: 17 additions & 0 deletions examples/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ use arithmetic_coding::Model;

mod common;

/// A model for encoding/decoding integers 1..4
#[derive(Clone)]
pub struct MyModel;

/// Invalid symbol error.
///
/// This occurs if an integer is found that is not in the range 1..4
#[derive(Debug, thiserror::Error)]
#[error("invalid symbol: {0}")]
pub struct Error(u8);
Expand All @@ -16,6 +20,12 @@ impl Model for MyModel {
type Symbol = u8;
type ValueError = Error;

/// Given a symbol, return an interval representing the probability of that
/// symbol occurring.
///
/// Each symbol (plus a 'stop' symbol) is assigned a unique span of the
/// interval from 0-4. In this case each span has equal probability, so
/// is the same size.
fn probability(&self, symbol: Option<&Self::Symbol>) -> Result<Range<u32>, Error> {
match symbol {
None => Ok(0..1),
Expand All @@ -26,6 +36,7 @@ impl Model for MyModel {
}
}

/// For decoding, for each possible value, a symbol is returned.
fn symbol(&self, value: u32) -> Option<Self::Symbol> {
match value {
0..1 => None,
Expand All @@ -36,6 +47,12 @@ impl Model for MyModel {
}
}

/// The maximum denominator used for probability ranges.
///
/// The trait also includes a 'denominator' method, which is allowed to vary
/// for each symbol, but must never exceed `max_denominator`.
/// For non-adaptive models, this value is the same as `max_denominator`
/// (and this is the default value of the trait method).
fn max_denominator(&self) -> u32 {
4
}
Expand Down
13 changes: 9 additions & 4 deletions src/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ where
Self::with_state(state, model)
}

/// todo
/// Create a decoder from an existing [`State`] and [`Model`].
///
/// This is useful for manually chaining a shared buffer through multiple
/// decoders.
pub fn with_state(state: State<M::B, R>, model: M) -> Self {
#[cfg(debug_assertions)]
assert_precision_sufficient::<M>(model.max_denominator(), state.state.precision);
Expand All @@ -97,7 +100,7 @@ where
/// Return an iterator over the decoded symbols.
///
/// The iterator will continue returning symbols until EOF is reached
pub fn decode_all(&mut self) -> DecodeIter<M, R> {
pub const fn decode_all(&mut self) -> DecodeIter<M, R> {
DecodeIter { decoder: self }
}

Expand Down Expand Up @@ -142,7 +145,7 @@ where
Decoder::with_state(self.state, model)
}

/// todo
/// Return the internal model and state of the decoder.
pub fn into_inner(self) -> (M, State<M::B, R>) {
(self.model, self.state)
}
Expand Down Expand Up @@ -177,6 +180,7 @@ where
B: BitStore,
R: BitRead,
{
#[allow(clippy::struct_field_names)]
state: common::State<B>,
input: R,
x: B,
Expand All @@ -188,7 +192,8 @@ where
B: BitStore,
R: BitRead,
{
/// todo
/// Create a new [`State`] from an input stream of bits with a given
/// precision.
pub fn new(precision: u32, input: R) -> Self {
let state = common::State::new(precision);
let x = B::ZERO;
Expand Down
3 changes: 2 additions & 1 deletion src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ where
self.state.flush()
}

/// todo
/// Return the internal model and state of the encoder.
pub fn into_inner(self) -> (M, State<'a, M::B, W>) {
(self.model, self.state)
}
Expand All @@ -166,6 +166,7 @@ where
B: BitStore,
W: BitWrite,
{
#[allow(clippy::struct_field_names)]
state: common::State<B>,
pending: u32,
output: &'a mut W,
Expand Down
6 changes: 5 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
//! Arithmetic coding library

#![deny(missing_docs, missing_debug_implementations)]
#![deny(
missing_docs,
missing_debug_implementations,
missing_copy_implementations
)]

pub use arithmetic_coding_core::{fixed_length, max_length, one_shot, BitStore, Model};

Expand Down
5 changes: 5 additions & 0 deletions tests/max_length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ pub enum Symbol {
C,
}

/// This model encodes a variable number of symbols, up to a maximum of 3.
///
/// By taking advantage of the fact that the maximum number of symbols is known
/// ahead of time, compression is improved compared to a fully variable-length
/// model.
#[derive(Clone)]
pub struct MyModel;

Expand Down