diff options
Diffstat (limited to 'apps/codecs/libwma/common.c')
-rw-r--r-- | apps/codecs/libwma/common.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/apps/codecs/libwma/common.c b/apps/codecs/libwma/common.c index 619ce47197..b4577a4c74 100644 --- a/apps/codecs/libwma/common.c +++ b/apps/codecs/libwma/common.c | |||
@@ -105,3 +105,164 @@ int check_marker(GetBitContext *s, const char *msg) | |||
105 | return bit; | 105 | return bit; |
106 | } | 106 | } |
107 | 107 | ||
108 | /* VLC decoding */ | ||
109 | |||
110 | //#define DEBUG_VLC | ||
111 | |||
112 | #define GET_DATA(v, table, i, wrap, size) \ | ||
113 | {\ | ||
114 | const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ | ||
115 | switch(size) {\ | ||
116 | case 1:\ | ||
117 | v = *(const uint8_t *)ptr;\ | ||
118 | break;\ | ||
119 | case 2:\ | ||
120 | v = *(const uint16_t *)ptr;\ | ||
121 | break;\ | ||
122 | default:\ | ||
123 | v = *(const uint32_t *)ptr;\ | ||
124 | break;\ | ||
125 | }\ | ||
126 | } | ||
127 | |||
128 | static int alloc_table(VLC *vlc, int size) | ||
129 | { | ||
130 | int index; | ||
131 | index = vlc->table_size; | ||
132 | vlc->table_size += size; | ||
133 | if (vlc->table_size > vlc->table_allocated) { | ||
134 | vlc->table_allocated += (1 << vlc->bits); | ||
135 | if (!vlc->table) | ||
136 | return -1; | ||
137 | } | ||
138 | return index; | ||
139 | } | ||
140 | |||
141 | static int build_table(VLC *vlc, int table_nb_bits, | ||
142 | int nb_codes, | ||
143 | const void *bits, int bits_wrap, int bits_size, | ||
144 | const void *codes, int codes_wrap, int codes_size, | ||
145 | uint32_t code_prefix, int n_prefix) | ||
146 | { | ||
147 | int i, j, k, n, table_size, table_index, nb, n1, index; | ||
148 | uint32_t code; | ||
149 | VLC_TYPE (*table)[2]; | ||
150 | |||
151 | table_size = 1 << table_nb_bits; | ||
152 | table_index = alloc_table(vlc, table_size); | ||
153 | if (table_index < 0) | ||
154 | return -1; | ||
155 | table = &vlc->table[table_index]; | ||
156 | |||
157 | for(i=0;i<table_size;i++) | ||
158 | { | ||
159 | table[i][1] = 0; //bits | ||
160 | table[i][0] = -1; //codes | ||
161 | } | ||
162 | |||
163 | /* first pass: map codes and compute auxillary table sizes */ | ||
164 | for(i=0;i<nb_codes;i++) | ||
165 | { | ||
166 | GET_DATA(n, bits, i, bits_wrap, bits_size); | ||
167 | GET_DATA(code, codes, i, codes_wrap, codes_size); | ||
168 | /* we accept tables with holes */ | ||
169 | if (n <= 0) | ||
170 | continue; | ||
171 | /* if code matches the prefix, it is in the table */ | ||
172 | n -= n_prefix; | ||
173 | if (n > 0 && (code >> n) == code_prefix) | ||
174 | { | ||
175 | if (n <= table_nb_bits) | ||
176 | { | ||
177 | /* no need to add another table */ | ||
178 | j = (code << (table_nb_bits - n)) & (table_size - 1); | ||
179 | nb = 1 << (table_nb_bits - n); | ||
180 | for(k=0;k<nb;k++) | ||
181 | { | ||
182 | if (table[j][1] /*bits*/ != 0) | ||
183 | { | ||
184 | // PJJ exit(-1); | ||
185 | } | ||
186 | table[j][1] = n; //bits | ||
187 | table[j][0] = i; //code | ||
188 | j++; | ||
189 | } | ||
190 | } | ||
191 | else | ||
192 | { | ||
193 | n -= table_nb_bits; | ||
194 | j = (code >> n) & ((1 << table_nb_bits) - 1); | ||
195 | /* compute table size */ | ||
196 | n1 = -table[j][1]; //bits | ||
197 | if (n > n1) | ||
198 | n1 = n; | ||
199 | table[j][1] = -n1; //bits | ||
200 | } | ||
201 | } | ||
202 | } | ||
203 | |||
204 | /* second pass : fill auxillary tables recursively */ | ||
205 | for(i=0;i<table_size;i++) | ||
206 | { | ||
207 | n = table[i][1]; //bits | ||
208 | if (n < 0) | ||
209 | { | ||
210 | n = -n; | ||
211 | if (n > table_nb_bits) | ||
212 | { | ||
213 | n = table_nb_bits; | ||
214 | table[i][1] = -n; //bits | ||
215 | } | ||
216 | index = build_table(vlc, n, nb_codes, | ||
217 | bits, bits_wrap, bits_size, | ||
218 | codes, codes_wrap, codes_size, | ||
219 | (code_prefix << table_nb_bits) | i, | ||
220 | n_prefix + table_nb_bits); | ||
221 | if (index < 0) | ||
222 | return -1; | ||
223 | /* note: realloc has been done, so reload tables */ | ||
224 | table = &vlc->table[table_index]; | ||
225 | table[i][0] = index; //code | ||
226 | } | ||
227 | } | ||
228 | return table_index; | ||
229 | } | ||
230 | |||
231 | /* Build VLC decoding tables suitable for use with get_vlc(). | ||
232 | |||
233 | 'nb_bits' set thee decoding table size (2^nb_bits) entries. The | ||
234 | bigger it is, the faster is the decoding. But it should not be too | ||
235 | big to save memory and L1 cache. '9' is a good compromise. | ||
236 | |||
237 | 'nb_codes' : number of vlcs codes | ||
238 | |||
239 | 'bits' : table which gives the size (in bits) of each vlc code. | ||
240 | |||
241 | 'codes' : table which gives the bit pattern of of each vlc code. | ||
242 | |||
243 | 'xxx_wrap' : give the number of bytes between each entry of the | ||
244 | 'bits' or 'codes' tables. | ||
245 | |||
246 | 'xxx_size' : gives the number of bytes of each entry of the 'bits' | ||
247 | or 'codes' tables. | ||
248 | |||
249 | 'wrap' and 'size' allows to use any memory configuration and types | ||
250 | (byte/word/long) to store the 'bits' and 'codes' tables. | ||
251 | */ | ||
252 | int init_vlc(VLC *vlc, int nb_bits, int nb_codes, | ||
253 | const void *bits, int bits_wrap, int bits_size, | ||
254 | const void *codes, int codes_wrap, int codes_size) | ||
255 | { | ||
256 | vlc->bits = nb_bits; | ||
257 | vlc->table_size = 0; | ||
258 | |||
259 | if (build_table(vlc, nb_bits, nb_codes, | ||
260 | bits, bits_wrap, bits_size, | ||
261 | codes, codes_wrap, codes_size, | ||
262 | 0, 0) < 0) | ||
263 | { | ||
264 | |||
265 | return -1; | ||
266 | } | ||
267 | return 0; | ||
268 | } | ||