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