lewton/
header.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/*!
10Header decoding
11
12This module takes care of decoding of the three vorbis headers:
13
141. Identification
152. Comment
163. Setup
17
18It builds only on the internal bitpacking layer and the internal
19huffman tree handling mod. Everything else about the headers is
20decoded in this mod.
21*/
22
23use std::error;
24use std::fmt;
25use ::bitpacking::BitpackCursor;
26use ::huffman_tree::{VorbisHuffmanTree, HuffmanError};
27use std::io::{Cursor, ErrorKind, Read, Error};
28use byteorder::{ReadBytesExt, LittleEndian};
29use std::string::FromUtf8Error;
30use header_cached::{CachedBlocksizeDerived, compute_bark_map_cos_omega};
31
32/// Errors that can occur during Header decoding
33#[derive(Debug)]
34#[derive(PartialEq)]
35pub enum HeaderReadError {
36	EndOfPacket,
37	/// If the passed data don't start with the "vorbis"
38	/// capture pattern, this error is returned.
39	NotVorbisHeader,
40	UnsupportedVorbisVersion,
41	/// If the header violates the vorbis spec
42	HeaderBadFormat,
43	/// The given packet indeed seems to be a vorbis header,
44	/// but it looks like it is a different header type than
45	/// the function it was passed to.
46	///
47	/// It is not guaranteed that the type is a valid header type.
48	HeaderBadType(u8),
49	/// The given packet does not seem to be a header as per vorbis spec,
50	/// instead it seems to be an audio packet.
51	HeaderIsAudio,
52	Utf8DecodeError,
53	/// If the needed memory isn't addressable by us
54	///
55	/// This error is returned if a calculation yielded a higher value for
56	/// an internal buffer size that doesn't fit into the platform's address range.
57	/// Note that if we "simply" encounter an allocation failure (OOM, etc),
58	/// we do what libstd does in these cases: crash.
59	///
60	/// This error is not automatically an error of the passed data,
61	/// but rather is due to insufficient decoder hardware.
62	BufferNotAddressable,
63}
64
65// For the () error type returned by the bitpacking layer
66// TODO that type choice was a bit unfortunate,
67// perhaps one day fix this
68impl From<()> for HeaderReadError {
69	fn from(_ :()) -> HeaderReadError {
70		HeaderReadError::EndOfPacket
71	}
72}
73
74impl From<HuffmanError> for HeaderReadError {
75	fn from(_ :HuffmanError) -> HeaderReadError {
76		HeaderReadError::HeaderBadFormat
77	}
78}
79
80impl From<Error> for HeaderReadError {
81	fn from(err :Error) -> HeaderReadError {
82		match err.kind() {
83			ErrorKind::UnexpectedEof => HeaderReadError::EndOfPacket,
84			_ => panic!("Non EOF Error occured when reading from Cursor<&[u8]>: {}", err),
85		}
86	}
87}
88
89impl From<FromUtf8Error> for HeaderReadError {
90	fn from(_ :FromUtf8Error) -> HeaderReadError {
91		HeaderReadError::Utf8DecodeError
92	}
93}
94
95impl error::Error for HeaderReadError {}
96
97impl fmt::Display for HeaderReadError {
98	fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
99		let description = match self {
100			HeaderReadError::EndOfPacket => "End of packet reached.",
101			HeaderReadError::NotVorbisHeader => "The packet is not a vorbis header",
102			HeaderReadError::UnsupportedVorbisVersion => "The vorbis version is not supported",
103			HeaderReadError::HeaderBadFormat => "Invalid header",
104			HeaderReadError::HeaderBadType(_) => "Invalid/unexpected header type",
105			HeaderReadError::HeaderIsAudio => "Packet seems to be audio",
106			HeaderReadError::Utf8DecodeError => "UTF-8 decoding error",
107			HeaderReadError::BufferNotAddressable => "Requested to create buffer of non-addressable size",
108		};
109		write!(fmt, "{}", description)
110	}
111}
112
113/// Macro to convert values of any unsigned integral non-usize type to
114/// usize, and then check whether there had been any losses due to conversion.
115///
116/// If there were, it will return the BufferNotAddressable error.
117macro_rules! convert_to_usize {
118( $val:expr, $val_type:ident ) => { {
119	let converted :usize = $val as usize;
120	if $val != converted as $val_type {
121		try!(Err(HeaderReadError::BufferNotAddressable));
122	}
123	converted
124}}
125}
126
127// Internal function, tries to find out whether the
128// data returned by rdr belong to a vorbis header
129// On success it returns Some(n) with n as packet type
130// (you must check that n from 1,3,5)
131macro_rules! read_header_begin_body {
132( $rdr:expr ) => { {
133	let res = try!($rdr.read_u8());
134	if res & 1 == 0 {
135		// This is an audio packet per vorbis spec, if anything.
136		// (audio packets have their first bit set to 0,
137		// header packets have it set to 1)
138		try!(Err(HeaderReadError::HeaderIsAudio));
139	}
140	let is_vorbis =
141		try!($rdr.read_u8()) == 0x76 && // 'v'
142		try!($rdr.read_u8()) == 0x6f && // 'o'
143		try!($rdr.read_u8()) == 0x72 && // 'r'
144		try!($rdr.read_u8()) == 0x62 && // 'b'
145		try!($rdr.read_u8()) == 0x69 && // 'i'
146		try!($rdr.read_u8()) == 0x73;   // 's'
147	if !is_vorbis {
148		try!(Err(HeaderReadError::NotVorbisHeader));
149	}
150	return Ok(res);
151}}
152}
153fn read_header_begin(rdr :&mut BitpackCursor) -> Result<u8, HeaderReadError> {
154	read_header_begin_body!(rdr)
155}
156fn read_header_begin_cursor(rdr :&mut Cursor<&[u8]>) -> Result<u8, HeaderReadError> {
157	read_header_begin_body!(rdr)
158}
159
160
161#[test]
162fn test_read_hdr_begin() {
163	// Only tests flawed header begins, correct headers
164	// are tested later by the test methods for the headers
165
166	// Flawed ident header (see char before the /**/)
167	let test_arr = &[0x01, 0x76, 0x6f, 0x72,
168	0x62, 0x69, 0x72, /**/ 0x00, 0x00, 0x00, 0x00, 0x02,
169	0x44, 0xac, 0x00,      0x00, 0x00, 0x00, 0x00, 0x00,
170	0x80, 0xb5, 0x01,      0x00, 0x00, 0x00, 0x00, 0x00,
171	0xb8, 0x01];
172	let mut rdr :BitpackCursor = BitpackCursor::new(test_arr);
173	assert_eq!(read_header_begin(&mut rdr), Err(HeaderReadError::NotVorbisHeader));
174}
175
176/// The set of the three Vorbis headers
177pub type HeaderSet = (IdentHeader, CommentHeader, SetupHeader);
178
179/**
180Representation for the identification header
181
182The identification header is the first of the three
183headers inside each vorbis stream.
184
185It covers basic information about the stream.
186*/
187pub struct IdentHeader {
188	/// The number of audio channels in the stream
189	pub audio_channels :u8,
190	/// The sample rate of the stream
191	pub audio_sample_rate :u32,
192	/// The maximum bit rate of the stream
193	///
194	/// Note that this value is only a hint
195	/// and may be off by a large amount.
196	pub bitrate_maximum :i32,
197	/// The nominal bit rate of the stream
198	///
199	/// Note that this value is only a hint
200	/// and may be off by a large amount.
201	pub bitrate_nominal :i32,
202	/// The minimum bit rate of the stream
203	///
204	/// Note that this value is only a hint
205	/// and may be off by a large amount.
206	pub bitrate_minimum :i32,
207	pub blocksize_0 :u8,
208	pub blocksize_1 :u8,
209	pub(crate) cached_bs_derived :[CachedBlocksizeDerived; 2],
210}
211
212/**
213Reading the Identification header
214
215If it returns Err(sth) when being called with the first packet in a stream,
216the whole stream is to be considered undecodable as per the Vorbis spec.
217The function returns Err(`HeaderReadError::HeaderBadType`) if the header type
218doesn't match the ident header.
219*/
220pub fn read_header_ident(packet :&[u8]) -> Result<IdentHeader, HeaderReadError> {
221	let mut rdr = BitpackCursor::new(packet);
222	let hd_id = try!(read_header_begin(&mut rdr));
223	if hd_id != 1 {
224		try!(Err(HeaderReadError::HeaderBadType(hd_id)));
225	}
226	let vorbis_version = try!(rdr.read_u32());
227	if vorbis_version != 0 {
228		try!(Err(HeaderReadError::UnsupportedVorbisVersion));
229	}
230	let audio_channels = try!(rdr.read_u8());
231	let audio_sample_rate = try!(rdr.read_u32());
232	let bitrate_maximum = try!(rdr.read_i32());
233	let bitrate_nominal = try!(rdr.read_i32());
234	let bitrate_minimum = try!(rdr.read_i32());
235	let blocksize_0 = try!(rdr.read_u4());
236	let blocksize_1 = try!(rdr.read_u4());
237	let framing = try!(rdr.read_u8());
238	if blocksize_0 < 6 || blocksize_0 > 13 ||
239			blocksize_1 < 6 || blocksize_1 > 13 ||
240			(framing != 1) || blocksize_0 > blocksize_1 ||
241			audio_channels == 0 || audio_sample_rate == 0 {
242		try!(Err(HeaderReadError::HeaderBadFormat));
243	}
244	let hdr :IdentHeader = IdentHeader {
245		audio_channels,
246		audio_sample_rate,
247		bitrate_maximum,
248		bitrate_nominal,
249		bitrate_minimum,
250		blocksize_0,
251		blocksize_1,
252		cached_bs_derived : [
253			CachedBlocksizeDerived::from_blocksize(blocksize_0),
254			CachedBlocksizeDerived::from_blocksize(blocksize_1),
255		],
256	};
257	return Ok(hdr);
258}
259
260#[test]
261fn test_read_header_ident() {
262	// Valid ident header
263	let test_arr = &[0x01, 0x76, 0x6f, 0x72,
264	0x62, 0x69, 0x73, 0x00, 0x00, 0x00, 0x00, 0x02,
265	0x44, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266	0x80, 0xb5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
267	0xb8, 0x01];
268	let hdr = read_header_ident(test_arr).unwrap();
269	assert_eq!(hdr.audio_channels, 2);
270	assert_eq!(hdr.audio_sample_rate, 0x0000ac44);
271	assert_eq!(hdr.bitrate_maximum, 0);
272	assert_eq!(hdr.bitrate_nominal, 0x0001b580);
273	assert_eq!(hdr.bitrate_minimum, 0);
274	assert_eq!(hdr.blocksize_0, 8);
275	assert_eq!(hdr.blocksize_1, 11);
276}
277
278/**
279Representation of the comment header
280
281The comment header is the second of the three
282headers inside each vorbis stream.
283
284It contains text comment metadata
285about the stream, encoded as key-value pairs,
286and the vendor name.
287*/
288#[derive(Clone, PartialEq, Eq, Hash, Debug)]
289pub struct CommentHeader {
290	/// An identification string of the
291	/// software/library that encoded
292	/// the stream.
293	pub vendor :String,
294	/// A key-value list of the comments
295	/// attached to the stream.
296	pub comment_list :Vec<(String, String)>,
297}
298
299/**
300Reading the Comment header
301
302You should call this function with the second packet in the stream.
303
304The function does not check whether the comment field names consist
305of characters `0x20` through `0x7D` (`0x3D` excluded), as the vorbis
306spec requires.
307*/
308pub fn read_header_comment(packet :&[u8]) -> Result<CommentHeader, HeaderReadError> {
309	let mut rdr = Cursor::new(packet);
310	let hd_id = try!(read_header_begin_cursor(&mut rdr));
311	if hd_id != 3 {
312		try!(Err(HeaderReadError::HeaderBadType(hd_id)));
313	}
314	// First read the vendor string
315	let vendor_length = try!(rdr.read_u32::<LittleEndian>()) as usize;
316	let mut vendor_buf = vec![0; vendor_length]; // TODO fix this, we initialize memory for NOTHING!!! Out of some reason, this is seen as "unsafe" by rustc.
317	try!(rdr.read_exact(&mut vendor_buf));
318	let vendor = try!(String::from_utf8(vendor_buf));
319
320	// Now read the comments
321	let comment_count = try!(rdr.read_u32::<LittleEndian>()) as usize;
322	let mut comment_list = Vec::with_capacity(comment_count);
323	for _ in 0 .. comment_count {
324		let comment_length = try!(rdr.read_u32::<LittleEndian>()) as usize;
325		let mut comment_buf = vec![0; comment_length]; // TODO fix this, we initialize memory for NOTHING!!! Out of some reason, this is seen as "unsafe" by rustc.
326		try!(rdr.read_exact(&mut comment_buf));
327		let comment = match String::from_utf8(comment_buf) {
328			Ok(comment) => comment,
329			// Uncomment for closer compliance with the spec.
330			// The spec explicitly states that the comment entries
331			// should be UTF-8 formatted, however it seems that other
332			// decoder libraries tolerate non-UTF-8 formatted strings
333			// in comments. This has led to some files circulating
334			// with such errors inside. If we deny to decode such files,
335			// lewton would be the odd one out. Thus we just
336			// gracefully ignore them.
337			Err(_) => continue,
338		};
339		let eq_idx = match comment.find("=") {
340			Some(k) => k,
341			// Uncomment for closer compliance with the spec.
342			// It appears that some ogg files have fields without a = sign in the comments.
343			// Well there is not much we can do but gracefully ignore their stuff.
344			None => continue // try!(Err(HeaderReadError::HeaderBadFormat))
345		};
346		let (key_eq, val) = comment.split_at(eq_idx + 1);
347		let (key, _) = key_eq.split_at(eq_idx);
348		comment_list.push((String::from(key), String::from(val)));
349	}
350	let framing = try!(rdr.read_u8());
351	if framing != 1 {
352		try!(Err(HeaderReadError::HeaderBadFormat));
353	}
354	let hdr :CommentHeader = CommentHeader {
355		vendor,
356		comment_list,
357	};
358	return Ok(hdr);
359}
360
361pub(crate) struct Codebook {
362	pub codebook_dimensions :u16,
363	pub codebook_entries :u32,
364
365	// None if codebook_lookup_type == 0
366	pub codebook_vq_lookup_vec :Option<Vec<f32>>,
367
368	pub codebook_huffman_tree :VorbisHuffmanTree,
369}
370
371pub(crate) struct Residue {
372	pub residue_type :u8,
373	pub residue_begin :u32,
374	pub residue_end :u32,
375	pub residue_partition_size :u32,
376	pub residue_classifications :u8,
377	pub residue_classbook :u8,
378	pub residue_books :Vec<ResidueBook>,
379}
380
381pub(crate) struct Mapping {
382	pub mapping_submaps :u8,
383	pub mapping_magnitudes :Vec<u8>,
384	pub mapping_angles :Vec<u8>,
385	pub mapping_mux :Vec<u8>,
386	pub mapping_submap_floors :Vec<u8>,
387	pub mapping_submap_residues :Vec<u8>,
388}
389
390pub(crate) struct ModeInfo {
391	pub mode_blockflag :bool,
392	pub mode_mapping :u8,
393}
394
395pub(crate) enum Floor {
396	TypeZero(FloorTypeZero),
397	TypeOne(FloorTypeOne),
398}
399
400pub(crate) struct FloorTypeZero {
401	pub floor0_order :u8,
402	pub floor0_rate :u16,
403	pub floor0_bark_map_size :u16,
404	pub floor0_amplitude_bits :u8,
405	pub floor0_amplitude_offset :u8,
406	pub floor0_number_of_books :u8,
407	pub floor0_book_list :Vec<u8>,
408	pub cached_bark_cos_omega :[Vec<f32>; 2],
409}
410
411pub(crate) struct FloorTypeOne {
412	pub floor1_multiplier :u8,
413	pub floor1_partition_class :Vec<u8>,
414	pub floor1_class_dimensions :Vec<u8>,
415	pub floor1_class_subclasses :Vec<u8>,
416	pub floor1_subclass_books :Vec<Vec<i16>>,
417	pub floor1_class_masterbooks :Vec<u8>,
418	pub floor1_x_list :Vec<u32>,
419	pub floor1_x_list_sorted :Vec<(usize, u32)>,
420}
421
422pub(crate) struct ResidueBook {
423	vals_used :u8,
424	val_i :[u8; 8],
425}
426
427impl ResidueBook {
428	pub fn get_val(&self, i :u8) -> Option<u8> {
429		if i >= 8 {
430			// This is a precondition...
431			panic!("Tried to get ResidueBook value out of bounds (index = {})",
432				i);
433		}
434		return if self.vals_used & (1 << i) > 0 {
435			Some(self.val_i[i as usize])
436		} else {
437			None
438		};
439	}
440	/// Reads the `ResidueBook` from a `BitpackCursor`.
441	fn read_book(rdr :&mut BitpackCursor,
442			vals_used :u8, codebooks :&[Codebook])
443			-> Result<Self, HeaderReadError> {
444		let mut val_i :[u8; 8] = [0; 8];
445		for i in 0 .. 7 {
446			if vals_used & (1 << i) == 0 {
447				continue;
448			}
449			let val_entry = try!(rdr.read_u8());
450			if match codebooks.get(val_entry as usize) {
451				Some(v) => v.codebook_vq_lookup_vec.is_none(),
452				None => true,
453			} {
454				// Both of the cases are forbidden by spec
455				// (the codebook being out of bounds, or
456				// not having a value mapping)
457				try!(Err(HeaderReadError::HeaderBadFormat))
458			}
459			val_i[i] = val_entry;
460		}
461		return Ok(ResidueBook { vals_used, val_i });
462	}
463}
464
465pub struct SetupHeader {
466	pub(crate) codebooks :Vec<Codebook>,
467	pub(crate) floors :Vec<Floor>,
468	pub(crate) residues :Vec<Residue>,
469	pub(crate) mappings :Vec<Mapping>,
470	pub(crate) modes :Vec<ModeInfo>,
471}
472
473struct CodebookVqLookup {
474	codebook_lookup_type :u8,
475	codebook_minimum_value :f32,
476	codebook_delta_value :f32,
477	codebook_sequence_p :bool,
478	codebook_multiplicands :Vec<u32>,
479}
480
481/// Vector value decode for lookup
482///
483/// Prepares the VQ context vectors for later lookup
484/// by the codebook abstraction layer.
485///
486/// Returns `codebook_entries` many vectors,
487/// each being `codebook_dimensions` scalars wide),
488/// all stored in one Vec.
489fn lookup_vec_val_decode(lup :&CodebookVqLookup, codebook_entries :u32, codebook_dimensions :u16) -> Vec<f32> {
490	let mut value_vectors = Vec::with_capacity(
491		codebook_entries as usize * codebook_dimensions as usize);
492	if lup.codebook_lookup_type == 1 {
493		let codebook_lookup_values = lup.codebook_multiplicands.len();
494		for lookup_offset in 0 .. codebook_entries {
495			let mut last = 0.;
496			let mut index_divisor = 1;
497			for _ in 0 .. codebook_dimensions {
498				let multiplicand_offset = (lookup_offset / index_divisor as u32) as usize %
499					codebook_lookup_values;
500				let vec_elem = lup.codebook_multiplicands[multiplicand_offset] as f32 *
501					lup.codebook_delta_value + lup.codebook_minimum_value + last;
502				if lup.codebook_sequence_p {
503					last = vec_elem;
504				}
505				value_vectors.push(vec_elem);
506				index_divisor *= codebook_lookup_values;
507			}
508		}
509	} else {
510		for lookup_offset in 0 .. codebook_entries {
511			let mut last = 0.;
512			let mut multiplicand_offset :usize = lookup_offset as usize * codebook_dimensions as usize;
513			for _ in 0 .. codebook_dimensions {
514				let vec_elem = lup.codebook_multiplicands[multiplicand_offset] as f32 *
515					lup.codebook_delta_value + lup.codebook_minimum_value + last;
516				if lup.codebook_sequence_p {
517					last = vec_elem;
518				}
519				value_vectors.push(vec_elem);
520				multiplicand_offset += 1;
521			}
522		}
523	}
524	return value_vectors;
525}
526
527
528/// Small Error type for `BitpackCursor::read_huffman_vq`.
529///
530/// This is in order to enable calling code to distinguish
531/// between the two cases of the enum. Esp. in some cases
532/// the decoder might have to reject packages with the
533/// NoVqLookupForCodebook variant, but have to treat EndOfPacket
534/// as normal occurence.
535pub(crate) enum HuffmanVqReadErr {
536	EndOfPacket,
537	NoVqLookupForCodebook,
538}
539
540impl <'a> BitpackCursor <'a> {
541	/// Reads a huffman word using the codebook abstraction via a VQ context
542	pub(crate) fn read_huffman_vq<'b>(&mut self, b :&'b Codebook) -> Result<&'b[f32], HuffmanVqReadErr> {
543
544		let idx = match self.read_huffman(&b.codebook_huffman_tree) {
545			Ok(v) => v as usize,
546			Err(_) => return Err(HuffmanVqReadErr::EndOfPacket),
547		};
548		let codebook_vq_lookup_vec :&[f32] = match b.codebook_vq_lookup_vec.as_ref() {
549			Some(ref v) => v,
550			None => return Err(HuffmanVqReadErr::NoVqLookupForCodebook),
551		};
552		let dim = b.codebook_dimensions as usize;
553		return Ok(&codebook_vq_lookup_vec[idx * dim .. (idx + 1) * dim]);
554	}
555}
556
557static MAX_BASES_WITHOUT_OVERFLOW : &[u32] = &[
558	0xffffffff, 0xffffffff, 0x0000ffff, 0x00000659,
559	0x000000ff, 0x00000054, 0x00000028, 0x00000017,
560	0x0000000f, 0x0000000b, 0x00000009, 0x00000007,
561	0x00000006, 0x00000005, 0x00000004, 0x00000004,
562	0x00000003, 0x00000003, 0x00000003, 0x00000003,
563	0x00000003, 0x00000002, 0x00000002, 0x00000002,
564	0x00000002, 0x00000002, 0x00000002, 0x00000002,
565	0x00000002, 0x00000002, 0x00000002, 0x00000002];
566
567static MAX_BASE_MAX_BITS_WITHOUT_OVERFLOW : &[u8] = &[
568	0x1f, 0x1f, 0x0f, 0x0a,
569	0x07, 0x06, 0x05, 0x04,
570	0x03, 0x03, 0x03, 0x02,
571	0x02, 0x02, 0x02, 0x02,
572	0x01, 0x01, 0x01, 0x01,
573	0x01, 0x01, 0x01, 0x01,
574	0x01, 0x01, 0x01, 0x01,
575	0x01, 0x01, 0x01, 0x01];
576
577// For this little function I won't include the num crate.
578// precondition: base ^ exponent must not overflow.
579fn exp_fast(base :u32, exponent: u8) -> u32 {
580	let mut res :u32 = 1;
581	let mut selfmul = base;
582	for i in 0 .. 8 {
583		if (1 << i) & exponent > 0 {
584			res *= selfmul;
585		}
586		if let Some(newselfmul) = u32::checked_mul(selfmul, selfmul) {
587			selfmul = newselfmul;
588		} else {
589			// Okay, now we have to find out
590			// whether this matters or not.
591			// Check whether selfmul would have been needed.
592			if i < 7 && (exponent >> (i + 1)) > 0 {
593				panic!("Overflow when squaring for exp_fast, \
594					precondition violated!");
595			}
596			return res;
597		}
598	}
599	return res;
600}
601
602/// Returns, as defined in the vorbis spec:
603/// "the greatest integer for which to `[return_value]` the power of `[codebook_dimensions]` is less than or equal to `[codebook_entries]`"
604/// Essentially an "nth-root" algorithm.
605/// About the speed:
606/// Probably its super-optimized as it uses no floats,
607/// probably smarter algorithms using floats would be faster here. No idea.
608/// Either way, stackoverflow gave the (great) motivation for the algorithm:
609/// http://stackoverflow.com/questions/7407752
610fn lookup1_values(codebook_entries :u32, codebook_dimensions :u16) -> u32 {
611	if codebook_dimensions >= 32 {
612		// For codebook_dimensions >= 32 we'd already overflow the u32 range if
613		// we computed 2 ^ codebook_dimensions.
614		// Therefore, the result must be less than 2.
615		return if codebook_entries == 0 { 0 } else { 1 };
616	}
617	// Now do a binary search.
618	// We use two static helper arrays here. Both take the
619	// exponent (codebook_dimensions here) as index.
620	// The first array, MAX_BASES_WITHOUT_OVERFLOW contains
621	// the base that doesn't generate an overflow for the
622	// given exponent.
623	// The second array MAX_BASE_MAX_BITS_WITHOUT_OVERFLOW
624	// contains the number of the highest set bit in
625	// the corresponding entry in MAX_BASES_WITHOUT_OVERFLOW.
626	// This is the first bit that is "disputed" in the binary
627	// search to follow: we check the bases to support the
628	// claim by manual exponentiation.
629	let max_base_bits = MAX_BASE_MAX_BITS_WITHOUT_OVERFLOW[
630		codebook_dimensions as usize];
631	let max_base = MAX_BASES_WITHOUT_OVERFLOW[codebook_dimensions as usize];
632	let mut base_bits :u32 = 0;
633	for i in 0 .. max_base_bits + 1 {
634		let cur_disputed_bit :u32 = 1 << (max_base_bits - i);
635		base_bits |= cur_disputed_bit;
636		if max_base < base_bits ||
637				exp_fast(base_bits, codebook_dimensions as u8) > codebook_entries {
638			base_bits &= !cur_disputed_bit;
639		}
640	}
641	return base_bits;
642}
643
644#[test]
645fn test_lookup1_values() {
646	// First, with base two:
647	// 2 ^ 10 = 1024
648	assert_eq!(lookup1_values(1025, 10), 2);
649	assert_eq!(lookup1_values(1024, 10), 2);
650	assert_eq!(lookup1_values(1023, 10), 1);
651
652	// Now, the searched base is five:
653	// 5 ^ 5 = 3125
654	assert_eq!(lookup1_values(3126, 5), 5);
655	assert_eq!(lookup1_values(3125, 5), 5);
656	assert_eq!(lookup1_values(3124, 5), 4);
657
658	// Now some exotic tests (edge cases :p):
659	assert_eq!(lookup1_values(1, 1), 1);
660	assert_eq!(lookup1_values(0, 15), 0);
661	assert_eq!(lookup1_values(0, 0), 0);
662	assert_eq!(lookup1_values(1, 0), std::u32::MAX);
663	assert_eq!(lookup1_values(400, 0), std::u32::MAX);
664}
665
666/// Reads a codebook which is part of the setup header packet.
667fn read_codebook(rdr :&mut BitpackCursor) -> Result<Codebook, HeaderReadError> {
668
669	// 1. Read the sync pattern
670	let sync_pattern = try!(rdr.read_u24());
671	if sync_pattern != 0x564342 {
672		try!(Err(HeaderReadError::HeaderBadFormat));
673	}
674
675	// 2. Read the _dimension, _entries fields and the ordered bitflag
676	let codebook_dimensions = try!(rdr.read_u16());
677	let codebook_entries = try!(rdr.read_u24());
678	let ordered = try!(rdr.read_bit_flag());
679
680	// 3. Read the codeword lengths
681	let mut codebook_codeword_lengths = Vec::with_capacity(
682		convert_to_usize!(codebook_entries, u32));
683	if !ordered {
684		let sparse = try!(rdr.read_bit_flag());
685		for _ in 0 .. codebook_entries {
686			let length = if sparse {
687				let flag = try!(rdr.read_bit_flag());
688				if flag {
689					try!(rdr.read_u5()) + 1
690				} else {
691					/* The spec here asks that we should mark that the
692					entry is unused. But 0 already fulfills this purpose,
693					as everywhere else its guaranteed that the length is > 0.
694					No messing with Option<T> needed here :) */
695					0
696				}
697			} else {
698				try!(rdr.read_u5()) + 1
699			};
700			codebook_codeword_lengths.push(length);
701		}
702	} else {
703		let mut current_entry :u32 = 0;
704		let mut current_length = try!(rdr.read_u5()) + 1;
705		while current_entry < codebook_entries {
706			let number = try!(rdr.read_dyn_u32(
707				::ilog((codebook_entries - current_entry) as u64)));
708			for _ in current_entry .. current_entry + number {
709				codebook_codeword_lengths.push(current_length);
710			}
711			current_entry += number;
712			current_length += 1;
713			if current_entry as u32 > codebook_entries {
714				try!(Err(HeaderReadError::HeaderBadFormat));
715			}
716		}
717	}
718
719	// 4. Read the vector lookup table
720	let codebook_lookup_type = try!(rdr.read_u4());
721	if codebook_lookup_type > 2 {
722		// Not decodable per vorbis spec
723		try!(Err(HeaderReadError::HeaderBadFormat));
724	}
725	let codebook_lookup :Option<CodebookVqLookup> =
726	if codebook_lookup_type == 0 {
727		None
728	} else {
729		let codebook_minimum_value = try!(rdr.read_f32());
730		let codebook_delta_value = try!(rdr.read_f32());
731		let codebook_value_bits = try!(rdr.read_u4()) + 1;
732		let codebook_sequence_p = try!(rdr.read_bit_flag());
733		let codebook_lookup_values :u64 = if codebook_lookup_type == 1 {
734			 lookup1_values(codebook_entries, codebook_dimensions) as u64
735		} else {
736			codebook_entries as u64 * codebook_dimensions as u64
737		};
738		let mut codebook_multiplicands = Vec::with_capacity(
739			convert_to_usize!(codebook_lookup_values, u64));
740		for _ in 0 .. codebook_lookup_values {
741			codebook_multiplicands.push(try!(rdr.read_dyn_u32(codebook_value_bits)));
742		}
743		Some(CodebookVqLookup {
744			codebook_lookup_type,
745			codebook_minimum_value,
746			codebook_delta_value,
747			codebook_sequence_p,
748			codebook_multiplicands,
749		})
750	};
751	let codebook_vq_lookup_vec = codebook_lookup.as_ref().map(|lup| {
752		lookup_vec_val_decode(lup,
753			codebook_entries, codebook_dimensions)
754	});
755
756	return Ok(Codebook {
757		codebook_dimensions,
758		codebook_entries,
759		codebook_vq_lookup_vec,
760		codebook_huffman_tree : try!(VorbisHuffmanTree::load_from_array(&codebook_codeword_lengths)),
761	});
762}
763
764/// Reads a Floor which is part of the setup header packet.
765/// The `codebook_cnt` param is required to check for compliant streams
766fn read_floor(rdr :&mut BitpackCursor, codebook_cnt :u16, blocksizes :(u8, u8)) ->
767		Result<Floor, HeaderReadError> {
768	let floor_type = try!(rdr.read_u16());
769	match floor_type {
770		0 => {
771			let floor0_order = try!(rdr.read_u8());
772			let floor0_rate = try!(rdr.read_u16());
773			let floor0_bark_map_size = try!(rdr.read_u16());
774			let floor0_amplitude_bits = try!(rdr.read_u6());
775			if floor0_amplitude_bits > 64 {
776				// Unfortunately the audio decoder part
777				// doesn't support values > 64 because rust has no
778				// 128 bit integers yet.
779				// TODO when support is added, remove this
780				// check.
781				try!(Err(HeaderReadError::HeaderBadFormat));
782			}
783			let floor0_amplitude_offset = try!(rdr.read_u8());
784			let floor0_number_of_books = try!(rdr.read_u4()) + 1;
785			let mut floor0_book_list = Vec::with_capacity(
786				convert_to_usize!(floor0_number_of_books, u8));
787			for _ in 0 .. floor0_number_of_books {
788				let value = try!(rdr.read_u8());
789				if value as u16 > codebook_cnt {
790					try!(Err(HeaderReadError::HeaderBadFormat));
791				}
792				floor0_book_list.push(value);
793			}
794			Ok(Floor::TypeZero(FloorTypeZero {
795				floor0_order,
796				floor0_rate,
797				floor0_bark_map_size,
798				floor0_amplitude_bits,
799				floor0_amplitude_offset,
800				floor0_number_of_books,
801				floor0_book_list,
802				cached_bark_cos_omega : [
803					compute_bark_map_cos_omega(1 << (blocksizes.0 - 1),
804						floor0_rate, floor0_bark_map_size),
805					compute_bark_map_cos_omega(1 << (blocksizes.1 - 1),
806						floor0_rate, floor0_bark_map_size),
807				]
808			}))
809		},
810		1 => {
811			let floor1_partitions = try!(rdr.read_u5());
812			let mut maximum_class :i8 = -1;
813			let mut floor1_partition_class_list = Vec::with_capacity(
814				floor1_partitions as usize);
815			for _ in 0 .. floor1_partitions {
816				let cur_class = try!(rdr.read_u4());
817				maximum_class = if cur_class as i8 > maximum_class
818					{ cur_class as i8 } else { maximum_class };
819				floor1_partition_class_list.push(cur_class);
820			}
821
822			// TODO one day try out whether its more performant
823			// to have these two arrays in one, its wasteful to allocate
824			// 16 bit so that one can store 5 bits.
825			let mut floor1_class_dimensions = Vec::with_capacity((maximum_class + 1) as usize);
826			let mut floor1_class_subclasses = Vec::with_capacity((maximum_class + 1) as usize);
827
828			let mut floor1_subclass_books = Vec::with_capacity((maximum_class + 1) as usize);
829
830			let mut floor1_class_masterbooks = Vec::with_capacity((maximum_class + 1) as usize);
831			for _ in 0 .. maximum_class + 1 {
832				floor1_class_dimensions.push(try!(rdr.read_u3()) + 1);
833				let cur_subclass = try!(rdr.read_u2());
834				floor1_class_subclasses.push(cur_subclass);
835				if cur_subclass != 0 {
836					let cur_masterbook = try!(rdr.read_u8());
837					if cur_masterbook as u16 >= codebook_cnt {
838						// undecodable as per spec
839						try!(Err(HeaderReadError::HeaderBadFormat));
840					}
841					floor1_class_masterbooks.push(cur_masterbook);
842				} else {
843					// Some value... This never gets read,
844					// but Rust requires everything to be initialized,
845					// we can't increase the counter without initialisation.
846					floor1_class_masterbooks.push(0);
847				}
848				let cur_books_cnt :u8 = 1 << cur_subclass;
849				let mut cur_books = Vec::with_capacity(cur_books_cnt as usize);
850				for _ in 0 .. cur_books_cnt {
851					// The fact that we need i16 here (and shouldn't do
852					// wrapping sub) is only revealed if you read the
853					// "packet decode" part of the floor 1 spec...
854					let cur_book = (try!(rdr.read_u8()) as i16) - 1;
855					if cur_book >= codebook_cnt as i16 {
856						// undecodable as per spec
857						try!(Err(HeaderReadError::HeaderBadFormat));
858					}
859					cur_books.push(cur_book);
860				}
861				floor1_subclass_books.push(cur_books);
862			}
863			let floor1_multiplier = try!(rdr.read_u2()) + 1;
864			let rangebits = try!(rdr.read_u4());
865			let mut floor1_values :u16 = 2;
866			// Calculate the count before doing anything else
867			for cur_class_num in &floor1_partition_class_list {
868				floor1_values += floor1_class_dimensions[*cur_class_num as usize] as u16;
869			}
870			if floor1_values > 65 {
871				// undecodable as per spec
872				try!(Err(HeaderReadError::HeaderBadFormat));
873			}
874			let mut floor1_x_list = Vec::with_capacity(floor1_values as usize);
875			floor1_x_list.push(0);
876			floor1_x_list.push(1u32 << rangebits);
877			for cur_class_num in &floor1_partition_class_list {
878				for _ in 0 .. floor1_class_dimensions[*cur_class_num as usize] {
879					floor1_x_list.push(try!(rdr.read_dyn_u32(rangebits)));
880				}
881			}
882			// Now do an uniqueness check on floor1_x_list
883			// to check decodability.
884			let mut floor1_x_list_sorted = floor1_x_list.iter().cloned()
885				.enumerate().collect::<Vec<_>>();
886			floor1_x_list_sorted.sort_by(|a, b| a.1.cmp(&b.1));
887			// 0 is guaranteed to be in the list,
888			// and due to sorting it will be first.
889			let mut last = 1;
890			for el in &floor1_x_list_sorted {
891				if el.1 == last {
892					// duplicate entry found
893					// undecodable as per spec
894					try!(Err(HeaderReadError::HeaderBadFormat));
895				}
896				last = el.1;
897			}
898
899			// Only now return the result
900			Ok(Floor::TypeOne(FloorTypeOne {
901				floor1_multiplier,
902				floor1_partition_class : floor1_partition_class_list,
903				floor1_class_dimensions,
904				floor1_class_subclasses,
905				floor1_subclass_books,
906				floor1_class_masterbooks,
907				floor1_x_list,
908				floor1_x_list_sorted,
909
910			}))
911		},
912		// Type greater than 1 is error condition per spec
913		_ => Err(HeaderReadError::HeaderBadFormat),
914	}
915}
916
917/// Reads a Residue which is part of the setup header packet.
918/// The `codebook_cnt` param is required to check for compliant streams
919fn read_residue(rdr :&mut BitpackCursor, codebooks :&[Codebook])
920		-> Result<Residue, HeaderReadError> {
921	let residue_type = try!(rdr.read_u16());
922	if residue_type > 2 {
923		// Undecodable by spec
924		try!(Err(HeaderReadError::HeaderBadFormat));
925	}
926	let residue_begin = try!(rdr.read_u24());
927	let residue_end = try!(rdr.read_u24());
928	if residue_begin > residue_end {
929		// If residue_begin < residue_end, we'll get
930		// errors in audio parsing code.
931		// As the idea of residue end being before begin
932		// sounds quite wrong anyway, we already error
933		// earlier, in header parsing code.
934		try!(Err(HeaderReadError::HeaderBadFormat));
935	}
936	let residue_partition_size = try!(rdr.read_u24()) + 1;
937	let residue_classifications = try!(rdr.read_u6()) + 1;
938	let residue_classbook = try!(rdr.read_u8());
939	// Read the bitmap pattern:
940	let mut residue_cascade = Vec::with_capacity(residue_classifications as usize);
941	for _ in 0 .. residue_classifications {
942		let mut high_bits = 0;
943		let low_bits = try!(rdr.read_u3());
944		let bitflag = try!(rdr.read_bit_flag());
945		if bitflag {
946			high_bits = try!(rdr.read_u5());
947		}
948		residue_cascade.push((high_bits << 3) | low_bits);
949	}
950
951	let mut residue_books = Vec::with_capacity(residue_classifications as usize);
952	// Read the list of book numbers:
953	for cascade_entry in &residue_cascade {
954		residue_books.push(try!(
955			ResidueBook::read_book(rdr, *cascade_entry, codebooks)));
956	}
957	if residue_classbook as usize >= codebooks.len() {
958		// Undecodable because residue_classbook must be valid index
959		try!(Err(HeaderReadError::HeaderBadFormat));
960	}
961	/*
962	// Currently we check below condition in audio decode, following the spec,
963	// section 3.3., saying that it only renders the packet that wants to use the
964	// invalid codebook invalid, but not the whole stream only because there is a
965	// residue in the header (which may never be used).
966	if codebooks[residue_classbook as usize].codebook_vq_lookup_vec.is_none() {
967		// Undecodable because residue_classbook must be valid index
968		try!(Err(HeaderReadError::HeaderBadFormat));
969	}*/
970	return Ok(Residue {
971		residue_type : residue_type as u8,
972		residue_begin,
973		residue_end,
974		residue_partition_size,
975		residue_classifications,
976		residue_classbook,
977		residue_books,
978	});
979}
980
981/// Reads a "Mapping" which is part of the setup header packet.
982fn read_mapping(rdr :&mut BitpackCursor,
983		audio_chan_ilog :u8, audio_channels :u8,
984		floor_count :u8, residue_count :u8)
985		-> Result<Mapping, HeaderReadError> {
986	let mapping_type = try!(rdr.read_u16());
987	if mapping_type > 0 {
988		// Undecodable per spec
989		try!(Err(HeaderReadError::HeaderBadFormat));
990	}
991	let mapping_submaps = match try!(rdr.read_bit_flag()) {
992		true => try!(rdr.read_u4()) + 1,
993		false => 1,
994	};
995	let mapping_coupling_steps = match try!(rdr.read_bit_flag()) {
996		true => try!(rdr.read_u8()) as u16 + 1,
997		false => 0,
998	};
999	let mut mapping_magnitudes = Vec::with_capacity(mapping_coupling_steps as usize);
1000	let mut mapping_angles = Vec::with_capacity(mapping_coupling_steps as usize);
1001	for _ in 0 .. mapping_coupling_steps {
1002		let cur_mag = try!(rdr.read_dyn_u8(audio_chan_ilog));
1003		let cur_angle = try!(rdr.read_dyn_u8(audio_chan_ilog));
1004		if (cur_angle == cur_mag) || (cur_mag >= audio_channels)
1005				|| (cur_angle >= audio_channels) {
1006			// Undecodable per spec
1007			try!(Err(HeaderReadError::HeaderBadFormat));
1008		}
1009		mapping_magnitudes.push(cur_mag);
1010		mapping_angles.push(cur_angle);
1011	}
1012	let reserved = try!(rdr.read_u2());
1013	if reserved != 0 {
1014		// Undecodable per spec
1015		try!(Err(HeaderReadError::HeaderBadFormat));
1016	}
1017	let mapping_mux = if mapping_submaps > 1 {
1018		let mut m = Vec::with_capacity(audio_channels as usize);
1019		for _ in 0 .. audio_channels {
1020			let val = try!(rdr.read_u4());
1021			if val >= mapping_submaps {
1022				// Undecodable per spec
1023				try!(Err(HeaderReadError::HeaderBadFormat));
1024			}
1025			m.push(val);
1026		};
1027		m
1028	} else {
1029		vec![0; audio_channels as usize]
1030	};
1031	let mut mapping_submap_floors = Vec::with_capacity(mapping_submaps as usize);
1032	let mut mapping_submap_residues = Vec::with_capacity(mapping_submaps as usize);
1033	for _ in 0 .. mapping_submaps {
1034		// To whom those reserved bits may concern.
1035		// I have discarded them!
1036		try!(rdr.read_u8());
1037		let cur_floor = try!(rdr.read_u8());
1038		let cur_residue = try!(rdr.read_u8());
1039		if cur_floor >= floor_count ||
1040				cur_residue >= residue_count {
1041			// Undecodable per spec
1042			try!(Err(HeaderReadError::HeaderBadFormat));
1043		}
1044		mapping_submap_floors.push(cur_floor);
1045		mapping_submap_residues.push(cur_residue);
1046	}
1047	return Ok(Mapping {
1048		mapping_submaps,
1049		mapping_magnitudes,
1050		mapping_angles,
1051		mapping_mux,
1052		mapping_submap_floors,
1053		mapping_submap_residues,
1054	});
1055}
1056
1057/// Reads a ModeInfo which is part of the setup header packet.
1058fn read_mode_info(rdr :&mut BitpackCursor, mapping_count :u8) -> Result<ModeInfo, HeaderReadError> {
1059	let mode_blockflag = try!(rdr.read_bit_flag());
1060	let mode_windowtype = try!(rdr.read_u16());
1061	let mode_transformtype = try!(rdr.read_u16());
1062	let mode_mapping = try!(rdr.read_u8());
1063	// Verifying ranges
1064	if mode_windowtype != 0 ||
1065			mode_transformtype != 0 ||
1066			mode_mapping >= mapping_count {
1067		// Undecodable per spec
1068		try!(Err(HeaderReadError::HeaderBadFormat));
1069	}
1070	return Ok(ModeInfo {
1071		mode_blockflag,
1072		mode_mapping,
1073	});
1074}
1075
1076/// Reading the setup header.
1077///
1078/// The audio channel and blocksize info needed by the function
1079/// can be obtained from the ident header.
1080pub fn read_header_setup(packet :&[u8], audio_channels :u8, blocksizes :(u8, u8)) ->
1081		Result<SetupHeader, HeaderReadError> {
1082	let mut rdr = BitpackCursor::new(packet);
1083	let hd_id = try!(read_header_begin(&mut rdr));
1084	if hd_id != 5 {
1085		try!(Err(HeaderReadError::HeaderBadType(hd_id)));
1086	}
1087
1088	// Little preparation -- needed later
1089	let audio_chan_ilog = ::ilog((audio_channels - 1) as u64);
1090
1091	//::print_u8_slice(packet);
1092
1093	// 1. Read the codebooks
1094	let vorbis_codebook_count :u16 = try!(rdr.read_u8()) as u16 + 1;
1095	let mut codebooks = Vec::with_capacity(vorbis_codebook_count as usize);
1096	for _ in 0 .. vorbis_codebook_count {
1097		codebooks.push(try!(read_codebook(&mut rdr)));
1098	}
1099
1100	// 2. Read the time domain transforms
1101	let vorbis_time_count :u8 = try!(rdr.read_u6()) + 1;
1102	for _ in 0 .. vorbis_time_count {
1103		if try!(rdr.read_u16()) != 0 {
1104			try!(Err(HeaderReadError::HeaderBadFormat));
1105		}
1106	}
1107
1108	// 3. Read the floor values
1109	let vorbis_floor_count :u8 = try!(rdr.read_u6()) + 1;
1110	let mut floors = Vec::with_capacity(vorbis_floor_count as usize);
1111	for _ in 0 .. vorbis_floor_count {
1112		floors.push(try!(read_floor(&mut rdr, vorbis_codebook_count, blocksizes)));
1113	}
1114
1115	// 4. Read the residue values
1116	let vorbis_residue_count :u8 = try!(rdr.read_u6()) + 1;
1117	let mut residues = Vec::with_capacity(vorbis_residue_count as usize);
1118	for _ in 0 .. vorbis_residue_count {
1119		residues.push(try!(read_residue(&mut rdr, &codebooks)));
1120	}
1121
1122	// 5. Read the mappings
1123	let vorbis_mapping_count :u8 = try!(rdr.read_u6()) + 1;
1124	let mut mappings = Vec::with_capacity(vorbis_mapping_count as usize);
1125	for _ in 0 .. vorbis_mapping_count {
1126		mappings.push(try!(read_mapping(& mut rdr,
1127			audio_chan_ilog, audio_channels,
1128			vorbis_floor_count, vorbis_residue_count)));
1129	}
1130
1131	// 6. Read the modes
1132	let vorbis_mode_count :u8 = try!(rdr.read_u6()) + 1;
1133	let mut modes = Vec::with_capacity(vorbis_mode_count as usize);
1134	for _ in 0 .. vorbis_mode_count {
1135		modes.push(try!(read_mode_info(& mut rdr, vorbis_mapping_count)));
1136	}
1137
1138	// Now we only have to make sure the framing bit is set,
1139	// and we can successfully return the setup header!
1140	let framing :bool = try!(rdr.read_bit_flag());
1141	if !framing {
1142		try!(Err(HeaderReadError::HeaderBadFormat));
1143	}
1144
1145	return Ok(SetupHeader {
1146		codebooks,
1147		floors,
1148		residues,
1149		mappings,
1150		modes,
1151	});
1152}