diff --git a/src/lib.rs b/src/lib.rs index 645e250..dedc9f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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; @@ -22,5 +21,6 @@ mod loop_filter; mod lossless; mod lossless_transform; mod transform; +mod vp8_arithmetic_decoder; pub mod vp8; diff --git a/src/vp8.rs b/src/vp8.rs index b30a5c3..6e79eb8 100644 --- a/src/vp8.rs +++ b/src/vp8.rs @@ -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; @@ -1021,7 +1020,7 @@ struct Segment { /// Only decodes keyframes pub struct Vp8Decoder { r: R, - b: BoolReader, + b: ArithmeticDecoder, mbwidth: u16, mbheight: u16, @@ -1036,7 +1035,7 @@ pub struct Vp8Decoder { ref_delta: [i32; 4], mode_delta: [i32; 4], - partitions: [BoolReader; 8], + partitions: [ArithmeticDecoder; 8], num_partitions: u8, segment_tree_nodes: [TreeNode; 3], @@ -1065,7 +1064,7 @@ impl Vp8Decoder { Self { r, - b: BoolReader::new(), + b: ArithmeticDecoder::new(), mbwidth: 0, mbheight: 0, @@ -1080,14 +1079,14 @@ impl Vp8Decoder { 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, @@ -1631,9 +1630,9 @@ impl Vp8Decoder { 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; @@ -1643,7 +1642,7 @@ impl Vp8Decoder { 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); @@ -1668,8 +1667,8 @@ impl Vp8Decoder { 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 @@ -1688,7 +1687,7 @@ impl Vp8Decoder { 2 }; - if reader.read_flag().or_accumulate(&mut res) { + if decoder.read_flag().or_accumulate(&mut res) { abs_value = -abs_value; } @@ -1698,7 +1697,7 @@ impl Vp8Decoder { has_coefficients = true; } - reader.check(res, has_coefficients) + decoder.check(res, has_coefficients) } fn read_residual_data( diff --git a/src/bool_reader.rs b/src/vp8_arithmetic_decoder.rs similarity index 89% rename from src/bool_reader.rs rename to src/vp8_arithmetic_decoder.rs index 4c2ce8d..7f8c4be 100644 --- a/src/bool_reader.rs +++ b/src/vp8_arithmetic_decoder.rs @@ -36,7 +36,7 @@ impl BitResult { } #[cfg_attr(test, derive(Debug))] -pub(crate) struct BoolReader { +pub(crate) struct ArithmeticDecoder { chunks: Box<[[u8; 4]]>, state: State, final_bytes: [u8; 3], @@ -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], @@ -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 @@ -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 @@ -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, @@ -377,7 +377,7 @@ impl BoolReader { } } -impl FastReader<'_> { +impl FastDecoder<'_> { fn commit_if_valid(self, value_if_not_past_eof: T) -> Option { // If `chunk_index > self.chunks.len()`, it means we used zeroes // instead of an actual chunk and `value_if_not_past_eof` is nonsense. @@ -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()); } }