1use 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#[derive(Debug)]
34#[derive(PartialEq)]
35pub enum HeaderReadError {
36 EndOfPacket,
37 NotVorbisHeader,
40 UnsupportedVorbisVersion,
41 HeaderBadFormat,
43 HeaderBadType(u8),
49 HeaderIsAudio,
52 Utf8DecodeError,
53 BufferNotAddressable,
63}
64
65impl 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
113macro_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
127macro_rules! read_header_begin_body {
132( $rdr:expr ) => { {
133 let res = try!($rdr.read_u8());
134 if res & 1 == 0 {
135 try!(Err(HeaderReadError::HeaderIsAudio));
139 }
140 let is_vorbis =
141 try!($rdr.read_u8()) == 0x76 && try!($rdr.read_u8()) == 0x6f && try!($rdr.read_u8()) == 0x72 && try!($rdr.read_u8()) == 0x62 && try!($rdr.read_u8()) == 0x69 && try!($rdr.read_u8()) == 0x73; 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 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
176pub type HeaderSet = (IdentHeader, CommentHeader, SetupHeader);
178
179pub struct IdentHeader {
188 pub audio_channels :u8,
190 pub audio_sample_rate :u32,
192 pub bitrate_maximum :i32,
197 pub bitrate_nominal :i32,
202 pub bitrate_minimum :i32,
207 pub blocksize_0 :u8,
208 pub blocksize_1 :u8,
209 pub(crate) cached_bs_derived :[CachedBlocksizeDerived; 2],
210}
211
212pub 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 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#[derive(Clone, PartialEq, Eq, Hash, Debug)]
289pub struct CommentHeader {
290 pub vendor :String,
294 pub comment_list :Vec<(String, String)>,
297}
298
299pub 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 let vendor_length = try!(rdr.read_u32::<LittleEndian>()) as usize;
316 let mut vendor_buf = vec![0; vendor_length]; try!(rdr.read_exact(&mut vendor_buf));
318 let vendor = try!(String::from_utf8(vendor_buf));
319
320 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]; try!(rdr.read_exact(&mut comment_buf));
327 let comment = match String::from_utf8(comment_buf) {
328 Ok(comment) => comment,
329 Err(_) => continue,
338 };
339 let eq_idx = match comment.find("=") {
340 Some(k) => k,
341 None => continue };
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 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 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 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 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
481fn 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
528pub(crate) enum HuffmanVqReadErr {
536 EndOfPacket,
537 NoVqLookupForCodebook,
538}
539
540impl <'a> BitpackCursor <'a> {
541 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
577fn 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 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
602fn lookup1_values(codebook_entries :u32, codebook_dimensions :u16) -> u32 {
611 if codebook_dimensions >= 32 {
612 return if codebook_entries == 0 { 0 } else { 1 };
616 }
617 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 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 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 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
666fn read_codebook(rdr :&mut BitpackCursor) -> Result<Codebook, HeaderReadError> {
668
669 let sync_pattern = try!(rdr.read_u24());
671 if sync_pattern != 0x564342 {
672 try!(Err(HeaderReadError::HeaderBadFormat));
673 }
674
675 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 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 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 let codebook_lookup_type = try!(rdr.read_u4());
721 if codebook_lookup_type > 2 {
722 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
764fn 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 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 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 try!(Err(HeaderReadError::HeaderBadFormat));
840 }
841 floor1_class_masterbooks.push(cur_masterbook);
842 } else {
843 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 let cur_book = (try!(rdr.read_u8()) as i16) - 1;
855 if cur_book >= codebook_cnt as i16 {
856 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 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 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 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 let mut last = 1;
890 for el in &floor1_x_list_sorted {
891 if el.1 == last {
892 try!(Err(HeaderReadError::HeaderBadFormat));
895 }
896 last = el.1;
897 }
898
899 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 _ => Err(HeaderReadError::HeaderBadFormat),
914 }
915}
916
917fn 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 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 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 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 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 try!(Err(HeaderReadError::HeaderBadFormat));
960 }
961 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
981fn 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 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 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 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 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 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 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
1057fn 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 if mode_windowtype != 0 ||
1065 mode_transformtype != 0 ||
1066 mode_mapping >= mapping_count {
1067 try!(Err(HeaderReadError::HeaderBadFormat));
1069 }
1070 return Ok(ModeInfo {
1071 mode_blockflag,
1072 mode_mapping,
1073 });
1074}
1075
1076pub 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 let audio_chan_ilog = ::ilog((audio_channels - 1) as u64);
1090
1091 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 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 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 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 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 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 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}