annotate common.c @ 0:986e461dc072 libavcodec

Initial revision
author glantau
date Sun, 22 Jul 2001 14:18:56 +0000
parents
children 1b4461b5a7fb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
1 /*
986e461dc072 Initial revision
glantau
parents:
diff changeset
2 * Common bit i/o utils
986e461dc072 Initial revision
glantau
parents:
diff changeset
3 * Copyright (c) 2000, 2001 Gerard Lantau.
986e461dc072 Initial revision
glantau
parents:
diff changeset
4 *
986e461dc072 Initial revision
glantau
parents:
diff changeset
5 * This program is free software; you can redistribute it and/or modify
986e461dc072 Initial revision
glantau
parents:
diff changeset
6 * it under the terms of the GNU General Public License as published by
986e461dc072 Initial revision
glantau
parents:
diff changeset
7 * the Free Software Foundation; either version 2 of the License, or
986e461dc072 Initial revision
glantau
parents:
diff changeset
8 * (at your option) any later version.
986e461dc072 Initial revision
glantau
parents:
diff changeset
9 *
986e461dc072 Initial revision
glantau
parents:
diff changeset
10 * This program is distributed in the hope that it will be useful,
986e461dc072 Initial revision
glantau
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
986e461dc072 Initial revision
glantau
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
986e461dc072 Initial revision
glantau
parents:
diff changeset
13 * GNU General Public License for more details.
986e461dc072 Initial revision
glantau
parents:
diff changeset
14 *
986e461dc072 Initial revision
glantau
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License
986e461dc072 Initial revision
glantau
parents:
diff changeset
16 * along with this program; if not, write to the Free Software
986e461dc072 Initial revision
glantau
parents:
diff changeset
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
986e461dc072 Initial revision
glantau
parents:
diff changeset
18 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
19 #include <stdlib.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
20 #include <stdio.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
21 #include <string.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
22 #ifdef __FreeBSD__
986e461dc072 Initial revision
glantau
parents:
diff changeset
23 #include <sys/param.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
24 #endif
986e461dc072 Initial revision
glantau
parents:
diff changeset
25 #include <netinet/in.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
26 #include <math.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
27 #include "common.h"
986e461dc072 Initial revision
glantau
parents:
diff changeset
28
986e461dc072 Initial revision
glantau
parents:
diff changeset
29 #define NDEBUG
986e461dc072 Initial revision
glantau
parents:
diff changeset
30 #include <assert.h>
986e461dc072 Initial revision
glantau
parents:
diff changeset
31
986e461dc072 Initial revision
glantau
parents:
diff changeset
32 void init_put_bits(PutBitContext *s,
986e461dc072 Initial revision
glantau
parents:
diff changeset
33 UINT8 *buffer, int buffer_size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
34 void *opaque,
986e461dc072 Initial revision
glantau
parents:
diff changeset
35 void (*write_data)(void *, UINT8 *, int))
986e461dc072 Initial revision
glantau
parents:
diff changeset
36 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
37 s->buf = buffer;
986e461dc072 Initial revision
glantau
parents:
diff changeset
38 s->buf_ptr = s->buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
39 s->buf_end = s->buf + buffer_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
40 s->bit_cnt=0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
41 s->bit_buf=0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
42 s->data_out_size = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
43 s->write_data = write_data;
986e461dc072 Initial revision
glantau
parents:
diff changeset
44 s->opaque = opaque;
986e461dc072 Initial revision
glantau
parents:
diff changeset
45 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
46
986e461dc072 Initial revision
glantau
parents:
diff changeset
47 static void flush_buffer(PutBitContext *s)
986e461dc072 Initial revision
glantau
parents:
diff changeset
48 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
49 int size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
50 if (s->write_data) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
51 size = s->buf_ptr - s->buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
52 if (size > 0)
986e461dc072 Initial revision
glantau
parents:
diff changeset
53 s->write_data(s->opaque, s->buf, size);
986e461dc072 Initial revision
glantau
parents:
diff changeset
54 s->buf_ptr = s->buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
55 s->data_out_size += size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
56 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
57 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
58
986e461dc072 Initial revision
glantau
parents:
diff changeset
59 void put_bits(PutBitContext *s, int n, unsigned int value)
986e461dc072 Initial revision
glantau
parents:
diff changeset
60 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
61 unsigned int bit_buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
62 int bit_cnt;
986e461dc072 Initial revision
glantau
parents:
diff changeset
63
986e461dc072 Initial revision
glantau
parents:
diff changeset
64 #ifdef STATS
986e461dc072 Initial revision
glantau
parents:
diff changeset
65 st_out_bit_counts[st_current_index] += n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
66 #endif
986e461dc072 Initial revision
glantau
parents:
diff changeset
67 // printf("put_bits=%d %x\n", n, value);
986e461dc072 Initial revision
glantau
parents:
diff changeset
68 assert(n == 32 || value < (1U << n));
986e461dc072 Initial revision
glantau
parents:
diff changeset
69
986e461dc072 Initial revision
glantau
parents:
diff changeset
70 bit_buf = s->bit_buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
71 bit_cnt = s->bit_cnt;
986e461dc072 Initial revision
glantau
parents:
diff changeset
72
986e461dc072 Initial revision
glantau
parents:
diff changeset
73 // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
74 /* XXX: optimize */
986e461dc072 Initial revision
glantau
parents:
diff changeset
75 if (n < (32-bit_cnt)) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
76 bit_buf |= value << (32 - n - bit_cnt);
986e461dc072 Initial revision
glantau
parents:
diff changeset
77 bit_cnt+=n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
78 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
79 bit_buf |= value >> (n + bit_cnt - 32);
986e461dc072 Initial revision
glantau
parents:
diff changeset
80 *(UINT32 *)s->buf_ptr = htonl(bit_buf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
81 //printf("bitbuf = %08x\n", bit_buf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
82 s->buf_ptr+=4;
986e461dc072 Initial revision
glantau
parents:
diff changeset
83 if (s->buf_ptr >= s->buf_end)
986e461dc072 Initial revision
glantau
parents:
diff changeset
84 flush_buffer(s);
986e461dc072 Initial revision
glantau
parents:
diff changeset
85 bit_cnt=bit_cnt + n - 32;
986e461dc072 Initial revision
glantau
parents:
diff changeset
86 if (bit_cnt == 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
87 bit_buf = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
88 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
89 bit_buf = value << (32 - bit_cnt);
986e461dc072 Initial revision
glantau
parents:
diff changeset
90 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
91 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
92
986e461dc072 Initial revision
glantau
parents:
diff changeset
93 s->bit_buf = bit_buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
94 s->bit_cnt = bit_cnt;
986e461dc072 Initial revision
glantau
parents:
diff changeset
95 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
96
986e461dc072 Initial revision
glantau
parents:
diff changeset
97 /* return the number of bits output */
986e461dc072 Initial revision
glantau
parents:
diff changeset
98 long long get_bit_count(PutBitContext *s)
986e461dc072 Initial revision
glantau
parents:
diff changeset
99 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
100 return (s->buf_ptr - s->buf + s->data_out_size) * 8 + (long long)s->bit_cnt;
986e461dc072 Initial revision
glantau
parents:
diff changeset
101 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
102
986e461dc072 Initial revision
glantau
parents:
diff changeset
103 void align_put_bits(PutBitContext *s)
986e461dc072 Initial revision
glantau
parents:
diff changeset
104 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
105 put_bits(s,(8 - s->bit_cnt) & 7,0);
986e461dc072 Initial revision
glantau
parents:
diff changeset
106 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
107
986e461dc072 Initial revision
glantau
parents:
diff changeset
108 /* pad the end of the output stream with zeros */
986e461dc072 Initial revision
glantau
parents:
diff changeset
109 void flush_put_bits(PutBitContext *s)
986e461dc072 Initial revision
glantau
parents:
diff changeset
110 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
111 while (s->bit_cnt > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
112 /* XXX: should test end of buffer */
986e461dc072 Initial revision
glantau
parents:
diff changeset
113 *s->buf_ptr++=s->bit_buf >> 24;
986e461dc072 Initial revision
glantau
parents:
diff changeset
114 s->bit_buf<<=8;
986e461dc072 Initial revision
glantau
parents:
diff changeset
115 s->bit_cnt-=8;
986e461dc072 Initial revision
glantau
parents:
diff changeset
116 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
117 flush_buffer(s);
986e461dc072 Initial revision
glantau
parents:
diff changeset
118 s->bit_cnt=0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
119 s->bit_buf=0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
120 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
121
986e461dc072 Initial revision
glantau
parents:
diff changeset
122 /* for jpeg : espace 0xff with 0x00 after it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
123 void jput_bits(PutBitContext *s, int n, unsigned int value)
986e461dc072 Initial revision
glantau
parents:
diff changeset
124 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
125 unsigned int bit_buf, b;
986e461dc072 Initial revision
glantau
parents:
diff changeset
126 int bit_cnt, i;
986e461dc072 Initial revision
glantau
parents:
diff changeset
127
986e461dc072 Initial revision
glantau
parents:
diff changeset
128 assert(n == 32 || value < (1U << n));
986e461dc072 Initial revision
glantau
parents:
diff changeset
129
986e461dc072 Initial revision
glantau
parents:
diff changeset
130 bit_buf = s->bit_buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
131 bit_cnt = s->bit_cnt;
986e461dc072 Initial revision
glantau
parents:
diff changeset
132
986e461dc072 Initial revision
glantau
parents:
diff changeset
133 //printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
986e461dc072 Initial revision
glantau
parents:
diff changeset
134 /* XXX: optimize */
986e461dc072 Initial revision
glantau
parents:
diff changeset
135 if (n < (32-bit_cnt)) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
136 bit_buf |= value << (32 - n - bit_cnt);
986e461dc072 Initial revision
glantau
parents:
diff changeset
137 bit_cnt+=n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
138 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
139 bit_buf |= value >> (n + bit_cnt - 32);
986e461dc072 Initial revision
glantau
parents:
diff changeset
140 /* handle escape */
986e461dc072 Initial revision
glantau
parents:
diff changeset
141 for(i=0;i<4;i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
142 b = (bit_buf >> 24);
986e461dc072 Initial revision
glantau
parents:
diff changeset
143 *(s->buf_ptr++) = b;
986e461dc072 Initial revision
glantau
parents:
diff changeset
144 if (b == 0xff)
986e461dc072 Initial revision
glantau
parents:
diff changeset
145 *(s->buf_ptr++) = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
146 bit_buf <<= 8;
986e461dc072 Initial revision
glantau
parents:
diff changeset
147 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
148 /* we flush the buffer sooner to handle worst case */
986e461dc072 Initial revision
glantau
parents:
diff changeset
149 if (s->buf_ptr >= (s->buf_end - 8))
986e461dc072 Initial revision
glantau
parents:
diff changeset
150 flush_buffer(s);
986e461dc072 Initial revision
glantau
parents:
diff changeset
151
986e461dc072 Initial revision
glantau
parents:
diff changeset
152 bit_cnt=bit_cnt + n - 32;
986e461dc072 Initial revision
glantau
parents:
diff changeset
153 if (bit_cnt == 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
154 bit_buf = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
155 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
156 bit_buf = value << (32 - bit_cnt);
986e461dc072 Initial revision
glantau
parents:
diff changeset
157 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
158 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
159
986e461dc072 Initial revision
glantau
parents:
diff changeset
160 s->bit_buf = bit_buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
161 s->bit_cnt = bit_cnt;
986e461dc072 Initial revision
glantau
parents:
diff changeset
162 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
163
986e461dc072 Initial revision
glantau
parents:
diff changeset
164 /* pad the end of the output stream with zeros */
986e461dc072 Initial revision
glantau
parents:
diff changeset
165 void jflush_put_bits(PutBitContext *s)
986e461dc072 Initial revision
glantau
parents:
diff changeset
166 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
167 unsigned int b;
986e461dc072 Initial revision
glantau
parents:
diff changeset
168
986e461dc072 Initial revision
glantau
parents:
diff changeset
169 while (s->bit_cnt > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
170 b = s->bit_buf >> 24;
986e461dc072 Initial revision
glantau
parents:
diff changeset
171 *s->buf_ptr++ = b;
986e461dc072 Initial revision
glantau
parents:
diff changeset
172 if (b == 0xff)
986e461dc072 Initial revision
glantau
parents:
diff changeset
173 *s->buf_ptr++ = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
174 s->bit_buf<<=8;
986e461dc072 Initial revision
glantau
parents:
diff changeset
175 s->bit_cnt-=8;
986e461dc072 Initial revision
glantau
parents:
diff changeset
176 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
177 flush_buffer(s);
986e461dc072 Initial revision
glantau
parents:
diff changeset
178 s->bit_cnt=0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
179 s->bit_buf=0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
180 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
181
986e461dc072 Initial revision
glantau
parents:
diff changeset
182 /* bit input functions */
986e461dc072 Initial revision
glantau
parents:
diff changeset
183
986e461dc072 Initial revision
glantau
parents:
diff changeset
184 void init_get_bits(GetBitContext *s,
986e461dc072 Initial revision
glantau
parents:
diff changeset
185 UINT8 *buffer, int buffer_size)
986e461dc072 Initial revision
glantau
parents:
diff changeset
186 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
187 s->buf = buffer;
986e461dc072 Initial revision
glantau
parents:
diff changeset
188 s->buf_ptr = buffer;
986e461dc072 Initial revision
glantau
parents:
diff changeset
189 s->buf_end = buffer + buffer_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
190 s->bit_cnt = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
191 s->bit_buf = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
192 while (s->buf_ptr < s->buf_end &&
986e461dc072 Initial revision
glantau
parents:
diff changeset
193 s->bit_cnt < 32) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
194 s->bit_buf |= (*s->buf_ptr++ << (24 - s->bit_cnt));
986e461dc072 Initial revision
glantau
parents:
diff changeset
195 s->bit_cnt += 8;
986e461dc072 Initial revision
glantau
parents:
diff changeset
196 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
197 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
198
986e461dc072 Initial revision
glantau
parents:
diff changeset
199 /* n must be >= 1 and <= 32 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
200 unsigned int get_bits(GetBitContext *s, int n)
986e461dc072 Initial revision
glantau
parents:
diff changeset
201 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
202 unsigned int val;
986e461dc072 Initial revision
glantau
parents:
diff changeset
203 int bit_cnt;
986e461dc072 Initial revision
glantau
parents:
diff changeset
204 unsigned int bit_buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
205 UINT8 *buf_ptr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
206
986e461dc072 Initial revision
glantau
parents:
diff changeset
207 #ifdef STATS
986e461dc072 Initial revision
glantau
parents:
diff changeset
208 st_bit_counts[st_current_index] += n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
209 #endif
986e461dc072 Initial revision
glantau
parents:
diff changeset
210
986e461dc072 Initial revision
glantau
parents:
diff changeset
211 bit_cnt = s->bit_cnt;
986e461dc072 Initial revision
glantau
parents:
diff changeset
212 bit_buf = s->bit_buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
213
986e461dc072 Initial revision
glantau
parents:
diff changeset
214 bit_cnt -= n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
215 if (bit_cnt >= 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
216 /* most common case here */
986e461dc072 Initial revision
glantau
parents:
diff changeset
217 val = bit_buf >> (32 - n);
986e461dc072 Initial revision
glantau
parents:
diff changeset
218 bit_buf <<= n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
219 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
220 val = bit_buf >> (32 - n);
986e461dc072 Initial revision
glantau
parents:
diff changeset
221 buf_ptr = s->buf_ptr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
222 buf_ptr += 4;
986e461dc072 Initial revision
glantau
parents:
diff changeset
223 /* handle common case: we can read everything */
986e461dc072 Initial revision
glantau
parents:
diff changeset
224 if (buf_ptr <= s->buf_end) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
225 bit_buf = (buf_ptr[-4] << 24) |
986e461dc072 Initial revision
glantau
parents:
diff changeset
226 (buf_ptr[-3] << 16) |
986e461dc072 Initial revision
glantau
parents:
diff changeset
227 (buf_ptr[-2] << 8) |
986e461dc072 Initial revision
glantau
parents:
diff changeset
228 (buf_ptr[-1]);
986e461dc072 Initial revision
glantau
parents:
diff changeset
229 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
230 buf_ptr -= 4;
986e461dc072 Initial revision
glantau
parents:
diff changeset
231 bit_buf = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
232 if (buf_ptr < s->buf_end)
986e461dc072 Initial revision
glantau
parents:
diff changeset
233 bit_buf |= *buf_ptr++ << 24;
986e461dc072 Initial revision
glantau
parents:
diff changeset
234 if (buf_ptr < s->buf_end)
986e461dc072 Initial revision
glantau
parents:
diff changeset
235 bit_buf |= *buf_ptr++ << 16;
986e461dc072 Initial revision
glantau
parents:
diff changeset
236 if (buf_ptr < s->buf_end)
986e461dc072 Initial revision
glantau
parents:
diff changeset
237 bit_buf |= *buf_ptr++ << 8;
986e461dc072 Initial revision
glantau
parents:
diff changeset
238 if (buf_ptr < s->buf_end)
986e461dc072 Initial revision
glantau
parents:
diff changeset
239 bit_buf |= *buf_ptr++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
240 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
241 s->buf_ptr = buf_ptr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
242 val |= bit_buf >> (32 + bit_cnt);
986e461dc072 Initial revision
glantau
parents:
diff changeset
243 bit_buf <<= - bit_cnt;
986e461dc072 Initial revision
glantau
parents:
diff changeset
244 bit_cnt += 32;
986e461dc072 Initial revision
glantau
parents:
diff changeset
245 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
246 s->bit_buf = bit_buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
247 s->bit_cnt = bit_cnt;
986e461dc072 Initial revision
glantau
parents:
diff changeset
248 return val;
986e461dc072 Initial revision
glantau
parents:
diff changeset
249 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
250
986e461dc072 Initial revision
glantau
parents:
diff changeset
251 void align_get_bits(GetBitContext *s)
986e461dc072 Initial revision
glantau
parents:
diff changeset
252 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
253 int n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
254 n = s->bit_cnt & 7;
986e461dc072 Initial revision
glantau
parents:
diff changeset
255 if (n > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
256 get_bits(s, n);
986e461dc072 Initial revision
glantau
parents:
diff changeset
257 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
258 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
259
986e461dc072 Initial revision
glantau
parents:
diff changeset
260 /* VLC decoding */
986e461dc072 Initial revision
glantau
parents:
diff changeset
261
986e461dc072 Initial revision
glantau
parents:
diff changeset
262 //#define DEBUG_VLC
986e461dc072 Initial revision
glantau
parents:
diff changeset
263
986e461dc072 Initial revision
glantau
parents:
diff changeset
264 #define GET_DATA(v, table, i, wrap, size) \
986e461dc072 Initial revision
glantau
parents:
diff changeset
265 {\
986e461dc072 Initial revision
glantau
parents:
diff changeset
266 UINT8 *ptr = (UINT8 *)table + i * wrap;\
986e461dc072 Initial revision
glantau
parents:
diff changeset
267 switch(size) {\
986e461dc072 Initial revision
glantau
parents:
diff changeset
268 case 1:\
986e461dc072 Initial revision
glantau
parents:
diff changeset
269 v = *(UINT8 *)ptr;\
986e461dc072 Initial revision
glantau
parents:
diff changeset
270 break;\
986e461dc072 Initial revision
glantau
parents:
diff changeset
271 case 2:\
986e461dc072 Initial revision
glantau
parents:
diff changeset
272 v = *(UINT16 *)ptr;\
986e461dc072 Initial revision
glantau
parents:
diff changeset
273 break;\
986e461dc072 Initial revision
glantau
parents:
diff changeset
274 default:\
986e461dc072 Initial revision
glantau
parents:
diff changeset
275 v = *(UINT32 *)ptr;\
986e461dc072 Initial revision
glantau
parents:
diff changeset
276 break;\
986e461dc072 Initial revision
glantau
parents:
diff changeset
277 }\
986e461dc072 Initial revision
glantau
parents:
diff changeset
278 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
279
986e461dc072 Initial revision
glantau
parents:
diff changeset
280
986e461dc072 Initial revision
glantau
parents:
diff changeset
281 static int alloc_table(VLC *vlc, int size)
986e461dc072 Initial revision
glantau
parents:
diff changeset
282 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
283 int index;
986e461dc072 Initial revision
glantau
parents:
diff changeset
284 index = vlc->table_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
285 vlc->table_size += size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
286 if (vlc->table_size > vlc->table_allocated) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
287 vlc->table_allocated += (1 << vlc->bits);
986e461dc072 Initial revision
glantau
parents:
diff changeset
288 vlc->table_bits = realloc(vlc->table_bits,
986e461dc072 Initial revision
glantau
parents:
diff changeset
289 sizeof(INT8) * vlc->table_allocated);
986e461dc072 Initial revision
glantau
parents:
diff changeset
290 vlc->table_codes = realloc(vlc->table_codes,
986e461dc072 Initial revision
glantau
parents:
diff changeset
291 sizeof(INT16) * vlc->table_allocated);
986e461dc072 Initial revision
glantau
parents:
diff changeset
292 if (!vlc->table_bits ||
986e461dc072 Initial revision
glantau
parents:
diff changeset
293 !vlc->table_codes)
986e461dc072 Initial revision
glantau
parents:
diff changeset
294 return -1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
295 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
296 return index;
986e461dc072 Initial revision
glantau
parents:
diff changeset
297 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
298
986e461dc072 Initial revision
glantau
parents:
diff changeset
299 static int build_table(VLC *vlc, int table_nb_bits,
986e461dc072 Initial revision
glantau
parents:
diff changeset
300 int nb_codes,
986e461dc072 Initial revision
glantau
parents:
diff changeset
301 const void *bits, int bits_wrap, int bits_size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
302 const void *codes, int codes_wrap, int codes_size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
303 UINT32 code_prefix, int n_prefix)
986e461dc072 Initial revision
glantau
parents:
diff changeset
304 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
305 int i, j, k, n, table_size, table_index, nb, n1, index;
986e461dc072 Initial revision
glantau
parents:
diff changeset
306 UINT32 code;
986e461dc072 Initial revision
glantau
parents:
diff changeset
307 INT8 *table_bits;
986e461dc072 Initial revision
glantau
parents:
diff changeset
308 INT16 *table_codes;
986e461dc072 Initial revision
glantau
parents:
diff changeset
309
986e461dc072 Initial revision
glantau
parents:
diff changeset
310 table_size = 1 << table_nb_bits;
986e461dc072 Initial revision
glantau
parents:
diff changeset
311 table_index = alloc_table(vlc, table_size);
986e461dc072 Initial revision
glantau
parents:
diff changeset
312 #ifdef DEBUG_VLC
986e461dc072 Initial revision
glantau
parents:
diff changeset
313 printf("new table index=%d size=%d code_prefix=%x n=%d\n",
986e461dc072 Initial revision
glantau
parents:
diff changeset
314 table_index, table_size, code_prefix, n_prefix);
986e461dc072 Initial revision
glantau
parents:
diff changeset
315 #endif
986e461dc072 Initial revision
glantau
parents:
diff changeset
316 if (table_index < 0)
986e461dc072 Initial revision
glantau
parents:
diff changeset
317 return -1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
318 table_bits = &vlc->table_bits[table_index];
986e461dc072 Initial revision
glantau
parents:
diff changeset
319 table_codes = &vlc->table_codes[table_index];
986e461dc072 Initial revision
glantau
parents:
diff changeset
320
986e461dc072 Initial revision
glantau
parents:
diff changeset
321 for(i=0;i<table_size;i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
322 table_bits[i] = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
323 table_codes[i] = -1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
324 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
325
986e461dc072 Initial revision
glantau
parents:
diff changeset
326 /* first pass: map codes and compute auxillary table sizes */
986e461dc072 Initial revision
glantau
parents:
diff changeset
327 for(i=0;i<nb_codes;i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
328 GET_DATA(n, bits, i, bits_wrap, bits_size);
986e461dc072 Initial revision
glantau
parents:
diff changeset
329 GET_DATA(code, codes, i, codes_wrap, codes_size);
986e461dc072 Initial revision
glantau
parents:
diff changeset
330 /* we accept tables with holes */
986e461dc072 Initial revision
glantau
parents:
diff changeset
331 if (n <= 0)
986e461dc072 Initial revision
glantau
parents:
diff changeset
332 continue;
986e461dc072 Initial revision
glantau
parents:
diff changeset
333 #if defined(DEBUG_VLC) && 0
986e461dc072 Initial revision
glantau
parents:
diff changeset
334 printf("i=%d n=%d code=0x%x\n", i, n, code);
986e461dc072 Initial revision
glantau
parents:
diff changeset
335 #endif
986e461dc072 Initial revision
glantau
parents:
diff changeset
336 /* if code matches the prefix, it is in the table */
986e461dc072 Initial revision
glantau
parents:
diff changeset
337 n -= n_prefix;
986e461dc072 Initial revision
glantau
parents:
diff changeset
338 if (n > 0 && (code >> n) == code_prefix) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
339 if (n <= table_nb_bits) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
340 /* no need to add another table */
986e461dc072 Initial revision
glantau
parents:
diff changeset
341 j = (code << (table_nb_bits - n)) & (table_size - 1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
342 nb = 1 << (table_nb_bits - n);
986e461dc072 Initial revision
glantau
parents:
diff changeset
343 for(k=0;k<nb;k++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
344 #ifdef DEBUG_VLC
986e461dc072 Initial revision
glantau
parents:
diff changeset
345 printf("%4x: code=%d n=%d\n",
986e461dc072 Initial revision
glantau
parents:
diff changeset
346 j, i, n);
986e461dc072 Initial revision
glantau
parents:
diff changeset
347 #endif
986e461dc072 Initial revision
glantau
parents:
diff changeset
348 if (table_bits[j] != 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
349 fprintf(stderr, "incorrect codes\n");
986e461dc072 Initial revision
glantau
parents:
diff changeset
350 exit(1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
351 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
352 table_bits[j] = n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
353 table_codes[j] = i;
986e461dc072 Initial revision
glantau
parents:
diff changeset
354 j++;
986e461dc072 Initial revision
glantau
parents:
diff changeset
355 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
356 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
357 n -= table_nb_bits;
986e461dc072 Initial revision
glantau
parents:
diff changeset
358 j = (code >> n) & ((1 << table_nb_bits) - 1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
359 #ifdef DEBUG_VLC
986e461dc072 Initial revision
glantau
parents:
diff changeset
360 printf("%4x: n=%d (subtable)\n",
986e461dc072 Initial revision
glantau
parents:
diff changeset
361 j, n);
986e461dc072 Initial revision
glantau
parents:
diff changeset
362 #endif
986e461dc072 Initial revision
glantau
parents:
diff changeset
363 /* compute table size */
986e461dc072 Initial revision
glantau
parents:
diff changeset
364 n1 = -table_bits[j];
986e461dc072 Initial revision
glantau
parents:
diff changeset
365 if (n > n1)
986e461dc072 Initial revision
glantau
parents:
diff changeset
366 n1 = n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
367 table_bits[j] = -n1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
368 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
369 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
370 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
371
986e461dc072 Initial revision
glantau
parents:
diff changeset
372 /* second pass : fill auxillary tables recursively */
986e461dc072 Initial revision
glantau
parents:
diff changeset
373 for(i=0;i<table_size;i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
374 n = table_bits[i];
986e461dc072 Initial revision
glantau
parents:
diff changeset
375 if (n < 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
376 n = -n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
377 if (n > table_nb_bits) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
378 n = table_nb_bits;
986e461dc072 Initial revision
glantau
parents:
diff changeset
379 table_bits[i] = -n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
380 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
381 index = build_table(vlc, n, nb_codes,
986e461dc072 Initial revision
glantau
parents:
diff changeset
382 bits, bits_wrap, bits_size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
383 codes, codes_wrap, codes_size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
384 (code_prefix << table_nb_bits) | i,
986e461dc072 Initial revision
glantau
parents:
diff changeset
385 n_prefix + table_nb_bits);
986e461dc072 Initial revision
glantau
parents:
diff changeset
386 if (index < 0)
986e461dc072 Initial revision
glantau
parents:
diff changeset
387 return -1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
388 /* note: realloc has been done, so reload tables */
986e461dc072 Initial revision
glantau
parents:
diff changeset
389 table_bits = &vlc->table_bits[table_index];
986e461dc072 Initial revision
glantau
parents:
diff changeset
390 table_codes = &vlc->table_codes[table_index];
986e461dc072 Initial revision
glantau
parents:
diff changeset
391 table_codes[i] = index;
986e461dc072 Initial revision
glantau
parents:
diff changeset
392 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
393 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
394 return table_index;
986e461dc072 Initial revision
glantau
parents:
diff changeset
395 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
396
986e461dc072 Initial revision
glantau
parents:
diff changeset
397
986e461dc072 Initial revision
glantau
parents:
diff changeset
398 /* wrap and size allow to handle most types of storage. */
986e461dc072 Initial revision
glantau
parents:
diff changeset
399 int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
986e461dc072 Initial revision
glantau
parents:
diff changeset
400 const void *bits, int bits_wrap, int bits_size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
401 const void *codes, int codes_wrap, int codes_size)
986e461dc072 Initial revision
glantau
parents:
diff changeset
402 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
403 vlc->bits = nb_bits;
986e461dc072 Initial revision
glantau
parents:
diff changeset
404 vlc->table_bits = NULL;
986e461dc072 Initial revision
glantau
parents:
diff changeset
405 vlc->table_codes = NULL;
986e461dc072 Initial revision
glantau
parents:
diff changeset
406 vlc->table_allocated = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
407 vlc->table_size = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
408 #ifdef DEBUG_VLC
986e461dc072 Initial revision
glantau
parents:
diff changeset
409 printf("build table nb_codes=%d\n", nb_codes);
986e461dc072 Initial revision
glantau
parents:
diff changeset
410 #endif
986e461dc072 Initial revision
glantau
parents:
diff changeset
411
986e461dc072 Initial revision
glantau
parents:
diff changeset
412 if (build_table(vlc, nb_bits, nb_codes,
986e461dc072 Initial revision
glantau
parents:
diff changeset
413 bits, bits_wrap, bits_size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
414 codes, codes_wrap, codes_size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
415 0, 0) < 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
416 if (vlc->table_bits)
986e461dc072 Initial revision
glantau
parents:
diff changeset
417 free(vlc->table_bits);
986e461dc072 Initial revision
glantau
parents:
diff changeset
418 if (vlc->table_codes)
986e461dc072 Initial revision
glantau
parents:
diff changeset
419 free(vlc->table_codes);
986e461dc072 Initial revision
glantau
parents:
diff changeset
420 return -1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
421 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
422 return 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
423 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
424
986e461dc072 Initial revision
glantau
parents:
diff changeset
425
986e461dc072 Initial revision
glantau
parents:
diff changeset
426 void free_vlc(VLC *vlc)
986e461dc072 Initial revision
glantau
parents:
diff changeset
427 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
428 free(vlc->table_bits);
986e461dc072 Initial revision
glantau
parents:
diff changeset
429 free(vlc->table_codes);
986e461dc072 Initial revision
glantau
parents:
diff changeset
430 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
431
986e461dc072 Initial revision
glantau
parents:
diff changeset
432 int get_vlc(GetBitContext *s, VLC *vlc)
986e461dc072 Initial revision
glantau
parents:
diff changeset
433 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
434 int bit_cnt, code, n, nb_bits, index;
986e461dc072 Initial revision
glantau
parents:
diff changeset
435 UINT32 bit_buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
436 INT16 *table_codes;
986e461dc072 Initial revision
glantau
parents:
diff changeset
437 INT8 *table_bits;
986e461dc072 Initial revision
glantau
parents:
diff changeset
438 UINT8 *buf_ptr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
439
986e461dc072 Initial revision
glantau
parents:
diff changeset
440 SAVE_BITS(s);
986e461dc072 Initial revision
glantau
parents:
diff changeset
441 nb_bits = vlc->bits;
986e461dc072 Initial revision
glantau
parents:
diff changeset
442 table_codes = vlc->table_codes;
986e461dc072 Initial revision
glantau
parents:
diff changeset
443 table_bits = vlc->table_bits;
986e461dc072 Initial revision
glantau
parents:
diff changeset
444 for(;;) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
445 SHOW_BITS(s, index, nb_bits);
986e461dc072 Initial revision
glantau
parents:
diff changeset
446 code = table_codes[index];
986e461dc072 Initial revision
glantau
parents:
diff changeset
447 n = table_bits[index];
986e461dc072 Initial revision
glantau
parents:
diff changeset
448 if (n > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
449 /* most common case */
986e461dc072 Initial revision
glantau
parents:
diff changeset
450 FLUSH_BITS(n);
986e461dc072 Initial revision
glantau
parents:
diff changeset
451 #ifdef STATS
986e461dc072 Initial revision
glantau
parents:
diff changeset
452 st_bit_counts[st_current_index] += n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
453 #endif
986e461dc072 Initial revision
glantau
parents:
diff changeset
454 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
455 } else if (n == 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
456 return -1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
457 } else {
986e461dc072 Initial revision
glantau
parents:
diff changeset
458 FLUSH_BITS(nb_bits);
986e461dc072 Initial revision
glantau
parents:
diff changeset
459 #ifdef STATS
986e461dc072 Initial revision
glantau
parents:
diff changeset
460 st_bit_counts[st_current_index] += nb_bits;
986e461dc072 Initial revision
glantau
parents:
diff changeset
461 #endif
986e461dc072 Initial revision
glantau
parents:
diff changeset
462 nb_bits = -n;
986e461dc072 Initial revision
glantau
parents:
diff changeset
463 table_codes = vlc->table_codes + code;
986e461dc072 Initial revision
glantau
parents:
diff changeset
464 table_bits = vlc->table_bits + code;
986e461dc072 Initial revision
glantau
parents:
diff changeset
465 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
466 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
467 RESTORE_BITS(s);
986e461dc072 Initial revision
glantau
parents:
diff changeset
468 return code;
986e461dc072 Initial revision
glantau
parents:
diff changeset
469 }