Skip to content

Commit

Permalink
Rename BoolReader to ArithmeticDecoder
Browse files Browse the repository at this point in the history
  • Loading branch information
SLiV9 authored and kornelski committed Jan 11, 2025
1 parent 3607c21 commit cadb88f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 62 deletions.
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ pub use self::decoder::{DecodingError, LoopCount, WebPDecoder};
pub use self::encoder::{ColorType, EncoderParams, EncodingError, WebPEncoder};

mod alpha_blending;
mod bool_reader;
mod decoder;
mod encoder;
mod extended;
Expand All @@ -22,5 +21,6 @@ mod loop_filter;
mod lossless;
mod lossless_transform;
mod transform;
mod vp8_arithmetic_decoder;

pub mod vp8;
41 changes: 20 additions & 21 deletions src/vp8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ use std::io::Read;

use crate::decoder::DecodingError;

use super::bool_reader::BoolReader;
use super::loop_filter;
use super::transform;
use super::vp8_arithmetic_decoder::ArithmeticDecoder;
use super::{loop_filter, transform};

const MAX_SEGMENTS: usize = 4;
const NUM_DCT_TOKENS: usize = 12;
Expand Down Expand Up @@ -1021,7 +1020,7 @@ struct Segment {
/// Only decodes keyframes
pub struct Vp8Decoder<R> {
r: R,
b: BoolReader,
b: ArithmeticDecoder,

mbwidth: u16,
mbheight: u16,
Expand All @@ -1036,7 +1035,7 @@ pub struct Vp8Decoder<R> {
ref_delta: [i32; 4],
mode_delta: [i32; 4],

partitions: [BoolReader; 8],
partitions: [ArithmeticDecoder; 8],
num_partitions: u8,

segment_tree_nodes: [TreeNode; 3],
Expand Down Expand Up @@ -1065,7 +1064,7 @@ impl<R: Read> Vp8Decoder<R> {

Self {
r,
b: BoolReader::new(),
b: ArithmeticDecoder::new(),

mbwidth: 0,
mbheight: 0,
Expand All @@ -1080,14 +1079,14 @@ impl<R: Read> Vp8Decoder<R> {
mode_delta: [0; 4],

partitions: [
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
ArithmeticDecoder::new(),
ArithmeticDecoder::new(),
ArithmeticDecoder::new(),
ArithmeticDecoder::new(),
ArithmeticDecoder::new(),
ArithmeticDecoder::new(),
ArithmeticDecoder::new(),
ArithmeticDecoder::new(),
],

num_partitions: 1,
Expand Down Expand Up @@ -1631,9 +1630,9 @@ impl<R: Read> Vp8Decoder<R> {

let first = if plane == 0 { 1usize } else { 0usize };
let probs = &self.token_probs[plane];
let reader = &mut self.partitions[p];
let decoder = &mut self.partitions[p];

let mut res = reader.start_accumulated_result();
let mut res = decoder.start_accumulated_result();

let mut complexity = complexity;
let mut has_coefficients = false;
Expand All @@ -1643,7 +1642,7 @@ impl<R: Read> Vp8Decoder<R> {
let band = COEFF_BANDS[i] as usize;
let tree = &probs[band][complexity];

let token = reader
let token = decoder
.read_with_tree_with_first_node(tree, tree[skip as usize])
.or_accumulate(&mut res);

Expand All @@ -1668,8 +1667,8 @@ impl<R: Read> Vp8Decoder<R> {
if t == 0 {
break;
}
let b = reader.read_bool(t).or_accumulate(&mut res);
extra = extra + extra + b as i16;
let b = decoder.read_bool(t).or_accumulate(&mut res);
extra = extra + extra + i16::from(b);
}

i16::from(DCT_CAT_BASE[(category - DCT_CAT1) as usize]) + extra
Expand All @@ -1688,7 +1687,7 @@ impl<R: Read> Vp8Decoder<R> {
2
};

if reader.read_flag().or_accumulate(&mut res) {
if decoder.read_flag().or_accumulate(&mut res) {
abs_value = -abs_value;
}

Expand All @@ -1698,7 +1697,7 @@ impl<R: Read> Vp8Decoder<R> {
has_coefficients = true;
}

reader.check(res, has_coefficients)
decoder.check(res, has_coefficients)
}

fn read_residual_data(
Expand Down
80 changes: 40 additions & 40 deletions src/bool_reader.rs → src/vp8_arithmetic_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl<T: Default> BitResult<T> {
}

#[cfg_attr(test, derive(Debug))]
pub(crate) struct BoolReader {
pub(crate) struct ArithmeticDecoder {
chunks: Box<[[u8; 4]]>,
state: State,
final_bytes: [u8; 3],
Expand All @@ -53,21 +53,21 @@ struct State {
}

#[cfg_attr(test, derive(Debug))]
struct FastReader<'a> {
struct FastDecoder<'a> {
chunks: &'a [[u8; 4]],
uncommitted_state: State,
save_state: &'a mut State,
}

impl BoolReader {
pub(crate) fn new() -> BoolReader {
impl ArithmeticDecoder {
pub(crate) fn new() -> ArithmeticDecoder {
let state = State {
chunk_index: 0,
value: 0,
range: 255,
bit_count: -8,
};
BoolReader {
ArithmeticDecoder {
chunks: Box::new([]),
state,
final_bytes: [0; 3],
Expand Down Expand Up @@ -117,7 +117,7 @@ impl BoolReader {
/// discarded anyway.
///
/// Each call to `start_accumulated_result` must be followed by a call to
/// `check` on the *same* `BoolReader`.
/// `check` on the *same* `ArithmeticDecoder`.
#[inline(always)]
pub(crate) fn start_accumulated_result(&mut self) -> BitResultAccumulator {
BitResultAccumulator
Expand Down Expand Up @@ -216,7 +216,7 @@ impl BoolReader {
self.cold_read_with_tree(tree, usize::from(first_node.index))
}

// As a similar (but different) speedup to BitResult, the FastReader reads
// As a similar (but different) speedup to BitResult, the FastDecoder reads
// bits under an assumption and validates it at the end.
//
// The idea here is that for normal-sized webp images, the vast majority
Expand All @@ -228,8 +228,8 @@ impl BoolReader {
// work for those last few bytes -- in fact we even keep retrying the fast
// method to save an if-statement --, but more than make up for that by
// speeding up reading from the other thousands or millions of bytes.
fn fast(&mut self) -> FastReader<'_> {
FastReader {
fn fast(&mut self) -> FastDecoder<'_> {
FastDecoder {
chunks: &self.chunks,
uncommitted_state: self.state,
save_state: &mut self.state,
Expand Down Expand Up @@ -377,7 +377,7 @@ impl BoolReader {
}
}

impl FastReader<'_> {
impl FastDecoder<'_> {
fn commit_if_valid<T>(self, value_if_not_past_eof: T) -> Option<T> {
// If `chunk_index > self.chunks.len()`, it means we used zeroes
// instead of an actual chunk and `value_if_not_past_eof` is nonsense.
Expand Down Expand Up @@ -564,50 +564,50 @@ mod tests {
use super::*;

#[test]
fn test_bool_reader_hello_short() {
let mut reader = BoolReader::new();
fn test_arithmetic_decoder_hello_short() {
let mut decoder = ArithmeticDecoder::new();
let data = b"hel";
let size = data.len();
let mut buf = vec![[0u8; 4]; 1];
buf.as_mut_slice().as_flattened_mut()[..size].copy_from_slice(&data[..]);
reader.init(buf, size).unwrap();
let mut res = reader.start_accumulated_result();
assert_eq!(false, reader.read_flag().or_accumulate(&mut res));
assert_eq!(true, reader.read_bool(10).or_accumulate(&mut res));
assert_eq!(false, reader.read_bool(250).or_accumulate(&mut res));
assert_eq!(1, reader.read_literal(1).or_accumulate(&mut res));
assert_eq!(5, reader.read_literal(3).or_accumulate(&mut res));
assert_eq!(64, reader.read_literal(8).or_accumulate(&mut res));
assert_eq!(185, reader.read_literal(8).or_accumulate(&mut res));
reader.check(res, ()).unwrap();
decoder.init(buf, size).unwrap();
let mut res = decoder.start_accumulated_result();
assert_eq!(false, decoder.read_flag().or_accumulate(&mut res));
assert_eq!(true, decoder.read_bool(10).or_accumulate(&mut res));
assert_eq!(false, decoder.read_bool(250).or_accumulate(&mut res));
assert_eq!(1, decoder.read_literal(1).or_accumulate(&mut res));
assert_eq!(5, decoder.read_literal(3).or_accumulate(&mut res));
assert_eq!(64, decoder.read_literal(8).or_accumulate(&mut res));
assert_eq!(185, decoder.read_literal(8).or_accumulate(&mut res));
decoder.check(res, ()).unwrap();
}

#[test]
fn test_bool_reader_hello_long() {
let mut reader = BoolReader::new();
fn test_arithmetic_decoder_hello_long() {
let mut decoder = ArithmeticDecoder::new();
let data = b"hello world";
let size = data.len();
let mut buf = vec![[0u8; 4]; (size + 3) / 4];
buf.as_mut_slice().as_flattened_mut()[..size].copy_from_slice(&data[..]);
reader.init(buf, size).unwrap();
let mut res = reader.start_accumulated_result();
assert_eq!(false, reader.read_flag().or_accumulate(&mut res));
assert_eq!(true, reader.read_bool(10).or_accumulate(&mut res));
assert_eq!(false, reader.read_bool(250).or_accumulate(&mut res));
assert_eq!(1, reader.read_literal(1).or_accumulate(&mut res));
assert_eq!(5, reader.read_literal(3).or_accumulate(&mut res));
assert_eq!(64, reader.read_literal(8).or_accumulate(&mut res));
assert_eq!(185, reader.read_literal(8).or_accumulate(&mut res));
assert_eq!(31, reader.read_literal(8).or_accumulate(&mut res));
reader.check(res, ()).unwrap();
decoder.init(buf, size).unwrap();
let mut res = decoder.start_accumulated_result();
assert_eq!(false, decoder.read_flag().or_accumulate(&mut res));
assert_eq!(true, decoder.read_bool(10).or_accumulate(&mut res));
assert_eq!(false, decoder.read_bool(250).or_accumulate(&mut res));
assert_eq!(1, decoder.read_literal(1).or_accumulate(&mut res));
assert_eq!(5, decoder.read_literal(3).or_accumulate(&mut res));
assert_eq!(64, decoder.read_literal(8).or_accumulate(&mut res));
assert_eq!(185, decoder.read_literal(8).or_accumulate(&mut res));
assert_eq!(31, decoder.read_literal(8).or_accumulate(&mut res));
decoder.check(res, ()).unwrap();
}

#[test]
fn test_bool_reader_uninit() {
let mut reader = BoolReader::new();
let mut res = reader.start_accumulated_result();
let _ = reader.read_flag().or_accumulate(&mut res);
let result = reader.check(res, ());
fn test_arithmetic_decoder_uninit() {
let mut decoder = ArithmeticDecoder::new();
let mut res = decoder.start_accumulated_result();
let _ = decoder.read_flag().or_accumulate(&mut res);
let result = decoder.check(res, ());
assert!(result.is_err());
}
}

0 comments on commit cadb88f

Please sign in to comment.