summaryrefslogtreecommitdiff
path: root/media/libtheora/lib/huffdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/libtheora/lib/huffdec.c')
-rw-r--r--media/libtheora/lib/huffdec.c521
1 files changed, 0 insertions, 521 deletions
diff --git a/media/libtheora/lib/huffdec.c b/media/libtheora/lib/huffdec.c
deleted file mode 100644
index fe013c611..000000000
--- a/media/libtheora/lib/huffdec.c
+++ /dev/null
@@ -1,521 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 *
- * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function:
- last mod: $Id: huffdec.c 17577 2010-10-29 04:00:07Z tterribe $
-
- ********************************************************************/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ogg/ogg.h>
-#include "huffdec.h"
-#include "decint.h"
-
-
-
-/*Instead of storing every branching in the tree, subtrees can be collapsed
- into one node, with a table of size 1<<nbits pointing directly to its
- descedents nbits levels down.
- This allows more than one bit to be read at a time, and avoids following all
- the intermediate branches with next to no increased code complexity once
- the collapsed tree has been built.
- We do _not_ require that a subtree be complete to be collapsed, but instead
- store duplicate pointers in the table, and record the actual depth of the
- node below its parent.
- This tells us the number of bits to advance the stream after reaching it.
-
- This turns out to be equivalent to the method described in \cite{Hash95},
- without the requirement that codewords be sorted by length.
- If the codewords were sorted by length (so-called ``canonical-codes''), they
- could be decoded much faster via either Lindell and Moffat's approach or
- Hashemian's Condensed Huffman Code approach, the latter of which has an
- extremely small memory footprint.
- We can't use Choueka et al.'s finite state machine approach, which is
- extremely fast, because we can't allow multiple symbols to be output at a
- time; the codebook can and does change between symbols.
- It also has very large memory requirements, which impairs cache coherency.
-
- We store the tree packed in an array of 16-bit integers (words).
- Each node consists of a single word, followed consecutively by two or more
- indices of its children.
- Let n be the value of this first word.
- This is the number of bits that need to be read to traverse the node, and
- must be positive.
- 1<<n entries follow in the array, each an index to a child node.
- If the child is positive, then it is the index of another internal node in
- the table.
- If the child is negative or zero, then it is a leaf node.
- These are stored directly in the child pointer to save space, since they only
- require a single word.
- If a leaf node would have been encountered before reading n bits, then it is
- duplicated the necessary number of times in this table.
- Leaf nodes pack both a token value and their actual depth in the tree.
- The token in the leaf node is (-leaf&255).
- The number of bits that need to be consumed to reach the leaf, starting from
- the current node, is (-leaf>>8).
-
- @ARTICLE{Hash95,
- author="Reza Hashemian",
- title="Memory Efficient and High-Speed Search {Huffman} Coding",
- journal="{IEEE} Transactions on Communications",
- volume=43,
- number=10,
- pages="2576--2581",
- month=Oct,
- year=1995
- }*/
-
-
-
-/*The map from external spec-defined tokens to internal tokens.
- This is constructed so that any extra bits read with the original token value
- can be masked off the least significant bits of its internal token index.
- In addition, all of the tokens which require additional extra bits are placed
- at the start of the list, and grouped by type.
- OC_DCT_REPEAT_RUN3_TOKEN is placed first, as it is an extra-special case, so
- giving it index 0 may simplify comparisons on some architectures.
- These requirements require some substantial reordering.*/
-static const unsigned char OC_DCT_TOKEN_MAP[TH_NDCT_TOKENS]={
- /*OC_DCT_EOB1_TOKEN (0 extra bits)*/
- 15,
- /*OC_DCT_EOB2_TOKEN (0 extra bits)*/
- 16,
- /*OC_DCT_EOB3_TOKEN (0 extra bits)*/
- 17,
- /*OC_DCT_REPEAT_RUN0_TOKEN (2 extra bits)*/
- 88,
- /*OC_DCT_REPEAT_RUN1_TOKEN (3 extra bits)*/
- 80,
- /*OC_DCT_REPEAT_RUN2_TOKEN (4 extra bits)*/
- 1,
- /*OC_DCT_REPEAT_RUN3_TOKEN (12 extra bits)*/
- 0,
- /*OC_DCT_SHORT_ZRL_TOKEN (3 extra bits)*/
- 48,
- /*OC_DCT_ZRL_TOKEN (6 extra bits)*/
- 14,
- /*OC_ONE_TOKEN (0 extra bits)*/
- 56,
- /*OC_MINUS_ONE_TOKEN (0 extra bits)*/
- 57,
- /*OC_TWO_TOKEN (0 extra bits)*/
- 58,
- /*OC_MINUS_TWO_TOKEN (0 extra bits)*/
- 59,
- /*OC_DCT_VAL_CAT2 (1 extra bit)*/
- 60,
- 62,
- 64,
- 66,
- /*OC_DCT_VAL_CAT3 (2 extra bits)*/
- 68,
- /*OC_DCT_VAL_CAT4 (3 extra bits)*/
- 72,
- /*OC_DCT_VAL_CAT5 (4 extra bits)*/
- 2,
- /*OC_DCT_VAL_CAT6 (5 extra bits)*/
- 4,
- /*OC_DCT_VAL_CAT7 (6 extra bits)*/
- 6,
- /*OC_DCT_VAL_CAT8 (10 extra bits)*/
- 8,
- /*OC_DCT_RUN_CAT1A (1 extra bit)*/
- 18,
- 20,
- 22,
- 24,
- 26,
- /*OC_DCT_RUN_CAT1B (3 extra bits)*/
- 32,
- /*OC_DCT_RUN_CAT1C (4 extra bits)*/
- 12,
- /*OC_DCT_RUN_CAT2A (2 extra bits)*/
- 28,
- /*OC_DCT_RUN_CAT2B (3 extra bits)*/
- 40
-};
-
-/*The log base 2 of number of internal tokens associated with each of the spec
- tokens (i.e., how many of the extra bits are folded into the token value).
- Increasing the maximum value beyond 3 will enlarge the amount of stack
- required for tree construction.*/
-static const unsigned char OC_DCT_TOKEN_MAP_LOG_NENTRIES[TH_NDCT_TOKENS]={
- 0,0,0,2,3,0,0,3,0,0,0,0,0,1,1,1,1,2,3,1,1,1,2,1,1,1,1,1,3,1,2,3
-};
-
-
-/*The size a lookup table is allowed to grow to relative to the number of
- unique nodes it contains.
- E.g., if OC_HUFF_SLUSH is 4, then at most 75% of the space in the tree is
- wasted (1/4 of the space must be used).
- Larger numbers can decode tokens with fewer read operations, while smaller
- numbers may save more space.
- With a sample file:
- 32233473 read calls are required when no tree collapsing is done (100.0%).
- 19269269 read calls are required when OC_HUFF_SLUSH is 1 (59.8%).
- 11144969 read calls are required when OC_HUFF_SLUSH is 2 (34.6%).
- 10538563 read calls are required when OC_HUFF_SLUSH is 4 (32.7%).
- 10192578 read calls are required when OC_HUFF_SLUSH is 8 (31.6%).
- Since a value of 2 gets us the vast majority of the speed-up with only a
- small amount of wasted memory, this is what we use.
- This value must be less than 128, or you could create a tree with more than
- 32767 entries, which would overflow the 16-bit words used to index it.*/
-#define OC_HUFF_SLUSH (2)
-/*The root of the tree is on the fast path, and a larger value here is more
- beneficial than elsewhere in the tree.
- 7 appears to give the best performance, trading off between increased use of
- the single-read fast path and cache footprint for the tables, though
- obviously this will depend on your cache size.
- Using 7 here, the VP3 tables are about twice as large compared to using 2.*/
-#define OC_ROOT_HUFF_SLUSH (7)
-
-
-
-/*Unpacks a Huffman codebook.
- _opb: The buffer to unpack from.
- _tokens: Stores a list of internal tokens, in the order they were found in
- the codebook, and the lengths of their corresponding codewords.
- This is enough to completely define the codebook, while minimizing
- stack usage and avoiding temporary allocations (for platforms
- where free() is a no-op).
- Return: The number of internal tokens in the codebook, or a negative value
- on error.*/
-int oc_huff_tree_unpack(oc_pack_buf *_opb,unsigned char _tokens[256][2]){
- ogg_uint32_t code;
- int len;
- int ntokens;
- int nleaves;
- code=0;
- len=ntokens=nleaves=0;
- for(;;){
- long bits;
- bits=oc_pack_read1(_opb);
- /*Only process nodes so long as there's more bits in the buffer.*/
- if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
- /*Read an internal node:*/
- if(!bits){
- len++;
- /*Don't allow codewords longer than 32 bits.*/
- if(len>32)return TH_EBADHEADER;
- }
- /*Read a leaf node:*/
- else{
- ogg_uint32_t code_bit;
- int neb;
- int nentries;
- int token;
- /*Don't allow more than 32 spec-tokens per codebook.*/
- if(++nleaves>32)return TH_EBADHEADER;
- bits=oc_pack_read(_opb,OC_NDCT_TOKEN_BITS);
- neb=OC_DCT_TOKEN_MAP_LOG_NENTRIES[bits];
- token=OC_DCT_TOKEN_MAP[bits];
- nentries=1<<neb;
- while(nentries-->0){
- _tokens[ntokens][0]=(unsigned char)token++;
- _tokens[ntokens][1]=(unsigned char)(len+neb);
- ntokens++;
- }
- code_bit=0x80000000U>>len-1;
- while(len>0&&(code&code_bit)){
- code^=code_bit;
- code_bit<<=1;
- len--;
- }
- if(len<=0)break;
- code|=code_bit;
- }
- }
- return ntokens;
-}
-
-/*Count how many tokens would be required to fill a subtree at depth _depth.
- _tokens: A list of internal tokens, in the order they are found in the
- codebook, and the lengths of their corresponding codewords.
- _depth: The depth of the desired node in the corresponding tree structure.
- Return: The number of tokens that belong to that subtree.*/
-static int oc_huff_subtree_tokens(unsigned char _tokens[][2],int _depth){
- ogg_uint32_t code;
- int ti;
- code=0;
- ti=0;
- do{
- if(_tokens[ti][1]-_depth<32)code+=0x80000000U>>_tokens[ti++][1]-_depth;
- else{
- /*Because of the expanded internal tokens, we can have codewords as long
- as 35 bits.
- A single recursion here is enough to advance past them.*/
- code++;
- ti+=oc_huff_subtree_tokens(_tokens+ti,_depth+31);
- }
- }
- while(code<0x80000000U);
- return ti;
-}
-
-/*Compute the number of bits to use for a collapsed tree node at the given
- depth.
- _tokens: A list of internal tokens, in the order they are found in the
- codebook, and the lengths of their corresponding codewords.
- _ntokens: The number of tokens corresponding to this tree node.
- _depth: The depth of this tree node.
- Return: The number of bits to use for a collapsed tree node rooted here.
- This is always at least one, even if this was a leaf node.*/
-static int oc_huff_tree_collapse_depth(unsigned char _tokens[][2],
- int _ntokens,int _depth){
- int got_leaves;
- int loccupancy;
- int occupancy;
- int slush;
- int nbits;
- int best_nbits;
- slush=_depth>0?OC_HUFF_SLUSH:OC_ROOT_HUFF_SLUSH;
- /*It's legal to have a tree with just a single node, which requires no bits
- to decode and always returns the same token.
- However, no encoder actually does this (yet).
- To avoid a special case in oc_huff_token_decode(), we force the number of
- lookahead bits to be at least one.
- This will produce a tree that looks ahead one bit and then advances the
- stream zero bits.*/
- nbits=1;
- occupancy=2;
- got_leaves=1;
- do{
- int ti;
- if(got_leaves)best_nbits=nbits;
- nbits++;
- got_leaves=0;
- loccupancy=occupancy;
- for(occupancy=ti=0;ti<_ntokens;occupancy++){
- if(_tokens[ti][1]<_depth+nbits)ti++;
- else if(_tokens[ti][1]==_depth+nbits){
- got_leaves=1;
- ti++;
- }
- else ti+=oc_huff_subtree_tokens(_tokens+ti,_depth+nbits);
- }
- }
- while(occupancy>loccupancy&&occupancy*slush>=1<<nbits);
- return best_nbits;
-}
-
-/*Determines the size in words of a Huffman tree node that represents a
- subtree of depth _nbits.
- _nbits: The depth of the subtree.
- This must be greater than zero.
- Return: The number of words required to store the node.*/
-static size_t oc_huff_node_size(int _nbits){
- return 1+(1<<_nbits);
-}
-
-/*Produces a collapsed-tree representation of the given token list.
- _tree: The storage for the collapsed Huffman tree.
- This may be NULL to compute the required storage size instead of
- constructing the tree.
- _tokens: A list of internal tokens, in the order they are found in the
- codebook, and the lengths of their corresponding codewords.
- _ntokens: The number of tokens corresponding to this tree node.
- Return: The number of words required to store the tree.*/
-#if defined(_MSC_VER) && _MSC_VER >= 1700
-#pragma optimize( "", off )
-#endif
-static size_t oc_huff_tree_collapse(ogg_int16_t *_tree,
- unsigned char _tokens[][2],int _ntokens){
- ogg_int16_t node[34];
- unsigned char depth[34];
- unsigned char last[34];
- size_t ntree;
- int ti;
- int l;
- depth[0]=0;
- last[0]=(unsigned char)(_ntokens-1);
- ntree=0;
- ti=0;
- l=0;
- do{
- int nbits;
- nbits=oc_huff_tree_collapse_depth(_tokens+ti,last[l]+1-ti,depth[l]);
- node[l]=(ogg_int16_t)ntree;
- ntree+=oc_huff_node_size(nbits);
- if(_tree!=NULL)_tree[node[l]++]=(ogg_int16_t)nbits;
- do{
- while(ti<=last[l]&&_tokens[ti][1]<=depth[l]+nbits){
- if(_tree!=NULL){
- ogg_int16_t leaf;
- int nentries;
- nentries=1<<depth[l]+nbits-_tokens[ti][1];
- leaf=(ogg_int16_t)-(_tokens[ti][1]-depth[l]<<8|_tokens[ti][0]);
- while(nentries-->0)_tree[node[l]++]=leaf;
- }
- ti++;
- }
- if(ti<=last[l]){
- /*We need to recurse*/
- depth[l+1]=(unsigned char)(depth[l]+nbits);
- if(_tree!=NULL)_tree[node[l]++]=(ogg_int16_t)ntree;
- l++;
- last[l]=
- (unsigned char)(ti+oc_huff_subtree_tokens(_tokens+ti,depth[l])-1);
- break;
- }
- /*Pop back up a level of recursion.*/
- else if(l-->0)nbits=depth[l+1]-depth[l];
- }
- while(l>=0);
- }
- while(l>=0);
- return ntree;
-}
-#if defined(_MSC_VER) && _MSC_VER >= 1700
-#pragma optimize( "", on )
-#endif
-
-/*Unpacks a set of Huffman trees, and reduces them to a collapsed
- representation.
- _opb: The buffer to unpack the trees from.
- _nodes: The table to fill with the Huffman trees.
- Return: 0 on success, or a negative value on error.
- The caller is responsible for cleaning up any partially initialized
- _nodes on failure.*/
-int oc_huff_trees_unpack(oc_pack_buf *_opb,
- ogg_int16_t *_nodes[TH_NHUFFMAN_TABLES]){
- int i;
- for(i=0;i<TH_NHUFFMAN_TABLES;i++){
- unsigned char tokens[256][2];
- int ntokens;
- ogg_int16_t *tree;
- size_t size;
- /*Unpack the full tree into a temporary buffer.*/
- ntokens=oc_huff_tree_unpack(_opb,tokens);
- if(ntokens<0)return ntokens;
- /*Figure out how big the collapsed tree will be and allocate space for it.*/
- size=oc_huff_tree_collapse(NULL,tokens,ntokens);
- /*This should never happen; if it does it means you set OC_HUFF_SLUSH or
- OC_ROOT_HUFF_SLUSH too large.*/
- if(size>32767)return TH_EIMPL;
- tree=(ogg_int16_t *)_ogg_malloc(size*sizeof(*tree));
- if(tree==NULL)return TH_EFAULT;
- /*Construct the collapsed the tree.*/
- oc_huff_tree_collapse(tree,tokens,ntokens);
- _nodes[i]=tree;
- }
- return 0;
-}
-
-/*Determines the size in words of a Huffman subtree.
- _tree: The complete Huffman tree.
- _node: The index of the root of the desired subtree.
- Return: The number of words required to store the tree.*/
-static size_t oc_huff_tree_size(const ogg_int16_t *_tree,int _node){
- size_t size;
- int nchildren;
- int n;
- int i;
- n=_tree[_node];
- size=oc_huff_node_size(n);
- nchildren=1<<n;
- i=0;
- do{
- int child;
- child=_tree[_node+i+1];
- if(child<=0)i+=1<<n-(-child>>8);
- else{
- size+=oc_huff_tree_size(_tree,child);
- i++;
- }
- }
- while(i<nchildren);
- return size;
-}
-
-/*Makes a copy of the given set of Huffman trees.
- _dst: The array to store the copy in.
- _src: The array of trees to copy.*/
-int oc_huff_trees_copy(ogg_int16_t *_dst[TH_NHUFFMAN_TABLES],
- const ogg_int16_t *const _src[TH_NHUFFMAN_TABLES]){
- int total;
- int i;
- total=0;
- for(i=0;i<TH_NHUFFMAN_TABLES;i++){
- size_t size;
- size=oc_huff_tree_size(_src[i],0);
- total+=size;
- _dst[i]=(ogg_int16_t *)_ogg_malloc(size*sizeof(*_dst[i]));
- if(_dst[i]==NULL){
- while(i-->0)_ogg_free(_dst[i]);
- return TH_EFAULT;
- }
- memcpy(_dst[i],_src[i],size*sizeof(*_dst[i]));
- }
- return 0;
-}
-
-/*Frees the memory used by a set of Huffman trees.
- _nodes: The array of trees to free.*/
-void oc_huff_trees_clear(ogg_int16_t *_nodes[TH_NHUFFMAN_TABLES]){
- int i;
- for(i=0;i<TH_NHUFFMAN_TABLES;i++)_ogg_free(_nodes[i]);
-}
-
-
-/*Unpacks a single token using the given Huffman tree.
- _opb: The buffer to unpack the token from.
- _node: The tree to unpack the token with.
- Return: The token value.*/
-int oc_huff_token_decode_c(oc_pack_buf *_opb,const ogg_int16_t *_tree){
- const unsigned char *ptr;
- const unsigned char *stop;
- oc_pb_window window;
- int available;
- long bits;
- int node;
- int n;
- ptr=_opb->ptr;
- window=_opb->window;
- stop=_opb->stop;
- available=_opb->bits;
- node=0;
- for(;;){
- n=_tree[node];
- if(n>available){
- unsigned shift;
- shift=OC_PB_WINDOW_SIZE-available;
- do{
- /*We don't bother setting eof because we won't check for it after we've
- started decoding DCT tokens.*/
- if(ptr>=stop){
- shift=(unsigned)-OC_LOTS_OF_BITS;
- break;
- }
- shift-=8;
- window|=(oc_pb_window)*ptr++<<shift;
- }
- while(shift>=8);
- /*Note: We never request more than 24 bits, so there's no need to fill in
- the last partial byte here.*/
- available=OC_PB_WINDOW_SIZE-shift;
- }
- bits=window>>OC_PB_WINDOW_SIZE-n;
- node=_tree[node+1+bits];
- if(node<=0)break;
- window<<=n;
- available-=n;
- }
- node=-node;
- n=node>>8;
- window<<=n;
- available-=n;
- _opb->ptr=ptr;
- _opb->window=window;
- _opb->bits=available;
- return node&255;
-}