summaryrefslogtreecommitdiff
path: root/bitstream.c
blob: 7766394e111609b4c26c33f721d2a8b73ba255e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
 * Common bit I/O utils.
 *
 * Extracted 2009 from mplayer 2009-02-10 libavcodec/bitstream.c.
 *
 * Copyright (c) 2000, 2001 Fabrice Bellard
 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
 * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at>
 * Copyright (C) 2009 Andre Noll <maan@tuebingen.mpg.de>
 *
 * Licensed under the GNU Lesser General Public License. see file COPYING.LIB.
 */

/** \file bitstream.c Bitstream API for the wma decoder. */

#include "para.h"
#include "error.h"
#include "string.h"
#include "wma.h"
#include "portable_io.h"
#include "bitstream.h"

static inline uint32_t get_data(const void *table, int i, int size)
{
	const uint8_t *ptr = (const uint8_t *)table + i * size;
	uint32_t v;

	switch (size) {
	case 1:
		v = *(const uint8_t *)ptr;
		break;
	case 2:
		v = *(const uint16_t *)ptr;
		break;
	default:
		v = *(const uint32_t *)ptr;
		break;
	}
	return v;
}

static void alloc_table(struct vlc *vlc, int size)
{
	vlc->table_size += size;
	if (vlc->table_size > vlc->table_allocated) {
		vlc->table_allocated += (1 << vlc->bits);
		vlc->table = arr_realloc(vlc->table, vlc->table_allocated,
			sizeof(int16_t) * 2);
	}
}

static int build_table(struct vlc *vlc, int table_nb_bits, int nb_codes,
		const void *bits, const void *codes, int codes_size,
		uint32_t code_prefix, int n_prefix)
{
	int i, j, k, n, table_size, table_index, nb, n1, idx;
	uint32_t code;
	int16_t (*table)[2];

	table_size = 1 << table_nb_bits;
	table_index = vlc->table_size;
	alloc_table(vlc, table_size);
	table = &vlc->table[table_index];

	for (i = 0; i < table_size; i++) {
		table[i][1] = 0; /* bits */
		table[i][0] = -1; /* codes */
	}

	/* map codes and compute auxiliary table sizes */
	for (i = 0; i < nb_codes; i++) {
		n = get_data(bits, i, 1);
		/* we accept tables with holes */
		n -= n_prefix;
		if (n <= 0)
			continue;
		code = get_data(codes, i, codes_size);
		/* if code matches the prefix, it is in the table */
		if ((code >> n) != code_prefix)
			continue;
		if (n <= table_nb_bits) {
			/* no need to add another table */
			j = (code << (table_nb_bits - n)) & (table_size - 1);
			nb = 1 << (table_nb_bits - n);
			for (k = 0; k < nb; k++) {
				assert(table[j][1] == 0); /* incorrect code */
				table[j][1] = n; /* bits */
				table[j][0] = i;
				j++;
			}
		} else {
			n -= table_nb_bits;
			j = (code >> n) & ((1 << table_nb_bits) - 1);
			/* compute table size */
			n1 = -table[j][1]; /* bits */
			if (n > n1)
				n1 = n;
			table[j][1] = -n1; /* bits */
		}
	}

	/* fill auxiliary tables recursively */
	for (i = 0; i < table_size; i++) {
		n = table[i][1]; /* bits */
		if (n < 0) {
			n = -n;
			if (n > table_nb_bits) {
				n = table_nb_bits;
				table[i][1] = -n; /* bits */
			}
			idx = build_table(vlc, n, nb_codes, bits, codes,
				codes_size, (code_prefix << table_nb_bits) | i,
				n_prefix + table_nb_bits);
			/* vlc->table might have changed */
			table = &vlc->table[table_index];
			table[i][0] = idx; /* code */
		}
	}
	return table_index;
}

/**
 * Build VLC decoding tables suitable for use with get_vlc().
 *
 * \param vlc The structure to be initialized.
 * \param nb_bits Set the decoding table size (2^nb_bits) entries.
 * \param nb_codes Number of vlc codes.
 * \param bits Table which gives the size (in bits) of each vlc code.
 * \param codes Table which gives the bit pattern of of each vlc code.
 * \param codes_size The number of bytes of each entry of the \a codes tables.
 *
 * The bigger \a nb_bits is, the faster is the decoding. But it should not be
 * too big to save memory and L1 cache. '9' is a good compromise.
 *
 * The wrap and size parameters allow to use any memory configuration and
 * types (byte/word/long) to store the bits and codes tables.
 */
void init_vlc(struct vlc *vlc, int nb_bits, int nb_codes, const void *bits,
		const void *codes, int codes_size)
{
	PARA_INFO_LOG("nb_codes: %d\n", nb_codes);
	vlc->bits = nb_bits;
	vlc->table = NULL;
	vlc->table_allocated = 0;
	vlc->table_size = 0;
	build_table(vlc, nb_bits, nb_codes, bits, codes, codes_size, 0, 0);
}

/**
 * Deallocate all resources of a VLC table.
 *
 * \param vlc Pointer to an initialized vlc structure.
 *
 * The table given by \a vlc must have been initialized earlier via \ref
 * init_vlc().
 */
void free_vlc(struct vlc *vlc)
{
	freep(&vlc->table);
}

/**
 * Parse a vlc code.
 *
 * \param gbc The getbit context structure.
 * \param vlc The vlc tables to use.
 *
 * \return The vlc code.
 */
int get_vlc(struct getbit_context *gbc, const struct vlc *vlc)
{
	int n, idx, nb_bits, code;

	idx = show_bits(gbc, vlc->bits);
	code = vlc->table[idx][0];
	n = vlc->table[idx][1];
	if (n < 0) {
		skip_bits(gbc, vlc->bits);
		nb_bits = -n;
		idx = show_bits(gbc, nb_bits) + code;
		code = vlc->table[idx][0];
		n = vlc->table[idx][1];
		if (n < 0) {
			skip_bits(gbc, nb_bits);
			nb_bits = -n;
			idx = show_bits(gbc, nb_bits) + code;
			code = vlc->table[idx][0];
			n = vlc->table[idx][1];
		}
	}
	skip_bits(gbc, n);
	return code >= 0? code : -E_VLC;
}