lewton/
bitpacking.rs

1// Vorbis decoder written in Rust
2//
3// Copyright (c) 2016 est31 <MTest31@outlook.com>
4// and contributors. All rights reserved.
5// Licensed under MIT license, or Apache 2 license,
6// at your option. Please see the LICENSE file
7// attached to this source distribution for details.
8
9/*!
10Vorbis bitpacking layer
11
12Functionality to read content from the bitpacking layer.
13
14Implements vorbis spec, section 2.
15
16The most important struct of this mod is the `BitpackCursor` struct.
17It can be instantiated using `BitpackCursor::new()`.
18
19Note that this implementation doesn't fully align with the spec in the regard that it assumes a byte is an octet.
20This is no problem on most architectures.
21This non-alignment to the spec is due to the fact that the rust language is highly leaned towards byte == u8,
22and doesn't even have a builtin single byte type.
23*/
24
25use ::huffman_tree::{VorbisHuffmanTree, PeekedDataLookupResult};
26
27/// A Cursor on slices to read numbers and bitflags, bit aligned.
28pub struct BitpackCursor <'a> {
29	bit_cursor :u8,
30	byte_cursor :usize,
31	inner :&'a[u8],
32}
33
34macro_rules! sign_extend {
35( $num:expr, $desttype:ident, $bit_cnt_large:expr, $bit_cnt_small:expr) => { {
36	let n = $num;
37	let res :$desttype = n as $desttype;
38	let k :u8 = $bit_cnt_large - $bit_cnt_small;
39	res << k >> k
40} }
41}
42
43#[test]
44fn test_sign_extend() {
45	assert_eq!(sign_extend!(0b00,  i8,  8,  2),  0);
46	assert_eq!(sign_extend!(0b01,  i8,  8,  2),  1);
47	assert_eq!(sign_extend!(0b11,  i8,  8,  2), -1);
48	assert_eq!(sign_extend!(0b111, i8,  8,  3), -1);
49	assert_eq!(sign_extend!(0b101, i8,  8,  3), -3);
50	assert_eq!(sign_extend!(0b01111110, i16, 16, 8),  126);
51	assert_eq!(sign_extend!(0b10000010, i16, 16, 8), -126);
52}
53
54/// Returns `num` bits of 1 (but never more than 8).
55fn mask_bits(num : u8) -> u8 {
56	!((!0u8).wrapping_shl(num as u32)) | if num >= 8 { 0xff } else { 0 }
57}
58
59// Same as mask_bits but different in a special case: for num % 8 == 0
60// Make sure that 0 <= num <= 8.
61fn bmask_bits(num : u8) -> u8 {
62	(!0u8).wrapping_shr(8 - num as u32)
63}
64
65#[test]
66fn test_mask_bits() {
67	assert_eq!(mask_bits(0), 0b00000000);
68	assert_eq!(mask_bits(1), 0b00000001);
69	assert_eq!(mask_bits(2), 0b00000011);
70	assert_eq!(mask_bits(3), 0b00000111);
71	assert_eq!(mask_bits(4), 0b00001111);
72	assert_eq!(mask_bits(5), 0b00011111);
73	assert_eq!(mask_bits(6), 0b00111111);
74	assert_eq!(mask_bits(7), 0b01111111);
75	assert_eq!(mask_bits(8), 0b11111111);
76}
77
78#[test]
79fn test_bmask_bits() {
80	assert_eq!(bmask_bits(0), 0b11111111);
81	assert_eq!(bmask_bits(1), 0b00000001);
82	assert_eq!(bmask_bits(2), 0b00000011);
83	assert_eq!(bmask_bits(3), 0b00000111);
84	assert_eq!(bmask_bits(4), 0b00001111);
85	assert_eq!(bmask_bits(5), 0b00011111);
86	assert_eq!(bmask_bits(6), 0b00111111);
87	assert_eq!(bmask_bits(7), 0b01111111);
88	assert_eq!(bmask_bits(8), 0b11111111);
89}
90
91// The main macro to read bit aligned
92// Note that `$octetnum` is the number of octets in $bitnum ($bitnum / 8 rounded down)
93macro_rules! bpc_read_body {
94( $rettype:ident, $bitnum:expr, $octetnum:expr, $selfarg:expr ) => { {
95	let last_octet_partial :usize = ($bitnum as i8 - $octetnum as i8 * 8 > 0) as usize;
96	let octetnum_rounded_up :usize = last_octet_partial + $octetnum;
97	let bit_cursor_after = ($selfarg.bit_cursor + $bitnum) % 8;
98
99	if ($selfarg.bit_cursor + $bitnum) as usize > 8 * octetnum_rounded_up {
100		/*println!("Reading {} bits (octetnum={}, last_partial={}, total_touched={}+1)",
101			$bitnum, $octetnum, last_octet_partial, $octetnum + last_octet_partial);
102		println!("    byte_c={}; bit_c={}", $selfarg.byte_cursor, $selfarg.bit_cursor);// */
103		/*print!("Reading {} bits (byte_c={}; bit_c={}) [] = {:?}", $bitnum,
104			$selfarg.byte_cursor, $selfarg.bit_cursor,
105			&$selfarg.inner[$selfarg.byte_cursor .. $selfarg.byte_cursor +
106			1 + octetnum_rounded_up]);// */
107		if $selfarg.byte_cursor + 1 + octetnum_rounded_up > $selfarg.inner.len() {
108			//println!(" => Out of bounds :\\");
109			return Err(());
110		}
111		let buf = &$selfarg.inner[$selfarg.byte_cursor
112			.. $selfarg.byte_cursor + 1 + octetnum_rounded_up];
113		let mut res :$rettype = buf[0] as $rettype;
114		res >>= $selfarg.bit_cursor;
115		let mut cur_bit_cursor = 8 - $selfarg.bit_cursor;
116		for i in 1 .. octetnum_rounded_up {
117			res |= (buf[i] as $rettype) << cur_bit_cursor;
118			cur_bit_cursor += 8;
119		}
120		let last_bits = buf[octetnum_rounded_up] & mask_bits(bit_cursor_after);
121		res |= (last_bits as $rettype) << cur_bit_cursor;
122		$selfarg.byte_cursor += octetnum_rounded_up;
123		$selfarg.bit_cursor = bit_cursor_after;
124		//println!(" => {:?}", res);
125		Ok(res)
126	} else {
127		/*println!("Reading {} bits (octetnum={}, last_partial={}, total_touched={})",
128			$bitnum, $octetnum, last_octet_partial, $octetnum + last_octet_partial);
129		println!("    byte_c={}; bit_c={}", $selfarg.byte_cursor, $selfarg.bit_cursor);// */
130		/*print!("Reading {} bits (byte_c={}; bit_c={}) [] = {:?}", $bitnum,
131			$selfarg.byte_cursor, $selfarg.bit_cursor,
132			&$selfarg.inner[$selfarg.byte_cursor .. $selfarg.byte_cursor +
133			octetnum_rounded_up]);// */
134		if $selfarg.byte_cursor + octetnum_rounded_up > $selfarg.inner.len() {
135			//println!(" => Out of bounds :\\");
136			return Err(());
137		}
138		let buf = &$selfarg.inner[$selfarg.byte_cursor ..
139			$selfarg.byte_cursor + octetnum_rounded_up];
140		let mut res :$rettype = buf[0] as $rettype;
141		res >>= $selfarg.bit_cursor;
142		if $bitnum <= 8 {
143			res &= mask_bits($bitnum) as $rettype;
144		}
145		let mut cur_bit_cursor = 8 - $selfarg.bit_cursor;
146		for i in 1 .. octetnum_rounded_up - 1 {
147			res |= (buf[i] as $rettype) << cur_bit_cursor;
148			cur_bit_cursor += 8;
149		}
150		if $bitnum > 8 {
151			let last_bits = buf[octetnum_rounded_up - 1] & bmask_bits(bit_cursor_after);
152			res |= (last_bits as $rettype) << cur_bit_cursor;
153		}
154		$selfarg.byte_cursor += $octetnum;
155		$selfarg.byte_cursor += ($selfarg.bit_cursor == 8 - ($bitnum % 8)) as usize;
156		$selfarg.bit_cursor = bit_cursor_after;
157		//println!(" => {:?}", res);
158		Ok(res)
159	}
160} }
161}
162
163// The main macro to peek bit aligned
164// Note that `$octetnum` is the number of octets in $bitnum ($bitnum / 8 rounded down)
165macro_rules! bpc_peek_body {
166( $rettype:ident, $bitnum:expr, $octetnum:expr, $selfarg:expr ) => { {
167	let last_octet_partial :usize = ($bitnum as i8 - $octetnum as i8 * 8 > 0) as usize;
168	let octetnum_rounded_up :usize = last_octet_partial + $octetnum;
169	let bit_cursor_after = ($selfarg.bit_cursor + $bitnum) % 8;
170
171	if ($selfarg.bit_cursor + $bitnum) as usize > 8 * octetnum_rounded_up {
172		/*println!("Reading {} bits (octetnum={}, last_partial={}, total_touched={}+1)",
173			$bitnum, $octetnum, last_octet_partial, $octetnum + last_octet_partial);
174		println!("    byte_c={}; bit_c={}", $selfarg.byte_cursor, $selfarg.bit_cursor);// */
175		/*print!("Reading {} bits (byte_c={}; bit_c={}) [] = {:?}", $bitnum,
176			$selfarg.byte_cursor, $selfarg.bit_cursor,
177			&$selfarg.inner[$selfarg.byte_cursor .. $selfarg.byte_cursor +
178			1 + octetnum_rounded_up]);// */
179		if $selfarg.byte_cursor + 1 + octetnum_rounded_up > $selfarg.inner.len() {
180			//println!(" => Out of bounds :\\");
181			return Err(());
182		}
183		let buf = &$selfarg.inner[$selfarg.byte_cursor
184			.. $selfarg.byte_cursor + 1 + octetnum_rounded_up];
185		let mut res :$rettype = buf[0] as $rettype;
186		res >>= $selfarg.bit_cursor;
187		let mut cur_bit_cursor = 8 - $selfarg.bit_cursor;
188		for i in 1 .. octetnum_rounded_up {
189			res |= (buf[i] as $rettype) << cur_bit_cursor;
190			cur_bit_cursor += 8;
191		}
192		let last_bits = buf[octetnum_rounded_up] & mask_bits(bit_cursor_after);
193		res |= (last_bits as $rettype) << cur_bit_cursor;
194		//println!(" => {:?}", res);
195		Ok(res)
196	} else {
197		/*println!("Reading {} bits (octetnum={}, last_partial={}, total_touched={})",
198			$bitnum, $octetnum, last_octet_partial, $octetnum + last_octet_partial);
199		println!("    byte_c={}; bit_c={}", $selfarg.byte_cursor, $selfarg.bit_cursor);// */
200		/*print!("Reading {} bits (byte_c={}; bit_c={}) [] = {:?}", $bitnum,
201			$selfarg.byte_cursor, $selfarg.bit_cursor,
202			&$selfarg.inner[$selfarg.byte_cursor .. $selfarg.byte_cursor +
203			octetnum_rounded_up]);// */
204		if $selfarg.byte_cursor + octetnum_rounded_up > $selfarg.inner.len() {
205			//println!(" => Out of bounds :\\");
206			return Err(());
207		}
208		let buf = &$selfarg.inner[$selfarg.byte_cursor ..
209			$selfarg.byte_cursor + octetnum_rounded_up];
210		let mut res :$rettype = buf[0] as $rettype;
211		res >>= $selfarg.bit_cursor;
212		if $bitnum <= 8 {
213			res &= mask_bits($bitnum) as $rettype;
214		}
215		let mut cur_bit_cursor = 8 - $selfarg.bit_cursor;
216		for i in 1 .. octetnum_rounded_up - 1 {
217			res |= (buf[i] as $rettype) << cur_bit_cursor;
218			cur_bit_cursor += 8;
219		}
220		if $bitnum > 8 {
221			let last_bits = buf[octetnum_rounded_up - 1] & bmask_bits(bit_cursor_after);
222			res |= (last_bits as $rettype) << cur_bit_cursor;
223		}
224		//println!(" => {:?}", res);
225		Ok(res)
226	}
227} }
228}
229
230// The main macro to advance bit aligned
231// Note that `$octetnum` is the number of octets in $bitnum ($bitnum / 8 rounded down)
232macro_rules! bpc_advance_body {
233( $bitnum:expr, $octetnum:expr, $selfarg:expr ) => { {
234	let last_octet_partial :usize = ($bitnum as i8 - $octetnum as i8 * 8 > 0) as usize;
235	let octetnum_rounded_up :usize = last_octet_partial + $octetnum;
236	let bit_cursor_after = ($selfarg.bit_cursor + $bitnum) % 8;
237
238	if ($selfarg.bit_cursor + $bitnum) as usize > 8 * octetnum_rounded_up {
239		$selfarg.byte_cursor += octetnum_rounded_up;
240		$selfarg.bit_cursor = bit_cursor_after;
241		//println!(" => {:?}", res);
242		Ok(())
243	} else {
244		$selfarg.byte_cursor += $octetnum;
245		$selfarg.byte_cursor += ($selfarg.bit_cursor == 8 - ($bitnum % 8)) as usize;
246		$selfarg.bit_cursor = bit_cursor_after;
247		//println!(" => {:?}", res);
248		Ok(())
249	}
250} }
251}
252
253macro_rules! uk_reader {
254( $fnname:ident, $rettype:ident, $bitnum:expr, $octetnum:expr) => {
255	#[inline]
256	pub fn $fnname(&mut self) -> Result<$rettype, ()> {
257		bpc_read_body!($rettype, $bitnum, $octetnum, self)
258	}
259}
260}
261
262macro_rules! ik_reader {
263( $fnname:ident, $rettype:ident, $bitnum_of_rettype:expr, $bitnum:expr, $octetnum:expr) => {
264	#[inline]
265	pub fn $fnname(&mut self) -> Result<$rettype, ()> {
266		Ok(sign_extend!(try!(
267			bpc_read_body!($rettype, $bitnum, $octetnum, self)),
268			$rettype, $bitnum_of_rettype, $bitnum))
269	}
270}
271}
272
273macro_rules! ik_dynamic_reader {
274( $fnname:ident, $rettype:ident, $bitnum_of_rettype:expr) => {
275	#[inline]
276	pub fn $fnname(&mut self, bit_num :u8) -> Result<$rettype, ()> {
277		let octet_num :usize = (bit_num / 8) as usize;
278		assert!(bit_num <= $bitnum_of_rettype);
279		Ok(sign_extend!(try!(
280			bpc_read_body!($rettype, bit_num, octet_num, self)),
281			$rettype, $bitnum_of_rettype, bit_num))
282	}
283}
284}
285
286macro_rules! uk_dynamic_reader {
287( $fnname:ident, $rettype:ident, $bit_num_max:expr) => {
288	#[inline]
289	pub fn $fnname(&mut self, bit_num :u8) -> Result<$rettype, ()> {
290		let octet_num :usize = (bit_num / 8) as usize;
291		if bit_num == 0 {
292			// TODO: one day let bpc_read_body handle this,
293			// if its smartly doable in there.
294			// For why it is required, see comment in the
295			// test_bitpacking_reader_empty function.
296			return Ok(0);
297		}
298		assert!(bit_num <= $bit_num_max);
299		bpc_read_body!($rettype, bit_num, octet_num, self)
300	}
301}
302}
303
304fn float32_unpack(val :u32) -> f32 {
305	let sgn = val & 0x80000000;
306	let exp = (val & 0x7fe00000) >> 21;
307	let mantissa = (val & 0x1fffff) as f64;
308	let signed_mantissa = if sgn != 0 {
309		-mantissa
310	} else {
311		mantissa
312	};
313	return signed_mantissa as f32 * (exp as f32 - 788.0).exp2();
314}
315
316#[test]
317fn test_float_32_unpack() {
318	// Values were printed out from what stb_vorbis
319	// calculated for this function from a test file.
320	assert_eq!(float32_unpack(1611661312),      1.000000);
321	assert_eq!(float32_unpack(1616117760),      5.000000);
322	assert_eq!(float32_unpack(1618345984),     11.000000);
323	assert_eq!(float32_unpack(1620115456),     17.000000);
324	assert_eq!(float32_unpack(1627381760),    255.000000);
325	assert_eq!(float32_unpack(3759144960),     -1.000000);
326	assert_eq!(float32_unpack(3761242112),     -2.000000);
327	assert_eq!(float32_unpack(3763339264),     -4.000000);
328	assert_eq!(float32_unpack(3763601408),     -5.000000);
329	assert_eq!(float32_unpack(3765436416),     -8.000000);
330	assert_eq!(float32_unpack(3765829632),    -11.000000);
331	assert_eq!(float32_unpack(3768451072),    -30.000000);
332	assert_eq!(float32_unpack(3772628992),   -119.000000);
333	assert_eq!(float32_unpack(3780634624),  -1530.000000);
334}
335
336#[test]
337fn test_float_32_unpack_issue_24() {
338	// Regression test for issue #24, a
339	// mismatch in decoded output for audio_simple_with_error.ogg
340	// and singlemap-test.ogg.
341	// The values are taken from the codebook_delta_value and
342	// codebook_minimum_value values of the singlemap-test.ogg file.
343	// The expected values come from stb_vorbis.
344	assert_eq!(float32_unpack(1628434432), 255.0);
345	assert_eq!(float32_unpack(1621655552), 17.0);
346	assert_eq!(float32_unpack(1619722240), 11.0);
347	assert_eq!(float32_unpack(1613234176), 1.0);
348	assert_eq!(float32_unpack(3760717824), -1.0);
349	assert_eq!(float32_unpack(3762814976), -2.0);
350	assert_eq!(float32_unpack(3764912128), -4.0);
351	assert_eq!(float32_unpack(3765043200), -5.0);
352	assert_eq!(float32_unpack(3767009280), -8.0);
353	assert_eq!(float32_unpack(3767205888), -11.0);
354	assert_eq!(float32_unpack(3769565184), -30.0);
355	assert_eq!(float32_unpack(3773751296), -119.0);
356	assert_eq!(float32_unpack(3781948416), -1530.0);
357}
358
359// allow some code that is only used in the tests
360#[allow(dead_code)]
361impl <'a> BitpackCursor <'a> {
362
363	/// Creates a new `BitpackCursor` for the given data array
364	pub fn new(arr : &'a[u8]) -> BitpackCursor {
365		return BitpackCursor::<'a> { bit_cursor: 0, byte_cursor: 0, inner: arr };
366	}
367
368	// Unsigned, non-dynamic reader methods
369
370	// u32 based
371
372	// TODO add here if needed
373	uk_reader!(read_u32, u32, 32, 4);
374	// TODO add here if needed
375	uk_reader!(read_u24, u32, 24, 3);
376	// TODO add here if needed
377
378	// u16 based
379
380	uk_reader!(read_u16, u16, 16, 2);
381
382	// TODO add here if needed
383	uk_reader!(read_u13, u16, 13, 1);
384	// TODO add here if needed
385
386	// u8 based
387	uk_reader!(read_u8, u8, 8, 1);
388	uk_reader!(read_u7, u8, 7, 0);
389	uk_reader!(read_u6, u8, 6, 0);
390	uk_reader!(read_u5, u8, 5, 0);
391	uk_reader!(read_u4, u8, 4, 0);
392	uk_reader!(read_u3, u8, 3, 0);
393	uk_reader!(read_u2, u8, 2, 0);
394	uk_reader!(read_u1, u8, 1, 0);
395
396	// Returning bool:
397	#[inline]
398	pub fn read_bit_flag(&mut self) -> Result<bool, ()> {
399		return Ok(try!(self.read_u1()) == 1);
400	}
401
402	// Unsigned dynamic reader methods
403	// They panic if you give them invalid params
404	// (bit_num larger than maximum allowed bit number for the type)
405	uk_dynamic_reader!(read_dyn_u8,  u8,  8);
406	uk_dynamic_reader!(read_dyn_u16, u16, 16);
407	uk_dynamic_reader!(read_dyn_u32, u32, 32);
408	uk_dynamic_reader!(read_dyn_u64, u64, 64);
409
410	// Signed non-dynamic reader methods
411
412	ik_reader!(read_i32, i32, 32, 32, 4);
413	// TODO add here if needed
414
415	ik_reader!(read_i8, i8, 8, 8, 1);
416	ik_reader!(read_i7, i8, 8, 7, 0);
417	// TODO add here if needed
418
419	// Signed dynamic reader methods
420	// They panic if you give them invalid params
421	// (bit_num larger than maximum allowed bit number for the type)
422	ik_dynamic_reader!(read_dyn_i8,  i8,  8);
423	ik_dynamic_reader!(read_dyn_i16, i16, 16);
424	ik_dynamic_reader!(read_dyn_i32, i32, 32);
425
426	// Float reading methods
427
428	/// Reads a single floating point number in the vorbis-float32 format
429	pub fn read_f32(&mut self) -> Result<f32, ()> {
430		let val = try!(self.read_u32());
431		Ok(float32_unpack(val))
432	}
433
434	/// Peeks 8 bits of non read yet content without advancing the reader
435	#[inline]
436	pub fn peek_u8(&self) -> Result<u8, ()> {
437		bpc_peek_body!(u8, 8, 1, self)
438	}
439
440	// Advances the reader by the given number of bits (up to 8).
441	pub fn advance_dyn_u8(&mut self, bit_num :u8) -> Result<(), ()> {
442		let octet_num :usize = (bit_num / 8) as usize;
443		if bit_num == 0 {
444			// TODO: one day let bpc_advance_body handle this,
445			// if its smartly doable in there.
446			// For why it is required, see comment in the
447			// test_bitpacking_reader_empty function.
448			return Ok(());
449		}
450		assert!(bit_num <= 8);
451		bpc_advance_body!(bit_num, octet_num, self)
452	}
453
454	/// Reads a huffman word using the codebook abstraction
455	pub fn read_huffman(&mut self, tree :&VorbisHuffmanTree) -> Result<u32, ()> {
456		//let mut c :usize = 0;
457		//let mut w :usize = 0;
458		let mut iter = match self.peek_u8() {
459			Ok(data) => match tree.lookup_peeked_data(8, data as u32) {
460				PeekedDataLookupResult::Iter(advance, iter) => {
461					try!(self.advance_dyn_u8(advance));
462					iter
463				},
464				PeekedDataLookupResult::PayloadFound(advance, payload) => {
465					try!(self.advance_dyn_u8(advance));
466					return Ok(payload);
467				},
468			},
469			Err(_) => tree.iter(),
470		};
471
472		loop {
473			let b = try!(self.read_bit_flag());
474			/*
475			c +=1;
476			w >>= 1;
477			w |= (b as usize) << 63;
478			// Put this into the Some arm of the match below in order to debug:
479			{print!("({}:{}:{}) ", w >> (64 - c), v, c); }
480			// */
481			match iter.next(b) {
482				Some(v) => return Ok(v),
483				None => (),
484			}
485		}
486	}
487}
488
489#[test]
490fn test_bitpacking_reader_static() {
491	// Test vectors taken from Vorbis I spec, section 2.1.6
492	let test_arr = &[0b11111100, 0b01001000, 0b11001110, 0b00000110];
493	let mut cur = BitpackCursor::new(test_arr);
494	assert_eq!(cur.read_u4().unwrap(),  12);
495	assert_eq!(cur.read_u3().unwrap(),  7);
496	assert_eq!(cur.read_u7().unwrap(),  17);
497	assert_eq!(cur.read_u13().unwrap(), 6969);
498}
499
500#[test]
501fn test_bitpacking_reader_dynamic() {
502	// Test vectors taken from Vorbis I spec, section 2.1.6
503	let test_arr = &[0b11111100, 0b01001000, 0b11001110, 0b00000110];
504	let mut cur = BitpackCursor::new(test_arr);
505	assert_eq!(cur.read_dyn_u8(4).unwrap(),   12);
506	assert_eq!(cur.read_dyn_u8(3).unwrap(),   7);
507	assert_eq!(cur.read_dyn_u16(7).unwrap(),  17);
508	assert_eq!(cur.read_dyn_u16(13).unwrap(), 6969);
509
510	// Regression test for bug
511	let test_arr = &[93, 92];
512	let mut cur = BitpackCursor::new(test_arr);
513	assert_eq!(cur.read_dyn_u32(10).unwrap(), 93);
514}
515
516#[test]
517fn test_bitpacking_reader_empty() {
518	// Same as the normal bitpacking test
519	// but with some additional empty reads.
520	//
521	// This is expected to happen by the vorbis spec.
522	// For example, the mode_number read in the audio packet
523	// decode at first position may be 0 bit long (if there
524	// is only one mode, ilog([vorbis_mode_count] - 1) is zero).
525
526	let test_arr = &[0b11111100, 0b01001000, 0b11001110, 0b00000110];
527	let mut cur = BitpackCursor::new(test_arr);
528	assert_eq!(cur.read_dyn_u8(4).unwrap(),   12);
529	assert_eq!(cur.read_dyn_u8(0).unwrap(),   0);
530	assert_eq!(cur.read_dyn_u8(0).unwrap(),   0);
531	assert_eq!(cur.read_dyn_u8(3).unwrap(),   7);
532	assert_eq!(cur.read_dyn_u8(0).unwrap(),   0);
533	assert_eq!(cur.read_dyn_u16(7).unwrap(),  17);
534	assert_eq!(cur.read_dyn_u16(0).unwrap(),   0);
535	assert_eq!(cur.read_dyn_u16(0).unwrap(),   0);
536	assert_eq!(cur.read_dyn_u16(13).unwrap(), 6969);
537	assert_eq!(cur.read_dyn_u16(0).unwrap(),   0);
538}
539
540#[test]
541fn test_bitpacking_reader_byte_aligned() {
542	// Check that bitpacking readers work with "normal" byte aligned types:
543	let test_arr = &[0x00, 0x00, 0x00, 0x00, 0x01];
544	let mut cur = BitpackCursor::new(test_arr);
545	assert_eq!(cur.read_dyn_u32(32).unwrap(), 0);
546	assert_eq!(cur.read_dyn_u8(8).unwrap(),   1);
547
548	// We not just check here whether it works for byte aligned
549	// "normal" (non-dynamic) reader methods, we also check
550	// whether, after reading first one, then seven bits,
551	// it "gets back" to byte alignment (and increases the byte ctr)
552	let test_arr = &[0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01];
553	let mut cur = BitpackCursor::new(test_arr);
554	assert_eq!(cur.read_u1().unwrap(), 1);
555	assert_eq!(cur.read_u7().unwrap(), 4);
556	assert_eq!(cur.read_i8().unwrap(), 2);
557	assert_eq!(cur.read_u32().unwrap(), 0);
558	assert_eq!(cur.read_u8().unwrap(), 1);
559}
560
561#[test]
562fn test_capture_pattern_nonaligned() {
563	// Regression test from test OGG file
564	// Tests for proper codebook capture
565	// pattern reading.
566	//
567	// The OGG vorbis capture pattern
568	// is a three octet (24 bits) value.
569	//
570	// The first block tests capture pattern
571	// reading in a byte aligned scenario.
572	// The actually problematic part was
573	// the second block: it tests capture
574	// pattern reading in a non-aligned
575	// situation.
576
577	let capture_pattern_arr = &[0x42, 0x43, 0x56];
578	let mut cur = BitpackCursor::new(capture_pattern_arr);
579	assert_eq!(cur.read_u24().unwrap(), 0x564342);
580
581	let test_arr = &[0x28, 0x81, 0xd0, 0x90, 0x55, 0x00, 0x00];
582	let mut cur = BitpackCursor::new(test_arr);
583	cur.read_u5().unwrap(); // some value we are not interested in
584	cur.read_u5().unwrap(); // some value we are not interested in
585	assert_eq!(cur.read_u4().unwrap(), 0);
586	assert_eq!(cur.read_u24().unwrap(), 0x564342);
587	// Ensure that we incremented by only three bytes, not four
588	assert_eq!(cur.read_u16().unwrap(), 1);
589}