Mercurial > libavcodec.hg
comparison huffman.c @ 6473:e0cd9697ac6d libavcodec
huffman: add a zero_count flag and use it in fraps
fixes issue349
author | aurel |
---|---|
date | Sat, 08 Mar 2008 18:08:16 +0000 |
parents | e39e03d99d24 |
children | 524cb7f5ad2b |
comparison
equal
deleted
inserted
replaced
6472:e39e03d99d24 | 6473:e0cd9697ac6d |
---|---|
26 | 26 |
27 /* symbol for Huffman tree node */ | 27 /* symbol for Huffman tree node */ |
28 #define HNODE -1 | 28 #define HNODE -1 |
29 | 29 |
30 | 30 |
31 static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, Node *nodes, int node, uint32_t pfx, int pl, int *pos) | 31 static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, Node *nodes, int node, uint32_t pfx, int pl, int *pos, int no_zero_count) |
32 { | 32 { |
33 int s; | 33 int s; |
34 | 34 |
35 s = nodes[node].sym; | 35 s = nodes[node].sym; |
36 if(s != HNODE || !nodes[node].count){ | 36 if(s != HNODE || (no_zero_count && !nodes[node].count)){ |
37 bits[*pos] = pfx; | 37 bits[*pos] = pfx; |
38 lens[*pos] = pl; | 38 lens[*pos] = pl; |
39 xlat[*pos] = s; | 39 xlat[*pos] = s; |
40 (*pos)++; | 40 (*pos)++; |
41 }else{ | 41 }else{ |
42 pfx <<= 1; | 42 pfx <<= 1; |
43 pl++; | 43 pl++; |
44 get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0, pfx, pl, pos); | 44 get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0, pfx, pl, pos, |
45 no_zero_count); | |
45 pfx |= 1; | 46 pfx |= 1; |
46 get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0+1, pfx, pl, pos); | 47 get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0+1, pfx, pl, pos, |
48 no_zero_count); | |
47 } | 49 } |
48 } | 50 } |
49 | 51 |
50 static int build_huff_tree(VLC *vlc, Node *nodes, int head) | 52 static int build_huff_tree(VLC *vlc, Node *nodes, int head, int flags) |
51 { | 53 { |
54 int no_zero_count = !(flags & FF_HUFFMAN_FLAG_ZERO_COUNT); | |
52 uint32_t bits[256]; | 55 uint32_t bits[256]; |
53 int16_t lens[256]; | 56 int16_t lens[256]; |
54 uint8_t xlat[256]; | 57 uint8_t xlat[256]; |
55 int pos = 0; | 58 int pos = 0; |
56 | 59 |
57 get_tree_codes(bits, lens, xlat, nodes, head, 0, 0, &pos); | 60 get_tree_codes(bits, lens, xlat, nodes, head, 0, 0, &pos, no_zero_count); |
58 return init_vlc_sparse(vlc, 9, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0); | 61 return init_vlc_sparse(vlc, 9, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0); |
59 } | 62 } |
60 | 63 |
61 | 64 |
62 /** | 65 /** |
96 break; | 99 break; |
97 FFSWAP(Node, nodes[j], nodes[j-1]); | 100 FFSWAP(Node, nodes[j], nodes[j-1]); |
98 } | 101 } |
99 cur_node++; | 102 cur_node++; |
100 } | 103 } |
101 if(build_huff_tree(vlc, nodes, nb_codes*2-2) < 0){ | 104 if(build_huff_tree(vlc, nodes, nb_codes*2-2, flags) < 0){ |
102 av_log(avctx, AV_LOG_ERROR, "Error building tree\n"); | 105 av_log(avctx, AV_LOG_ERROR, "Error building tree\n"); |
103 return -1; | 106 return -1; |
104 } | 107 } |
105 return 0; | 108 return 0; |
106 } | 109 } |