pub fn load_from_array(codebook_codeword_lengths :&[u8]) -> Result<VorbisHuffmanTree, HuffmanError> {
		// First step: generate a simple tree representing the
		// Huffman tree
		let mut simple_tree = HuffTree { even_childs :true, payload :None, l :None, r :None };
		let mut cnt :usize = 0;
		let mut last_valid_idx = None;
		for (i, &codeword_length) in codebook_codeword_lengths.iter().enumerate() {
			if codeword_length == 0 {
				continue;
			}
			cnt += 1;
			last_valid_idx = Some(i);
			if !simple_tree.insert_rec(i as u32, codeword_length) {
				try!(Err(HuffmanError::Overspecified)) /* Overspecified, can't be put into tree */
			}
		}
		//println!("The tree:\n{:?}", simple_tree);

		// Single entry codebook special handling
		if cnt == 1 {
			let decoded = last_valid_idx.unwrap();
			let encoded_len = codebook_codeword_lengths[decoded];
			if encoded_len == 1 {
				// Return a vorbis tree that returns decoded for any single bit input
				return Ok(VorbisHuffmanTree {
					desc_prog :vec![1u32 << 31, 3, 3, decoded as u32],
					unrolled_entries :[
						UnrolledLookupEntry::HasEntry(1, decoded as u32); 256
					],
				});
			} else {
				// Single entry codebooks must have 1 as their only length entry
				try!(Err(HuffmanError::InvalidSingleEntry))
			}
		}

		if !simple_tree.even_childs {
			try!(Err(HuffmanError::Underpopulated)); /* Underpopulated */
		}

		// Second step: generate the actual desc_prog
		// by pre_order traversal of the tree.
		//
		// The general advantage of this approach over one with only the simple tree
		// is better cache locality and less memory requirements (at least after the
		// setup with the simple tree).
		let mut desc_prog = Vec::with_capacity(cnt);
		fn traverse(tree :& HuffTree, desc_prog :&mut Vec<u32>) -> u32 {
			let cur_pos = desc_prog.len() as u32;
			let has_children = tree.l.is_some() || tree.r.is_some();

			let entry = ((has_children as u32) << 31) | tree.payload.unwrap_or(0);
			//println!("push node (w_children : {:?}) at {:?} : {:?}", has_children, cur_pos, entry);
			desc_prog.push(entry);

			if has_children {
				desc_prog.push(0);
				desc_prog.push(0);
				desc_prog[cur_pos as usize + 1] =
					traverse(tree.l.as_ref().unwrap(), desc_prog);
				/*println!("left child of node {:?}: at {:?}", cur_pos,
					desc_prog[cur_pos as usize + 1]);// */
				desc_prog[cur_pos as usize + 2] =
					traverse(tree.r.as_ref().unwrap(), desc_prog);
				/*println!("right child of node {:?}: at {:?}", cur_pos,
					desc_prog[cur_pos as usize + 2]);// */
			}
			return cur_pos;
		}
		assert_eq!(traverse(&simple_tree, &mut desc_prog), 0);

		// Third step: generate unrolled entries array
		// Also by pre_order traversal.
		//
		// This gives us a speedup over desc_prog as reading the unrolled
		// entries should involve less branching and less lookups overall.
		let mut unrolled_entries = [UnrolledLookupEntry::Inconclusive; 256];
		fn uroll_traverse(tree :& HuffTree,
				unrolled_entries :&mut [UnrolledLookupEntry; 256],
				prefix :u32, prefix_idx :u8,
				desc_prog :&[u32], desc_prog_idx :u32) {
			let has_children = tree.l.is_some() || tree.r.is_some();

			if has_children {
				// There are children.
				// We'd like to recurse deeper. Can we?
				if prefix_idx == 8 {
					// No we can't.
					// The tree is too deep.
					unrolled_entries[prefix as usize] =
						UnrolledLookupEntry::InconclusiveWithHint(desc_prog_idx);
				} else {
					// Recurse deeper.
					uroll_traverse(tree.l.as_ref().unwrap(),
						unrolled_entries,
						prefix + (0 << prefix_idx), prefix_idx + 1,
						desc_prog, desc_prog[desc_prog_idx as usize + 1]);
					uroll_traverse(tree.r.as_ref().unwrap(),
						unrolled_entries,
						prefix + (1 << prefix_idx), prefix_idx + 1,
						desc_prog, desc_prog[desc_prog_idx as usize + 2]);
				}
			} else {
				// No children, fill the entries in the range according to
				// the prefix we have.
				let payload = tree.payload.unwrap();
				let it = 1 << prefix_idx;
				let mut i = prefix as usize;
				for _ in 1 .. (1u16 << (8 - prefix_idx)) {
					unrolled_entries[i] =
						UnrolledLookupEntry::HasEntry(prefix_idx, payload);
					i += it;
				}
			}
		}
		if cnt > 0 {
			uroll_traverse(&simple_tree,
				&mut unrolled_entries, 0, 0, &desc_prog, 0);
		}

		// Now we are done, return the result
		return Ok(VorbisHuffmanTree {
			desc_prog,
			unrolled_entries,
		});
	}
