tiny_bitstream/
bitstream.rs1use crate::constants::*;
2use crate::errors::*;
3
4use crate::debug_test;
5
6#[derive(Default)]
7pub struct BitEstream {
8 pub(crate) bits_container: BitContainer,
9 pub(crate) stream: Vec<u8>,
10 pub(crate) bit_pos: u8,
11}
12
13pub struct BitDstream {
14 pub(crate) bits_container: BitContainer,
15 pub(crate) stream: Vec<u8>,
16 pub(crate) bits_consumed: u8,
17}
18
19pub trait BitWriter<T> {
20 fn unchecked_write(&mut self, value: T, nb_bits: u8);
21}
22
23pub trait BitReader<T> {
24 fn read(&mut self, nb_bits: u8) -> Result<T>;
25}
26
27impl BitWriter<usize> for BitEstream {
28 fn unchecked_write(&mut self, mut value: usize, nb_bits: u8) {
29 assert!(nb_bits <= usize::BITS as u8);
30 if self.bit_pos == CTNR_SIZE {
31 self.flush_bits();
32 }
33 if nb_bits + self.bit_pos <= CTNR_SIZE {
34 self.bits_container |= (value & BIT_MASK[nb_bits as usize]) << self.bit_pos;
35 self.bit_pos += nb_bits;
36 return;
37 }
38 let rest = CTNR_SIZE - self.bit_pos;
40 self.bits_container |= (value & BIT_MASK[rest as usize]) << self.bit_pos;
41 self.bit_pos += rest;
42 self.flush_bits();
43 value >>= rest;
44 self.unchecked_write(value, nb_bits - rest)
45 }
46}
47
48impl BitReader<usize> for BitDstream {
49 fn read(&mut self, nb_bits: u8) -> Result<usize> {
50 assert!(usize::BITS as u8 >= nb_bits);
51 if CTNR_SIZE == self.bits_consumed {
52 if self.reload_container()? {
54 throw!(ReadOverflow);
55 }
56 }
57 if (CTNR_SIZE - self.bits_consumed) >= nb_bits {
58 return self.read_bits(nb_bits);
59 }
60 let rest = CTNR_SIZE - self.bits_consumed;
61 let rem = nb_bits - rest;
62 let ret = self.read_bits(rest)? << rem;
63 if self.reload_container()? {
64 throw!(ReadOverflow);
65 }
66 Ok(self.read_bits(rem)? + ret)
67 }
68}
69
70impl BitEstream {
71 pub fn new() -> Self {
75 Default::default()
76 }
77
78 #[inline]
81 pub fn add_bits<T: Into<BitContainer>>(&mut self, value: T, nb_bits: u8) -> Result<()> {
82 if nb_bits > BIT_MASK_SIZE {
83 throw!(AddBits, format!("MASK size smaller than {}", nb_bits))
84 }
85 if nb_bits + self.bit_pos > CTNR_SIZE {
86 throw!(AddBits, "Container overflow")
87 }
88 self.bits_container |= (value.into() & BIT_MASK[nb_bits as usize]) << self.bit_pos;
89 self.bit_pos += nb_bits;
90 Ok(())
91 }
92
93 #[inline]
99 pub fn unchecked_add_bits(&mut self, value: BitContainer, nb_bits: u8) -> Result<()> {
100 if value >> nb_bits != 0 || nb_bits + self.bit_pos > CTNR_SIZE {
101 throw!(
102 AddBits,
103 format!(
104 "Error add bits fast (nb_bits {}) (bit_pos {})",
105 nb_bits, self.bit_pos
106 )
107 )
108 }
109 self.bits_container |= value << self.bit_pos;
110 self.bit_pos += nb_bits;
111 Ok(())
112 }
113
114 #[inline]
119 pub fn flush_bits(&mut self) {
120 let nb_bytes = (self.bit_pos >> 3) as usize;
121 self.stream.append(
122 &mut self
123 .bits_container
124 .to_le_bytes()
125 .to_vec()
126 .drain(0..nb_bytes)
127 .collect(),
128 );
129 self.bit_pos &= 7;
130 if nb_bytes == CTNR_BYTES_SIZE {
131 self.bits_container = 0
132 } else {
133 self.bits_container >>= nb_bytes << 3;
134 }
135 }
136
137 #[inline]
145 pub fn close_stream(&mut self) -> Result<()> {
146 if self.bit_pos == CTNR_SIZE {
147 self.flush_bits();
149 }
150 self.unchecked_add_bits(1, 1)?;
151 self.flush_bits();
152 if self.bits_container > 0 {
153 debug_test!("Push {:010b} into the stream", self.bits_container as u8);
154 self.stream.push(self.bits_container as u8);
155 self.bits_container = 0;
156 }
157 Ok(())
158 }
159}
160
161impl TryFrom<BitEstream> for BitDstream {
162 type Error = BitStreamError;
163
164 fn try_from(mut stream: BitEstream) -> Result<Self> {
165 if stream.stream.is_empty() {
166 throw!(EmptyStream)
167 }
168 let (bits_container, bits_consumed, _) = build_dstream_from_vec(&mut stream.stream)?;
169 Ok(BitDstream {
170 bits_container,
171 stream: stream.stream,
172 bits_consumed,
173 })
174 }
175}
176
177impl From<BitEstream> for Vec<u8> {
178 fn from(mut stream: BitEstream) -> Self {
179 stream.close_stream().unwrap();
180 stream.stream
181 }
182}
183
184impl From<&BitEstream> for Vec<u8> {
185 fn from(stream: &BitEstream) -> Self {
186 stream.stream.clone()
187 }
188}
189
190impl TryFrom<Vec<u8>> for BitDstream {
191 type Error = BitStreamError;
192
193 fn try_from(mut stream: Vec<u8>) -> Result<Self> {
194 if stream.is_empty() {
195 throw!(EmptyStream)
196 }
197 let (bits_container, bits_consumed, _) = build_dstream_from_vec(&mut stream)?;
198 Ok(BitDstream {
199 bits_container,
200 stream,
201 bits_consumed,
202 })
203 }
204}
205
206impl BitDstream {
207 #[inline]
212 pub fn look_bits(&mut self, nb_bits: u8) -> Result<BitContainer> {
213 debug_test!("Looking at bits {} {}", self.bits_consumed, nb_bits);
214 get_middle_bits(
215 self.bits_container,
216 CTNR_SIZE
218 .checked_sub(self.bits_consumed)
219 .unwrap_or_else(|| {
220 panic!(
221 "attempt to substract with overflow: \
222 substract the buffer container size {CTNR_SIZE} with current\
223 bits consumed by the reader {}",
224 self.bits_consumed
225 )
226 })
227 .checked_sub(nb_bits)
228 .unwrap_or_else(|| {
229 panic!(
230 "attempt to substract with overflow: \
231 substract the buffer container size {CTNR_SIZE} with current\
232 bits consumed by the reader {} and a given number of bits: {}",
233 self.bits_consumed, nb_bits
234 )
235 }),
236 nb_bits,
237 )
238 }
239
240 #[inline]
243 pub fn skip_bits(&mut self, nb_bits: u8) {
244 self.bits_consumed += nb_bits
245 }
246
247 #[inline]
253 pub fn read_bits(&mut self, nb_bits: u8) -> Result<BitContainer> {
254 let bits = self.look_bits(nb_bits)?;
255 self.skip_bits(nb_bits);
256 Ok(bits)
257 }
258
259 #[inline]
262 pub fn reload_container(&mut self) -> Result<bool> {
263 if self.bits_consumed > CTNR_SIZE {
264 throw!(BitsOverflow, "Stream consume overflow")
265 }
266 if self.stream.is_empty() {
267 return Ok(true);
268 }
269 let nb_bytes = (self.bits_consumed >> 3) as usize;
270 self.bits_consumed &= 7;
271 let mut ctnr = self.bits_container.to_le_bytes().to_vec();
272 let mut ctnr = ctnr.drain(..ctnr.len() - nb_bytes).collect::<Vec<u8>>();
273 self.stream.append(&mut ctnr);
274 let dstr = build_dstream_from_vec(&mut self.stream)?;
275 self.bits_consumed = if dstr.2 < CTNR_BYTES_SIZE {
276 CTNR_SIZE - (dstr.2 << 3) as u8
277 } else {
278 0
279 };
280 self.bits_container = dstr.0;
281 Ok(false)
282 }
283}
284
285#[inline]
292fn read_le(v: &[u8]) -> BitContainer {
293 debug_test!("Read LITTLE-ENDIAN : {:?}", v);
294 assert_eq!(
295 v.len(),
296 CTNR_BYTES_SIZE,
297 "Unexpected size of container, cannot transmute value"
298 );
299 BitContainer::from_le_bytes(v.try_into().unwrap())
300}
301
302#[inline]
303pub fn get_upper_bits(bits_container: BitContainer, start: u8) -> BitContainer {
304 bits_container >> start
305}
306
307#[inline]
308pub fn get_middle_bits(
309 bit_container: BitContainer,
310 start: u8,
311 nb_bits: u8,
312) -> Result<BitContainer> {
313 const REG_MASK: u8 = CTNR_SIZE - 1;
314 if nb_bits > BIT_MASK_SIZE {
315 throw!(BitsOverflow, format!("at get_middle_bits() : {}", nb_bits))
316 }
317 Ok((bit_container >> (start & REG_MASK)) & BIT_MASK[nb_bits as usize])
318}
319
320#[inline]
321pub fn get_lower_bits(bit_container: BitContainer, nb_bits: u8) -> Result<BitContainer> {
322 if nb_bits > BIT_MASK_SIZE {
323 throw!(BitsOverflow, format!("at get_lower_bits() : {}", nb_bits))
324 }
325 Ok(bit_container & BIT_MASK[nb_bits as usize])
326}
327
328#[inline]
333fn build_dstream_from_vec(stream: &mut Vec<u8>) -> Result<(BitContainer, u8, usize)> {
334 debug_test!(
335 "\nStart building a new build_dstream_from_vec of len : {}",
336 stream.len()
337 );
338 let bytes: usize;
339 let mut bits_container: BitContainer;
340 if stream.len() >= CTNR_BYTES_SIZE {
341 let bits: Vec<u8> = stream.drain(stream.len() - CTNR_BYTES_SIZE..).collect();
343 bits_container = read_le(&bits);
344 bytes = CTNR_BYTES_SIZE;
345 } else {
346 bytes = stream.len();
348 bits_container = stream[0] as BitContainer;
349 #[cfg(target_pointer_width = "64")]
350 {
351 if stream.len() == 7 {
352 bits_container += (stream.pop().unwrap() as BitContainer) << (CTNR_SIZE - 16);
353 }
354 if stream.len() == 6 {
355 bits_container += (stream.pop().unwrap() as BitContainer) << (CTNR_SIZE - 24);
356 }
357 if stream.len() == 5 {
358 bits_container += (stream.pop().unwrap() as BitContainer) << (CTNR_SIZE - 32);
359 }
360 if stream.len() == 4 {
361 bits_container += (stream.pop().unwrap() as BitContainer) << 24;
362 }
363 }
364 if stream.len() == 3 {
365 bits_container += (stream.pop().unwrap() as BitContainer) << 16;
366 }
367 if stream.len() == 2 {
368 bits_container += (stream.pop().unwrap() as BitContainer) << 8;
369 }
370 stream.clear(); }
372 Ok((bits_container, bits_container.leading_zeros() as u8, bytes))
373}