zrip_core/bitstream/
reader_reverse.rs1#![forbid(unsafe_code)]
2
3use crate::bitstream::primitives;
4use crate::error::DecompressError;
5
6pub struct ReverseBitReader<'a> {
13 pub data: &'a [u8],
14 pub container: u64,
15 pub bits_consumed: u32,
16 pub ptr: usize,
17 pub limit_ptr: usize,
18}
19
20impl<'a> ReverseBitReader<'a> {
21 pub fn new(data: &'a [u8]) -> Result<Self, DecompressError> {
22 if data.is_empty() {
23 return Err(DecompressError::InputExhausted);
24 }
25
26 let last_byte = *data.last().unwrap();
27 if last_byte == 0 {
28 return Err(DecompressError::CorruptSequences);
29 }
30
31 let initial_consumed = last_byte.leading_zeros() + 1;
32
33 let ptr = if data.len() >= 8 { data.len() - 8 } else { 0 };
34
35 let container = if data.len() >= 8 {
36 primitives::read_u64_le_unaligned(data, ptr)
37 } else {
38 let mut val = 0u64;
39 for (i, &b) in data.iter().enumerate() {
40 val |= (b as u64) << (i * 8);
41 }
42 val
43 };
44
45 let bits_consumed = if data.len() >= 8 {
46 initial_consumed
47 } else {
48 64 - (data.len() as u32) * 8 + initial_consumed
49 };
50
51 let limit_ptr = if data.len() >= 8 { 8 } else { 0 };
52
53 Ok(Self {
54 data,
55 container,
56 bits_consumed,
57 ptr,
58 limit_ptr,
59 })
60 }
61
62 #[inline(always)]
63 pub fn refill(&mut self) {
64 if self.bits_consumed <= 7 || self.ptr == 0 {
65 return;
66 }
67 let byte_shift = (self.bits_consumed >> 3) as usize;
68 let actual_shift = byte_shift.min(self.ptr);
69 self.ptr -= actual_shift;
70 self.bits_consumed -= (actual_shift as u32) * 8;
71 if self.ptr + 8 <= self.data.len() {
72 self.container = primitives::read_u64_le_unaligned(self.data, self.ptr);
73 } else {
74 let mut val = 0u64;
75 let avail = self.data.len() - self.ptr;
76 for i in 0..avail {
77 val |= (primitives::get_byte_unchecked(self.data, self.ptr + i) as u64) << (i * 8);
78 }
79 self.container = val;
80 }
81 }
82
83 #[inline]
84 pub fn read_bits(&mut self, n: u8) -> Result<u32, DecompressError> {
85 debug_assert!(n <= 32);
86 if n == 0 {
87 return Ok(0);
88 }
89 self.refill();
90 let avail = 64u32.saturating_sub(self.bits_consumed);
91 if (n as u32) > avail {
92 return Err(DecompressError::InputExhausted);
93 }
94 let result = ((self.container << self.bits_consumed) >> (64 - n as u32)) as u32;
95 self.bits_consumed += n as u32;
96 Ok(result)
97 }
98
99 #[inline]
100 pub fn read_bits_unchecked(&mut self, n: u8) -> u32 {
101 debug_assert!(n <= 32);
102 if n == 0 {
103 return 0;
104 }
105 self.refill();
106 debug_assert!((n as u32) <= 64u32.saturating_sub(self.bits_consumed));
107 let result = ((self.container << self.bits_consumed) >> (64 - n as u32)) as u32;
108 self.bits_consumed += n as u32;
109 result
110 }
111
112 #[inline(always)]
113 pub fn consume_bits(&mut self, n: u8) {
114 debug_assert!((n as u32) <= 64u32.saturating_sub(self.bits_consumed));
115 self.bits_consumed += n as u32;
116 self.refill();
117 }
118
119 #[inline(always)]
120 pub fn read_bits_fast(&mut self, n: u8) -> u32 {
121 debug_assert!((n as u32) <= 64u32.saturating_sub(self.bits_consumed));
122 if n == 0 {
123 return 0;
124 }
125 let result = ((self.container << self.bits_consumed) >> (64 - n as u32)) as u32;
126 self.bits_consumed += n as u32;
127 result
128 }
129
130 #[inline(always)]
131 pub fn read_bits_branchless(&mut self, n: u8) -> u32 {
132 debug_assert!(n <= 32);
133 let result = ((self.container << (self.bits_consumed & 63)) >> 1 >> (63 - n as u32)) as u32;
134 self.bits_consumed += n as u32;
135 result
136 }
137
138 #[inline(always)]
139 pub fn refill_fast(&mut self) {
140 debug_assert!(self.ptr >= self.limit_ptr);
141 let byte_shift = (self.bits_consumed >> 3) as usize;
142 self.ptr -= byte_shift;
143 self.bits_consumed -= (byte_shift as u32) * 8;
144 self.container = primitives::read_u64_le_unaligned(self.data, self.ptr);
145 }
146
147 #[inline]
148 pub fn peek_bits(&self, n: u8) -> u32 {
149 debug_assert!(n <= 32);
150 debug_assert!((n as u32) <= 64u32.saturating_sub(self.bits_consumed));
151 if n == 0 {
152 return 0;
153 }
154 ((self.container << self.bits_consumed) >> (64 - n as u32)) as u32
155 }
156
157 #[inline]
158 pub fn bits_remaining(&self) -> usize {
159 64usize.saturating_sub(self.bits_consumed as usize) + self.ptr * 8
160 }
161
162 #[inline]
163 pub fn is_empty(&self) -> bool {
164 self.bits_consumed >= 64 && self.ptr == 0
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use super::*;
171
172 #[test]
173 fn empty_input() {
174 assert!(ReverseBitReader::new(&[]).is_err());
175 }
176
177 #[test]
178 fn zero_last_byte() {
179 assert!(ReverseBitReader::new(&[0x00]).is_err());
180 }
181
182 #[test]
183 fn sentinel_only_no_data() {
184 let data = [0b00000001];
185 let r = ReverseBitReader::new(&data).unwrap();
186 assert_eq!(r.bits_remaining(), 0);
187 }
188
189 #[test]
190 fn roundtrip_with_forward_writer() {
191 use crate::bitstream::writer::BitWriter;
192
193 let mut w = BitWriter::new();
194 w.write_bits(0b101, 3);
195 w.write_bits(0b11001010, 8);
196 w.write_bits(0b1, 1);
197 w.close_reverse_stream();
198 let bytes = w.into_bytes();
199
200 let mut r = ReverseBitReader::new(&bytes).unwrap();
201 assert_eq!(r.read_bits(1).unwrap(), 0b1);
202 assert_eq!(r.read_bits(8).unwrap(), 0b11001010);
203 assert_eq!(r.read_bits(3).unwrap(), 0b101);
204 assert_eq!(r.bits_remaining(), 0);
205 }
206
207 #[test]
208 fn single_byte_with_data() {
209 let data = [0b00001101];
210 let mut r = ReverseBitReader::new(&data).unwrap();
211 assert_eq!(r.read_bits(3).unwrap(), 0b101);
212 assert_eq!(r.bits_remaining(), 0);
213 }
214
215 #[test]
216 fn multi_byte_stream() {
217 use crate::bitstream::writer::BitWriter;
218
219 let mut w = BitWriter::new();
220 w.write_bits(0xFF, 8);
221 w.write_bits(0x3, 2);
222 w.close_reverse_stream();
223 let bytes = w.into_bytes();
224
225 let mut r = ReverseBitReader::new(&bytes).unwrap();
226 assert_eq!(r.read_bits(2).unwrap(), 0x3);
227 assert_eq!(r.read_bits(8).unwrap(), 0xFF);
228 }
229}