Skip to content

Commit 38a80e4

Browse files
authored
Refactor (#15)
* tidy up tests * tidy up examples
1 parent f45a056 commit 38a80e4

File tree

10 files changed

+234
-163
lines changed

10 files changed

+234
-163
lines changed

examples/common/mod.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use arithmetic_coding::{Decoder, Encoder, Model};
2+
use bitstream_io::{BigEndian, BitReader, BitWrite, BitWriter};
3+
4+
#[allow(unused)]
5+
pub fn round_trip<M>(model: M, input: Vec<M::Symbol>)
6+
where
7+
M: Model + Clone,
8+
M::Symbol: std::fmt::Debug,
9+
{
10+
println!("input: {:?}", &input);
11+
12+
println!("\nencoding...");
13+
let buffer = encode(model.clone(), input);
14+
15+
println!("buffer: {:?}", &buffer);
16+
17+
println!("\ndecoding...");
18+
for symbol in decode(model, &buffer) {
19+
println!("{:?}", symbol);
20+
}
21+
}
22+
23+
pub fn encode<M, I>(model: M, input: I) -> Vec<u8>
24+
where
25+
M: Model,
26+
I: IntoIterator<Item = M::Symbol>,
27+
{
28+
let mut bitwriter = BitWriter::endian(Vec::new(), BigEndian);
29+
let mut encoder = Encoder::<M>::new(model);
30+
31+
encoder.encode_all(input, &mut bitwriter).unwrap();
32+
bitwriter.byte_align().unwrap();
33+
34+
bitwriter.into_writer()
35+
}
36+
37+
pub fn decode<M>(model: M, buffer: &[u8]) -> Vec<M::Symbol>
38+
where
39+
M: Model,
40+
{
41+
let bitreader = BitReader::endian(buffer, BigEndian);
42+
let mut decoder = Decoder::new(model, bitreader).unwrap();
43+
let mut output = Vec::new();
44+
45+
while let Some(symbol) = decoder.decode_symbol().unwrap() {
46+
output.push(symbol);
47+
}
48+
output
49+
}

examples/concatenated.rs

Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#![feature(exclusive_range_pattern)]
22
#![feature(never_type)]
33

4+
use arithmetic_coding::{Decoder, Encoder, Model};
5+
use bitstream_io::{BigEndian, BitRead, BitReader, BitWrite, BitWriter};
6+
7+
const PRECISION: u32 = 12;
8+
49
mod integer {
510

611
use std::ops::Range;
@@ -83,52 +88,94 @@ mod symbolic {
8388
}
8489

8590
fn main() {
86-
const PRECISION: u32 = 12;
87-
use arithmetic_coding::{Decoder, Encoder};
88-
use bitstream_io::{BigEndian, BitReader, BitWrite, BitWriter};
8991
use symbolic::Symbol;
9092

9193
let input1 = [Symbol::A, Symbol::B, Symbol::C];
94+
println!("input1: {:?}", input1);
95+
9296
let input2 = [2, 1, 1, 2, 2];
97+
println!("input2: {:?}", input2);
9398

94-
let mut bitwriter = BitWriter::endian(Vec::default(), BigEndian);
99+
println!("\nencoding...");
95100

96-
println!("encoding...");
101+
let buffer = encode2(symbolic::Model, &input1, integer::Model, &input2);
97102

98-
let mut symbol_encoder = Encoder::with_precision(symbolic::Model, PRECISION);
99-
for symbol in &input1 {
100-
symbol_encoder.encode(Some(symbol), &mut bitwriter).unwrap();
101-
}
102-
symbol_encoder.encode(None, &mut bitwriter).unwrap();
103+
println!("\nbuffer: {:?}", &buffer);
103104

104-
let mut integer_encoder = symbol_encoder.chain(integer::Model);
105+
println!("\ndecoding...");
106+
let (output1, output2) = decode2(symbolic::Model, integer::Model, &buffer);
105107

106-
for symbol in &input2 {
107-
integer_encoder
108-
.encode(Some(symbol), &mut bitwriter)
109-
.unwrap();
108+
for symbol in output1 {
109+
println!("{:?}", symbol);
110110
}
111-
integer_encoder.encode(None, &mut bitwriter).unwrap();
112-
integer_encoder.flush(&mut bitwriter).unwrap();
111+
for symbol in output2 {
112+
println!("{:?}", symbol);
113+
}
114+
}
113115

114-
bitwriter.byte_align().unwrap();
116+
/// Encode two sets of symbols in sequence
117+
fn encode2<M, N>(model1: M, input1: &[M::Symbol], model2: N, input2: &[N::Symbol]) -> Vec<u8>
118+
where
119+
M: Model<B = N::B>,
120+
N: Model,
121+
{
122+
let mut bitwriter = BitWriter::endian(Vec::default(), BigEndian);
115123

116-
let buffer = bitwriter.into_writer();
124+
let mut encoder1 = Encoder::with_precision(model1, PRECISION);
125+
encode(&mut encoder1, input1, &mut bitwriter);
117126

118-
println!("buffer: {:?}", &buffer);
127+
let mut encoder2 = encoder1.chain(model2);
128+
encode(&mut encoder2, input2, &mut bitwriter);
119129

120-
let bitreader = BitReader::endian(buffer.as_slice(), BigEndian);
130+
encoder2.flush(&mut bitwriter).unwrap();
121131

122-
let mut symbol_decoder =
123-
Decoder::with_precision(symbolic::Model, bitreader, PRECISION).unwrap();
132+
bitwriter.byte_align().unwrap();
133+
bitwriter.into_writer()
134+
}
124135

125-
while let Some(symbol) = symbol_decoder.decode_symbol().unwrap() {
126-
println!("{:?}", symbol);
136+
/// Encode all symbols, followed by EOF. Doesn't flush the encoder (allowing
137+
/// more bits to be concatenated)
138+
fn encode<M, W>(encoder: &mut Encoder<M>, input: &[M::Symbol], bitwriter: &mut W)
139+
where
140+
M: Model,
141+
W: BitWrite,
142+
{
143+
for symbol in input {
144+
encoder.encode(Some(symbol), bitwriter).unwrap();
127145
}
146+
encoder.encode(None, bitwriter).unwrap();
147+
}
128148

129-
let mut integer_decoder = symbol_decoder.chain(integer::Model);
149+
/// Decode two sets of symbols, in sequence
150+
fn decode2<M, N>(model1: M, model2: N, buffer: &[u8]) -> (Vec<M::Symbol>, Vec<N::Symbol>)
151+
where
152+
M: Model<B = N::B>,
153+
N: Model,
154+
{
155+
let bitreader = BitReader::endian(buffer, BigEndian);
130156

131-
while let Some(symbol) = integer_decoder.decode_symbol().unwrap() {
132-
println!("{:?}", symbol);
157+
let mut decoder1 = Decoder::with_precision(model1, bitreader, PRECISION).unwrap();
158+
159+
let output1 = decode(&mut decoder1);
160+
161+
let mut decoder2 = decoder1.chain(model2);
162+
163+
let output2 = decode(&mut decoder2);
164+
165+
(output1, output2)
166+
}
167+
168+
/// Decode all symbols from a [`Decoder`] until EOF is reached
169+
fn decode<M, R>(decoder: &mut Decoder<M, R>) -> Vec<M::Symbol>
170+
where
171+
M: Model,
172+
R: BitRead,
173+
{
174+
let mut output = Vec::default();
175+
176+
while let Some(symbol) = decoder.decode_symbol().unwrap() {
177+
output.push(symbol);
133178
}
179+
180+
output
134181
}

examples/fixed_length.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33

44
use std::ops::Range;
55

6-
use arithmetic_coding::{fixed_length, Decoder, Encoder};
7-
use bitstream_io::{BigEndian, BitReader, BitWrite, BitWriter};
6+
use arithmetic_coding::fixed_length;
7+
8+
mod common;
89

910
#[derive(Debug)]
1011
pub enum Symbol {
@@ -47,27 +48,8 @@ impl fixed_length::Model for MyModel {
4748
}
4849

4950
fn main() {
50-
let input = [Symbol::A, Symbol::B, Symbol::C];
51-
51+
let input = vec![Symbol::A, Symbol::B, Symbol::C];
5252
let model = fixed_length::Wrapper::new(MyModel);
5353

54-
let output = Vec::default();
55-
let mut bitwriter = BitWriter::endian(output, BigEndian);
56-
let mut encoder = Encoder::new(model.clone());
57-
58-
println!("encoding...");
59-
encoder.encode_all(input, &mut bitwriter).unwrap();
60-
bitwriter.byte_align().unwrap();
61-
62-
let buffer = bitwriter.into_writer();
63-
64-
println!("buffer: {:?}", &buffer);
65-
66-
let bitreader = BitReader::endian(buffer.as_slice(), BigEndian);
67-
68-
println!("\ndecoding...");
69-
let mut decoder = Decoder::new(model, bitreader).unwrap();
70-
while let Some(symbol) = decoder.decode_symbol().unwrap() {
71-
dbg!(symbol);
72-
}
54+
common::round_trip(model, input);
7355
}

examples/integer.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
use std::ops::Range;
44

5-
use arithmetic_coding::{Decoder, Encoder, Model};
6-
use bitstream_io::{BigEndian, BitReader, BitWrite, BitWriter};
5+
use arithmetic_coding::Model;
76

7+
mod common;
8+
9+
#[derive(Clone)]
810
pub struct MyModel;
911

1012
#[derive(Debug, thiserror::Error)]
@@ -41,25 +43,5 @@ impl Model for MyModel {
4143
}
4244

4345
fn main() {
44-
let input = [2, 1, 1, 2, 2];
45-
46-
let output = Vec::default();
47-
let mut bitwriter = BitWriter::endian(output, BigEndian);
48-
let mut encoder = Encoder::new(MyModel);
49-
50-
println!("encoding...");
51-
encoder.encode_all(input, &mut bitwriter).unwrap();
52-
bitwriter.byte_align().unwrap();
53-
54-
let buffer = bitwriter.into_writer();
55-
56-
println!("buffer: {:?}", &buffer);
57-
58-
let bitreader = BitReader::endian(buffer.as_slice(), BigEndian);
59-
60-
println!("\ndecoding...");
61-
let mut decoder = Decoder::new(MyModel, bitreader).unwrap();
62-
while let Some(symbol) = decoder.decode_symbol().unwrap() {
63-
dbg!(symbol);
64-
}
46+
common::round_trip(MyModel, vec![2, 1, 1, 2, 2]);
6547
}

examples/sherlock.rs

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::{fs::File, io::Read, ops::Range};
22

3-
use arithmetic_coding::{Decoder, Encoder, Model};
4-
use bitstream_io::{BigEndian, BitReader, BitWrite, BitWriter};
3+
use arithmetic_coding::Model;
4+
5+
mod common;
56

67
const ALPHABET: &str =
78
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .,\n-':()[]#*;\"!?*&é/àâè%@$";
@@ -55,15 +56,7 @@ fn main() {
5556

5657
let model = StringModel::new(ALPHABET.chars().collect());
5758

58-
let output = Vec::default();
59-
let mut bitwriter = BitWriter::endian(output, BigEndian);
60-
let mut encoder = Encoder::new(model.clone());
61-
62-
println!("encoding...");
63-
encoder.encode_all(input.chars(), &mut bitwriter).unwrap();
64-
bitwriter.byte_align().unwrap();
65-
66-
let buffer = bitwriter.into_writer();
59+
let buffer = common::encode(model.clone(), input.chars());
6760

6861
let output_bytes = buffer.len();
6962

@@ -77,16 +70,9 @@ fn main() {
7770

7871
// println!("buffer: {:?}", &buffer);
7972

80-
let bitreader = BitReader::endian(buffer.as_slice(), BigEndian);
81-
82-
println!("\ndecoding...\n");
83-
let mut decoder = Decoder::new(model, bitreader).unwrap();
84-
let mut output = String::new();
85-
while let Some(symbol) = decoder.decode_symbol().unwrap() {
86-
output.push(symbol);
87-
}
73+
let output = common::decode(model, &buffer);
8874

89-
let mut prefix: String = output.chars().take(299).collect();
75+
let mut prefix: String = output.into_iter().take(299).collect();
9076
prefix.push_str("...");
9177

9278
println!("{}", prefix);

examples/symbolic.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33

44
use std::ops::Range;
55

6-
use arithmetic_coding::{Decoder, Encoder, Model};
7-
use bitstream_io::{BigEndian, BitReader, BitWrite, BitWriter};
6+
use arithmetic_coding::Model;
7+
8+
mod common;
89

910
#[derive(Debug)]
1011
pub enum Symbol {
@@ -13,6 +14,7 @@ pub enum Symbol {
1314
C,
1415
}
1516

17+
#[derive(Clone)]
1618
pub struct MyModel;
1719

1820
impl Model for MyModel {
@@ -44,25 +46,5 @@ impl Model for MyModel {
4446
}
4547

4648
fn main() {
47-
let input = [Symbol::A, Symbol::B, Symbol::C];
48-
49-
let output = Vec::default();
50-
let mut bitwriter = BitWriter::endian(output, BigEndian);
51-
let mut encoder = Encoder::new(MyModel);
52-
53-
println!("encoding...");
54-
encoder.encode_all(input, &mut bitwriter).unwrap();
55-
bitwriter.byte_align().unwrap();
56-
57-
let buffer = bitwriter.into_writer();
58-
59-
println!("buffer: {:?}", &buffer);
60-
61-
let bitreader = BitReader::endian(buffer.as_slice(), BigEndian);
62-
63-
println!("\ndecoding...");
64-
let mut decoder = Decoder::new(MyModel, bitreader).unwrap();
65-
while let Some(symbol) = decoder.decode_symbol().unwrap() {
66-
dbg!(symbol);
67-
}
49+
common::round_trip(MyModel, vec![Symbol::A, Symbol::B, Symbol::C]);
6850
}

0 commit comments

Comments
 (0)