/// Constructs a new `VorbisHuffmanTree` instance from the passed array,
/// like the vorbis spec demands.
///
/// Returns the resulting tree if the array results in a valid (neither
/// underspecified nor overspecified) tree.
Constructs a new `VorbisHuffmanTree` instance from the passed array,
like the vorbis spec demands.

Returns the resulting tree if the array results in a valid (neither
underspecified nor overspecified) tree.
Constructs a new ` VorbisHuffmanTree ` instance from the passed array like the vorbis spec demands . Returns the resulting tree if the array results in a valid ( neither underspecified nor overspecified ) tree .
pub fn load_from_array(codebook_codeword_lengths :&[u8]) -> Result<VorbisHuffmanTree, HuffmanError> {
		// First step: generate a simple tree representing the
		// Huffman tree
		let mut simple_tree = HuffTree { even_childs :true, payload :None, l :None, r :None };
		let mut cnt :usize = 0;
		let mut last_valid_idx = None;
		for (i, &codeword_length) in codebook_codeword_lengths.iter().enumerate() {
			if codeword_length == 0 {
				continue;
			}
			cnt += 1;
			last_valid_idx = Some(i);
			if !simple_tree.insert_rec(i as u32, codeword_length) {
				try!(Err(HuffmanError::Overspecified)) /* Overspecified, can't be put into tree */
			}
		}
		//println!("The tree:\n{:?}", simple_tree);
		// Single entry codebook special handling
		if cnt == 1 {
			let decoded = last_valid_idx.unwrap();
			let encoded_len = codebook_codeword_lengths[decoded];
			if encoded_len == 1 {
				// Return a vorbis tree that returns decoded for any single bit input
				return Ok(VorbisHuffmanTree {
					desc_prog :vec![1u32 << 31, 3, 3, decoded as u32],
					unrolled_entries :[
						UnrolledLookupEntry::HasEntry(1, decoded as u32); 256
					],
				});
			} else {
				// Single entry codebooks must have 1 as their only length entry
				try!(Err(HuffmanError::InvalidSingleEntry))
			}
		}
		if !simple_tree.even_childs {
			try!(Err(HuffmanError::Underpopulated)); /* Underpopulated */
		}
		// Second step: generate the actual desc_prog
		// by pre_order traversal of the tree.
		//
		// The general advantage of this approach over one with only the simple tree
		// is better cache locality and less memory requirements (at least after the
		// setup with the simple tree).
		let mut desc_prog = Vec::with_capacity(cnt);
		fn traverse(tree :& HuffTree, desc_prog :&mut Vec<u32>) -> u32 {
			let cur_pos = desc_prog.len() as u32;
			let has_children = tree.l.is_some() || tree.r.is_some();
			let entry = ((has_children as u32) << 31) | tree.payload.unwrap_or(0);
			//println!("push node (w_children : {:?}) at {:?} : {:?}", has_children, cur_pos, entry);
			desc_prog.push(entry);
			if has_children {
				desc_prog.push(0);
				desc_prog.push(0);
				desc_prog[cur_pos as usize + 1] =
					traverse(tree.l.as_ref().unwrap(), desc_prog);
				/*println!("left child of node {:?}: at {:?}", cur_pos,
					desc_prog[cur_pos as usize + 1]);// */
				desc_prog[cur_pos as usize + 2] =
					traverse(tree.r.as_ref().unwrap(), desc_prog);
				/*println!("right child of node {:?}: at {:?}", cur_pos,
					desc_prog[cur_pos as usize + 2]);// */
			}
			return cur_pos;
		}
		assert_eq!(traverse(&simple_tree, &mut desc_prog), 0);
		// Third step: generate unrolled entries array
		// Also by pre_order traversal.
		//
		// This gives us a speedup over desc_prog as reading the unrolled
		// entries should involve less branching and less lookups overall.
		let mut unrolled_entries = [UnrolledLookupEntry::Inconclusive; 256];
		fn uroll_traverse(tree :& HuffTree,
				unrolled_entries :&mut [UnrolledLookupEntry; 256],
				prefix :u32, prefix_idx :u8,
				desc_prog :&[u32], desc_prog_idx :u32) {
			let has_children = tree.l.is_some() || tree.r.is_some();
			if has_children {
				// There are children.
				// We'd like to recurse deeper. Can we?
				if prefix_idx == 8 {
					// No we can't.
					// The tree is too deep.
					unrolled_entries[prefix as usize] =
						UnrolledLookupEntry::InconclusiveWithHint(desc_prog_idx);
				} else {
					// Recurse deeper.
					uroll_traverse(tree.l.as_ref().unwrap(),
						unrolled_entries,
						prefix + (0 << prefix_idx), prefix_idx + 1,
						desc_prog, desc_prog[desc_prog_idx as usize + 1]);
					uroll_traverse(tree.r.as_ref().unwrap(),
						unrolled_entries,
						prefix + (1 << prefix_idx), prefix_idx + 1,
						desc_prog, desc_prog[desc_prog_idx as usize + 2]);
				}
			} else {
				// No children, fill the entries in the range according to
				// the prefix we have.
				let payload = tree.payload.unwrap();
				let it = 1 << prefix_idx;
				let mut i = prefix as usize;
				for _ in 1 .. (1u16 << (8 - prefix_idx)) {
					unrolled_entries[i] =
						UnrolledLookupEntry::HasEntry(prefix_idx, payload);
					i += it;
				}
			}
		}
		if cnt > 0 {
			uroll_traverse(&simple_tree,
				&mut unrolled_entries, 0, 0, &desc_prog, 0);
		}
		// Now we are done, return the result
		return Ok(VorbisHuffmanTree {
			desc_prog,
			unrolled_entries,
		});
	}
