comparison fraps.c @ 5820:ffac546a3861 libavcodec

moves fraps huffman decoder to its own file, making it more generic
author aurel
date Sun, 14 Oct 2007 21:19:40 +0000
parents 2b72f9bc4f06
children d2af52426ef7
comparison
equal deleted inserted replaced
5819:88e131c2d3f8 5820:ffac546a3861
31 * Version 2 files support by Konstantin Shishkov 31 * Version 2 files support by Konstantin Shishkov
32 */ 32 */
33 33
34 #include "avcodec.h" 34 #include "avcodec.h"
35 #include "bitstream.h" 35 #include "bitstream.h"
36 #include "huffman.h"
37 #include "bytestream.h"
36 #include "dsputil.h" 38 #include "dsputil.h"
37 39
38 #define FPS_TAG MKTAG('F', 'P', 'S', 'x') 40 #define FPS_TAG MKTAG('F', 'P', 'S', 'x')
39
40 /* symbol for Huffman tree node */
41 #define HNODE -1
42
43 /**
44 * Huffman node
45 * FIXME one day this should belong to one general framework
46 */
47 typedef struct Node{
48 int16_t sym;
49 int16_t n0;
50 int count;
51 }Node;
52 41
53 /** 42 /**
54 * local variable storage 43 * local variable storage
55 */ 44 */
56 typedef struct FrapsContext{ 45 typedef struct FrapsContext{
57 AVCodecContext *avctx; 46 AVCodecContext *avctx;
58 AVFrame frame; 47 AVFrame frame;
59 Node nodes[512];
60 uint8_t *tmpbuf; 48 uint8_t *tmpbuf;
61 DSPContext dsp; 49 DSPContext dsp;
62 } FrapsContext; 50 } FrapsContext;
63 51
64 52
89 */ 77 */
90 static int huff_cmp(const void *va, const void *vb){ 78 static int huff_cmp(const void *va, const void *vb){
91 const Node *a = va, *b = vb; 79 const Node *a = va, *b = vb;
92 return (a->count - b->count)*256 + a->sym - b->sym; 80 return (a->count - b->count)*256 + a->sym - b->sym;
93 } 81 }
94
95 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)
96 {
97 int s;
98
99 s = nodes[node].sym;
100 if(s != HNODE || !nodes[node].count){
101 bits[*pos] = pfx;
102 lens[*pos] = pl;
103 xlat[*pos] = s;
104 (*pos)++;
105 }else{
106 pfx <<= 1;
107 pl++;
108 get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0, pfx, pl, pos);
109 pfx |= 1;
110 get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0+1, pfx, pl, pos);
111 }
112 }
113
114 static int build_huff_tree(VLC *vlc, Node *nodes, uint8_t *xlat)
115 {
116 uint32_t bits[256];
117 int16_t lens[256];
118 int pos = 0;
119
120 get_tree_codes(bits, lens, xlat, nodes, 510, 0, 0, &pos);
121 return init_vlc(vlc, 9, pos, lens, 2, 2, bits, 4, 4, 0);
122 }
123
124 82
125 /** 83 /**
126 * decode Fraps v2 packed plane 84 * decode Fraps v2 packed plane
127 */ 85 */
128 static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, 86 static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w,
129 int h, uint8_t *src, int size, int Uoff) 87 int h, uint8_t *src, int size, int Uoff)
130 { 88 {
131 int i, j; 89 int i, j;
132 int cur_node;
133 GetBitContext gb; 90 GetBitContext gb;
134 VLC vlc; 91 VLC vlc;
135 int64_t sum = 0; 92 Node nodes[512];
136 uint8_t recode[256]; 93
137 94 for(i = 0; i < 256; i++)
138 for(i = 0; i < 256; i++){ 95 nodes[i].count = bytestream_get_le32(&src);
139 s->nodes[i].sym = i;
140 s->nodes[i].count = AV_RL32(src);
141 s->nodes[i].n0 = -2;
142 if(s->nodes[i].count < 0) {
143 av_log(s->avctx, AV_LOG_ERROR, "Symbol count < 0\n");
144 return -1;
145 }
146 src += 4;
147 sum += s->nodes[i].count;
148 }
149 size -= 1024; 96 size -= 1024;
150 97 if (ff_huff_build_tree(s->avctx, &vlc, 256, nodes, huff_cmp, 0) < 0)
151 if(sum >> 31) {
152 av_log(s->avctx, AV_LOG_ERROR, "Too high symbol frequencies. Tree construction is not possible\n");
153 return -1; 98 return -1;
154 }
155 qsort(s->nodes, 256, sizeof(Node), huff_cmp);
156 cur_node = 256;
157 for(i = 0; i < 511; i += 2){
158 s->nodes[cur_node].sym = HNODE;
159 s->nodes[cur_node].count = s->nodes[i].count + s->nodes[i+1].count;
160 s->nodes[cur_node].n0 = i;
161 for(j = cur_node; j > 0; j--){
162 if(s->nodes[j].count >= s->nodes[j - 1].count) break;
163 FFSWAP(Node, s->nodes[j], s->nodes[j - 1]);
164 }
165 cur_node++;
166 }
167 if(build_huff_tree(&vlc, s->nodes, recode) < 0){
168 av_log(s->avctx, AV_LOG_ERROR, "Error building tree\n");
169 return -1;
170 }
171 /* we have built Huffman table and are ready to decode plane */ 99 /* we have built Huffman table and are ready to decode plane */
172 100
173 /* convert bits so they may be used by standard bitreader */ 101 /* convert bits so they may be used by standard bitreader */
174 s->dsp.bswap_buf(s->tmpbuf, src, size >> 2); 102 s->dsp.bswap_buf(s->tmpbuf, src, size >> 2);
175 103
176 init_get_bits(&gb, s->tmpbuf, size * 8); 104 init_get_bits(&gb, s->tmpbuf, size * 8);
177 for(j = 0; j < h; j++){ 105 for(j = 0; j < h; j++){
178 for(i = 0; i < w; i++){ 106 for(i = 0; i < w; i++){
179 dst[i] = recode[get_vlc2(&gb, vlc.table, 9, 3)]; 107 dst[i] = get_vlc2(&gb, vlc.table, 9, 3);
180 /* lines are stored as deltas between previous lines 108 /* lines are stored as deltas between previous lines
181 * and we need to add 0x80 to the first lines of chroma planes 109 * and we need to add 0x80 to the first lines of chroma planes
182 */ 110 */
183 if(j) dst[i] += dst[i - stride]; 111 if(j) dst[i] += dst[i - stride];
184 else if(Uoff) dst[i] += 0x80; 112 else if(Uoff) dst[i] += 0x80;