CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/ext/at3_standalone/get_bits.cpp
Views: 1401
1
/*
2
* Common bit i/o utils
3
* Copyright (c) 2000, 2001 Fabrice Bellard
4
* Copyright (c) 2002-2004 Michael Niedermayer <[email protected]>
5
* Copyright (c) 2010 Loren Merritt
6
*
7
* alternative bitstream reader & writer by Michael Niedermayer <[email protected]>
8
*
9
* This file is part of FFmpeg.
10
*
11
* FFmpeg is free software; you can redistribute it and/or
12
* modify it under the terms of the GNU Lesser General Public
13
* License as published by the Free Software Foundation; either
14
* version 2.1 of the License, or (at your option) any later version.
15
*
16
* FFmpeg is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
* Lesser General Public License for more details.
20
*
21
* You should have received a copy of the GNU Lesser General Public
22
* License along with FFmpeg; if not, write to the Free Software
23
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
*/
25
26
/**
27
* @file
28
* bitstream api.
29
*/
30
31
#include <stdlib.h>
32
#include <string.h>
33
34
#include "compat.h"
35
#include "mem.h"
36
#include "get_bits.h"
37
38
static const uint8_t ff_reverse[256] = {
39
0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
40
0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
41
0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
42
0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
43
0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
44
0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
45
0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
46
0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
47
0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
48
0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
49
0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
50
0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
51
0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
52
0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
53
0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
54
0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF,
55
};
56
57
/* VLC decoding */
58
59
#define GET_DATA(v, table, i, wrap, size) \
60
{ \
61
const uint8_t *ptr = (const uint8_t *)table + i * wrap; \
62
switch(size) { \
63
case 1: \
64
v = *(const uint8_t *)ptr; \
65
break; \
66
case 2: \
67
v = *(const uint16_t *)ptr; \
68
break; \
69
default: \
70
v = *(const uint32_t *)ptr; \
71
break; \
72
} \
73
}
74
75
static int alloc_table(VLC *vlc, int size, int use_static)
76
{
77
int index = vlc->table_size;
78
79
vlc->table_size += size;
80
if (vlc->table_size > vlc->table_allocated) {
81
if (use_static)
82
abort(); // cannot do anything, init_vlc() is used with too little memory
83
vlc->table_allocated += (1 << vlc->bits);
84
vlc->table = (VLC_TYPE(*)[2])av_realloc_f(vlc->table, vlc->table_allocated, sizeof(VLC_TYPE) * 2);
85
if (!vlc->table) {
86
vlc->table_allocated = 0;
87
vlc->table_size = 0;
88
return AVERROR(ENOMEM);
89
}
90
memset(vlc->table + vlc->table_allocated - (unsigned int)(1UL << vlc->bits), 0, sizeof(VLC_TYPE) * 2 << vlc->bits);
91
}
92
return index;
93
}
94
95
static inline uint32_t bitswap_32(uint32_t x)
96
{
97
return (uint32_t)ff_reverse[ x & 0xFF] << 24 |
98
(uint32_t)ff_reverse[(x >> 8) & 0xFF] << 16 |
99
(uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8 |
100
(uint32_t)ff_reverse[ x >> 24];
101
}
102
103
typedef struct VLCcode {
104
/** codeword, with the first bit-to-be-read in the msb
105
* (even if intended for a little-endian bitstream reader) */
106
uint32_t code;
107
uint16_t symbol;
108
uint8_t bits;
109
} VLCcode;
110
111
static int compare_vlcspec(const void *a, const void *b)
112
{
113
const VLCcode *sa = (VLCcode *)a;
114
const VLCcode *sb = (VLCcode *)b;
115
return (sa->code >> 1) - (sb->code >> 1);
116
}
117
/**
118
* Build VLC decoding tables suitable for use with get_vlc().
119
*
120
* @param vlc the context to be initted
121
*
122
* @param table_nb_bits max length of vlc codes to store directly in this table
123
* (Longer codes are delegated to subtables.)
124
*
125
* @param nb_codes number of elements in codes[]
126
*
127
* @param codes descriptions of the vlc codes
128
* These must be ordered such that codes going into the same subtable are contiguous.
129
* Sorting by VLCcode.code is sufficient, though not necessary.
130
*/
131
static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
132
VLCcode *codes, int flags)
133
{
134
int table_size, table_index, index, code_prefix, symbol, subtable_bits;
135
int i, j, k, n, nb, inc;
136
uint32_t code;
137
volatile VLC_TYPE (* volatile table)[2]; // the double volatile is needed to prevent a internal compiler error in gcc 4.2
138
139
table_size = 1 << table_nb_bits;
140
if (table_nb_bits > 30)
141
return -1;
142
table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);
143
if (table_index < 0)
144
return table_index;
145
table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index];
146
147
/* first pass: map codes and compute auxiliary table sizes */
148
for (i = 0; i < nb_codes; i++) {
149
n = codes[i].bits;
150
code = codes[i].code;
151
symbol = codes[i].symbol;
152
if (n <= table_nb_bits) {
153
/* no need to add another table */
154
j = code >> (32 - table_nb_bits);
155
nb = 1 << (table_nb_bits - n);
156
inc = 1;
157
if (flags & INIT_VLC_LE) {
158
j = bitswap_32(code);
159
inc = 1 << n;
160
}
161
for (k = 0; k < nb; k++) {
162
int bits = table[j][1];
163
if (bits != 0 && bits != n) {
164
av_log(AV_LOG_ERROR, "incorrect codes");
165
return AVERROR_INVALIDDATA;
166
}
167
table[j][1] = n; //bits
168
table[j][0] = symbol;
169
j += inc;
170
}
171
} else {
172
/* fill auxiliary table recursively */
173
n -= table_nb_bits;
174
code_prefix = code >> (32 - table_nb_bits);
175
subtable_bits = n;
176
codes[i].bits = n;
177
codes[i].code = code << table_nb_bits;
178
for (k = i+1; k < nb_codes; k++) {
179
n = codes[k].bits - table_nb_bits;
180
if (n <= 0)
181
break;
182
code = codes[k].code;
183
if (code >> (32 - table_nb_bits) != code_prefix)
184
break;
185
codes[k].bits = n;
186
codes[k].code = code << table_nb_bits;
187
subtable_bits = FFMAX(subtable_bits, n);
188
}
189
subtable_bits = FFMIN(subtable_bits, table_nb_bits);
190
j = (flags & INIT_VLC_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix;
191
table[j][1] = -subtable_bits;
192
index = build_table(vlc, subtable_bits, k-i, codes+i, flags);
193
if (index < 0)
194
return index;
195
/* note: realloc has been done, so reload tables */
196
table = (volatile VLC_TYPE (*)[2])&vlc->table[table_index];
197
table[j][0] = index; //code
198
i = k-1;
199
}
200
}
201
202
for (i = 0; i < table_size; i++) {
203
if (table[i][1] == 0) //bits
204
table[i][0] = -1; //codes
205
}
206
207
return table_index;
208
}
209
210
211
/* Build VLC decoding tables suitable for use with get_vlc().
212
213
'nb_bits' set the decoding table size (2^nb_bits) entries. The
214
bigger it is, the faster is the decoding. But it should not be too
215
big to save memory and L1 cache. '9' is a good compromise.
216
217
'nb_codes' : number of vlcs codes
218
219
'bits' : table which gives the size (in bits) of each vlc code.
220
221
'codes' : table which gives the bit pattern of of each vlc code.
222
223
'symbols' : table which gives the values to be returned from get_vlc().
224
225
'xxx_wrap' : give the number of bytes between each entry of the
226
'bits' or 'codes' tables.
227
228
'xxx_size' : gives the number of bytes of each entry of the 'bits'
229
or 'codes' tables.
230
231
'wrap' and 'size' make it possible to use any memory configuration and types
232
(byte/word/long) to store the 'bits', 'codes', and 'symbols' tables.
233
234
'use_static' should be set to 1 for tables, which should be freed
235
with av_free_static(), 0 if ff_free_vlc() will be used.
236
*/
237
int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes,
238
const void *bits, int bits_wrap, int bits_size,
239
const void *codes, int codes_wrap, int codes_size,
240
const void *symbols, int symbols_wrap, int symbols_size,
241
int flags)
242
{
243
VLCcode *buf;
244
int i, j, ret;
245
VLCcode localbuf[1500]; // the maximum currently needed is 1296 by rv34
246
VLC localvlc, *vlc;
247
248
vlc = vlc_arg;
249
vlc->bits = nb_bits;
250
if (flags & INIT_VLC_USE_NEW_STATIC) {
251
av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf));
252
buf = localbuf;
253
localvlc = *vlc_arg;
254
vlc = &localvlc;
255
vlc->table_size = 0;
256
} else {
257
vlc->table = NULL;
258
vlc->table_allocated = 0;
259
vlc->table_size = 0;
260
261
buf = (VLCcode *)av_malloc_array((nb_codes + 1), sizeof(VLCcode));
262
if (!buf)
263
return AVERROR(ENOMEM);
264
}
265
266
267
av_assert0(symbols_size <= 2 || !symbols);
268
j = 0;
269
#define COPY(condition)\
270
for (i = 0; i < nb_codes; i++) { \
271
GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size); \
272
if (!(condition)) \
273
continue; \
274
if (buf[j].bits > 3*nb_bits || buf[j].bits>32) { \
275
av_log(AV_LOG_ERROR, "Too long VLC (%d) in init_vlc", buf[j].bits);\
276
if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
277
av_free(buf); \
278
return -1; \
279
} \
280
GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size); \
281
if (buf[j].code >= (1LL<<buf[j].bits)) { \
282
av_log(AV_LOG_ERROR, "Invalid code in init_vlc"); \
283
if (!(flags & INIT_VLC_USE_NEW_STATIC)) \
284
av_free(buf); \
285
return -1; \
286
} \
287
if (flags & INIT_VLC_LE) \
288
buf[j].code = bitswap_32(buf[j].code); \
289
else \
290
buf[j].code <<= 32 - buf[j].bits; \
291
if (symbols) \
292
GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size) \
293
else \
294
buf[j].symbol = i; \
295
j++; \
296
}
297
COPY(buf[j].bits > nb_bits);
298
// qsort is the slowest part of init_vlc, and could probably be improved or avoided
299
qsort(buf, j, sizeof(struct VLCcode), compare_vlcspec);
300
COPY(buf[j].bits && buf[j].bits <= nb_bits);
301
nb_codes = j;
302
303
ret = build_table(vlc, nb_bits, nb_codes, buf, flags);
304
305
if (flags & INIT_VLC_USE_NEW_STATIC) {
306
if(vlc->table_size != vlc->table_allocated)
307
av_log(AV_LOG_ERROR, "needed %d had %d", vlc->table_size, vlc->table_allocated);
308
309
av_assert0(ret >= 0);
310
*vlc_arg = *vlc;
311
} else {
312
av_free(buf);
313
if (ret < 0) {
314
av_freep(&vlc->table);
315
return ret;
316
}
317
}
318
return 0;
319
}
320
321
void ff_free_vlc(VLC *vlc)
322
{
323
av_freep(&vlc->table);
324
}
325
326