pub fn load_from_array ( codebook_codeword_lengths : & [ u8 ] ) -> Result < VorbisHuffmanTree , HuffmanError > { // First step: generate a simple tree representing the // Huffman tree let mut simple_tree = HuffTree { even_childs : true , payload : None , l : None , r : None } ; let mut cnt : usize = 0 ; let mut last_valid_idx = None ; for ( i , & codeword_length ) in codebook_codeword_lengths . iter ( ) . enumerate ( ) { if codeword_length == 0 { continue ; } cnt += 1 ; last_valid_idx = Some ( i ) ; if ! simple_tree . insert_rec ( i as u32 , codeword_length ) { try ! ( Err ( HuffmanError Overspecified ) ) /* Overspecified, can't be put into tree */ } } //println!("The tree:\n{:?}", simple_tree); // Single entry codebook special handling if cnt == 1 { let decoded = last_valid_idx . unwrap ( ) ; let encoded_len = codebook_codeword_lengths [ decoded ] ; if encoded_len == 1 { // Return a vorbis tree that returns decoded for any single bit input return Ok ( VorbisHuffmanTree { desc_prog : vec ! [ 1u32 31 3 3 decoded as u32 ] , unrolled_entries : [ UnrolledLookupEntry :: HasEntry ( 1 , decoded as u32 ) ; 256 ] , } ) ; } else { // Single entry codebooks must have 1 as their only length entry try ! ( Err ( HuffmanError InvalidSingleEntry ) ) } } if ! simple_tree . even_childs { try ! ( Err ( HuffmanError Underpopulated ) ) ; /* Underpopulated */ } // Second step: generate the actual desc_prog // by pre_order traversal of the tree. // // The general advantage of this approach over one with only the simple tree // is better cache locality and less memory requirements (at least after the // setup with the simple tree). let mut desc_prog = Vec :: with_capacity ( cnt ) ; fn traverse ( tree : & HuffTree , desc_prog : & mut Vec < u32 > ) -> u32 { let cur_pos = desc_prog . len ( ) as u32 ; let has_children = tree . l . is_some ( ) || tree . r . is_some ( ) ; let entry = ( ( has_children as u32 ) << 31 ) | tree . payload . unwrap_or ( 0 ) ; //println!("push node (w_children : {:?}) at {:?} : {:?}", has_children, cur_pos, entry); desc_prog . push ( entry ) ; if has_children { desc_prog . push ( 0 ) ; desc_prog . push ( 0 ) ; desc_prog [ cur_pos as usize + 1 ] = traverse ( tree . l . as_ref ( ) . unwrap ( ) , desc_prog ) ; /*println!("left child of node {:?}: at {:?}", cur_pos,
					desc_prog[cur_pos as usize + 1]);// */ desc_prog [ cur_pos as usize + 2 ] = traverse ( tree . r . as_ref ( ) . unwrap ( ) , desc_prog ) ; /*println!("right child of node {:?}: at {:?}", cur_pos,
					desc_prog[cur_pos as usize + 2]);// */ } return cur_pos ; } assert_eq ! ( traverse ( simple_tree mut desc_prog ) 0 ) ; // Third step: generate unrolled entries array // Also by pre_order traversal. // // This gives us a speedup over desc_prog as reading the unrolled // entries should involve less branching and less lookups overall. let mut unrolled_entries = [ UnrolledLookupEntry :: Inconclusive ; 256 ] ; fn uroll_traverse ( tree : & HuffTree , unrolled_entries : & mut [ UnrolledLookupEntry ; 256 ] , prefix : u32 , prefix_idx : u8 , desc_prog : & [ u32 ] , desc_prog_idx : u32 ) { let has_children = tree . l . is_some ( ) || tree . r . is_some ( ) ; if has_children { // There are children. // We'd like to recurse deeper. Can we? if prefix_idx == 8 { // No we can't. // The tree is too deep. unrolled_entries [ prefix as usize ] = UnrolledLookupEntry :: InconclusiveWithHint ( desc_prog_idx ) ; } else { // Recurse deeper. uroll_traverse ( tree . l . as_ref ( ) . unwrap ( ) , unrolled_entries , prefix + ( 0 << prefix_idx ) , prefix_idx + 1 , desc_prog , desc_prog [ desc_prog_idx as usize + 1 ] ) ; uroll_traverse ( tree . r . as_ref ( ) . unwrap ( ) , unrolled_entries , prefix + ( 1 << prefix_idx ) , prefix_idx + 1 , desc_prog , desc_prog [ desc_prog_idx as usize + 2 ] ) ; } } else { // No children, fill the entries in the range according to // the prefix we have. let payload = tree . payload . unwrap ( ) ; let it = 1 << prefix_idx ; let mut i = prefix as usize ; for _ in 1 .. ( 1u16 << ( 8 - prefix_idx ) ) { unrolled_entries [ i ] = UnrolledLookupEntry :: HasEntry ( prefix_idx , payload ) ; i += it ; } } } if cnt > 0 { uroll_traverse ( & simple_tree , & mut unrolled_entries , 0 , 0 , & desc_prog , 0 ) ; } // Now we are done, return the result return Ok ( VorbisHuffmanTree { desc_prog , unrolled_entries , } ) ; }
Constructs a new `VorbisHuffmanTree` instance from the passed array,
like the vorbis spec demands.
Constructs a new ` VorbisHuffmanTree ` instance from the passed array like the vorbis spec demands .
codebook_codeword_lengths
&[u8]
codebook_codeword_lengths
&[u8]