Line | Count | Source (jump to first uncovered line) |
1 | | /******************************************************************** |
2 | | * * |
3 | | * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * |
4 | | * * |
5 | | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
6 | | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
7 | | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
8 | | * * |
9 | | * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * |
10 | | * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * |
11 | | * * |
12 | | ******************************************************************** |
13 | | |
14 | | function: basic codebook pack/unpack/code/decode operations |
15 | | |
16 | | ********************************************************************/ |
17 | | |
18 | | #include <stdlib.h> |
19 | | #include <string.h> |
20 | | #include <math.h> |
21 | | #include <ogg/ogg.h> |
22 | | #include "ivorbiscodec.h" |
23 | | #include "codebook.h" |
24 | | #include "misc.h" |
25 | | |
26 | | /* unpacks a codebook from the packet buffer into the codebook struct, |
27 | | readies the codebook auxiliary structures for decode *************/ |
28 | 16.6k | static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){ |
29 | 16.6k | long i,j; |
30 | 16.6k | static_codebook *s=_ogg_calloc(1,sizeof(*s)); |
31 | | |
32 | | /* make sure alignment is correct */ |
33 | 16.6k | if(oggpack_read(opb,24)!=0x564342)goto _eofout; |
34 | | |
35 | | /* first the basic parameters */ |
36 | 16.5k | s->dim=oggpack_read(opb,16); |
37 | 16.5k | s->entries=oggpack_read(opb,24); |
38 | 16.5k | if(s->entries==-1)goto _eofout; |
39 | | |
40 | 16.5k | if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout; |
41 | | |
42 | | /* codeword ordering.... length ordered or unordered? */ |
43 | 16.5k | switch((int)oggpack_read(opb,1)){ |
44 | 13.9k | case 0:{ |
45 | 13.9k | long unused; |
46 | | /* allocated but unused entries? */ |
47 | 13.9k | unused=oggpack_read(opb,1); |
48 | 13.9k | if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb)) |
49 | 50 | goto _eofout; |
50 | | /* unordered */ |
51 | 13.9k | s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); |
52 | | |
53 | | /* allocated but unused entries? */ |
54 | 13.9k | if(unused){ |
55 | | /* yes, unused entries */ |
56 | | |
57 | 837k | for(i=0;i<s->entries;i++){ |
58 | 826k | if(oggpack_read(opb,1)){ |
59 | 323k | long num=oggpack_read(opb,5); |
60 | 323k | if(num==-1)goto _eofout; |
61 | 323k | s->lengthlist[i]=num+1; |
62 | 323k | }else |
63 | 502k | s->lengthlist[i]=0; |
64 | 826k | } |
65 | 11.8k | }else{ |
66 | | /* all entries used; no tagging */ |
67 | 334k | for(i=0;i<s->entries;i++){ |
68 | 332k | long num=oggpack_read(opb,5); |
69 | 332k | if(num==-1)goto _eofout; |
70 | 332k | s->lengthlist[i]=num+1; |
71 | 332k | } |
72 | 2.10k | } |
73 | | |
74 | 13.8k | break; |
75 | 13.9k | } |
76 | 13.8k | case 1: |
77 | | /* ordered */ |
78 | 2.54k | { |
79 | 2.54k | long length=oggpack_read(opb,5)+1; |
80 | 2.54k | if(length==0)goto _eofout; |
81 | 2.54k | s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); |
82 | | |
83 | 7.43k | for(i=0;i<s->entries;){ |
84 | 4.99k | long num=oggpack_read(opb,_ilog(s->entries-i)); |
85 | 4.99k | if(num==-1)goto _eofout; |
86 | 4.95k | if(length>32 || num>s->entries-i || |
87 | 4.95k | (num>0 && (num-1)>>(length>>1)>>((length+1)>>1))>0){ |
88 | 63 | goto _errout; |
89 | 63 | } |
90 | 138M | for(j=0;j<num;j++,i++) |
91 | 138M | s->lengthlist[i]=length; |
92 | 4.89k | length++; |
93 | 4.89k | } |
94 | 2.54k | } |
95 | 2.44k | break; |
96 | 2.44k | default: |
97 | | /* EOF */ |
98 | 15 | goto _eofout; |
99 | 16.5k | } |
100 | | |
101 | | /* Do we have a mapping to unpack? */ |
102 | 16.3k | switch((s->maptype=oggpack_read(opb,4))){ |
103 | 8.85k | case 0: |
104 | | /* no mapping */ |
105 | 8.85k | break; |
106 | 7.45k | case 1: case 2: |
107 | | /* implicitly populated value mapping */ |
108 | | /* explicitly populated value mapping */ |
109 | | |
110 | 7.45k | s->q_min=oggpack_read(opb,32); |
111 | 7.45k | s->q_delta=oggpack_read(opb,32); |
112 | 7.45k | s->q_quant=oggpack_read(opb,4)+1; |
113 | 7.45k | s->q_sequencep=oggpack_read(opb,1); |
114 | 7.45k | if(s->q_sequencep==-1)goto _eofout; |
115 | | |
116 | 7.43k | { |
117 | 7.43k | int quantvals=0; |
118 | 7.43k | switch(s->maptype){ |
119 | 5.16k | case 1: |
120 | 5.16k | quantvals=(s->dim==0?0:_book_maptype1_quantvals(s)); |
121 | 5.16k | break; |
122 | 2.27k | case 2: |
123 | 2.27k | quantvals=s->entries*s->dim; |
124 | 2.27k | break; |
125 | 7.43k | } |
126 | | |
127 | | /* quantized values */ |
128 | 7.43k | if((quantvals*s->q_quant+7)>>3>opb->storage-oggpack_bytes(opb)) |
129 | 161 | goto _eofout; |
130 | 7.27k | s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals); |
131 | 112k | for(i=0;i<quantvals;i++) |
132 | 105k | s->quantlist[i]=oggpack_read(opb,s->q_quant); |
133 | | |
134 | 7.27k | if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout; |
135 | 7.27k | } |
136 | 7.27k | break; |
137 | 7.27k | default: |
138 | 25 | goto _errout; |
139 | 16.3k | } |
140 | | |
141 | | /* all set */ |
142 | 16.1k | return(s); |
143 | | |
144 | 88 | _errout: |
145 | 548 | _eofout: |
146 | 548 | vorbis_staticbook_destroy(s); |
147 | 548 | return(NULL); |
148 | 88 | } |
149 | | |
150 | | /* the 'eliminate the decode tree' optimization actually requires the |
151 | | codewords to be MSb first, not LSb. This is an annoying inelegancy |
152 | | (and one of the first places where carefully thought out design |
153 | | turned out to be wrong; Vorbis II and future Ogg codecs should go |
154 | | to an MSb bitpacker), but not actually the huge hit it appears to |
155 | | be. The first-stage decode table catches most words so that |
156 | | bitreverse is not in the main execution path. */ |
157 | | |
158 | 78.4k | static ogg_uint32_t bitreverse(ogg_uint32_t x){ |
159 | 78.4k | x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000); |
160 | 78.4k | x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00); |
161 | 78.4k | x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0); |
162 | 78.4k | x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc); |
163 | 78.4k | return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa); |
164 | 78.4k | } |
165 | | |
166 | | STIN long decode_packed_entry_number(codebook *book, |
167 | 166k | oggpack_buffer *b){ |
168 | 166k | int read=book->dec_maxlength; |
169 | 166k | long lo,hi; |
170 | 166k | long lok = oggpack_look(b,book->dec_firsttablen); |
171 | | |
172 | 166k | if (lok >= 0) { |
173 | 154k | long entry = book->dec_firsttable[lok]; |
174 | 154k | if(entry&0x80000000UL){ |
175 | 70.2k | lo=(entry>>15)&0x7fff; |
176 | 70.2k | hi=book->used_entries-(entry&0x7fff); |
177 | 84.2k | }else{ |
178 | 84.2k | oggpack_adv(b, book->dec_codelengths[entry-1]); |
179 | 84.2k | return(entry-1); |
180 | 84.2k | } |
181 | 154k | }else{ |
182 | 12.2k | lo=0; |
183 | 12.2k | hi=book->used_entries; |
184 | 12.2k | } |
185 | | |
186 | 82.4k | lok = oggpack_look(b, read); |
187 | | |
188 | 101k | while(lok<0 && read>1) |
189 | 19.1k | lok = oggpack_look(b, --read); |
190 | | |
191 | 82.4k | if(lok<0){ |
192 | 4.04k | oggpack_adv(b,1); /* force eop */ |
193 | 4.04k | return -1; |
194 | 4.04k | } |
195 | | |
196 | | /* bisect search for the codeword in the ordered list */ |
197 | 78.4k | { |
198 | 78.4k | ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok); |
199 | | |
200 | 102k | while(hi-lo>1){ |
201 | 23.5k | long p=(hi-lo)>>1; |
202 | 23.5k | long test=book->codelist[lo+p]>testword; |
203 | 23.5k | lo+=p&(test-1); |
204 | 23.5k | hi-=p&(-test); |
205 | 23.5k | } |
206 | | |
207 | 78.4k | if(book->dec_codelengths[lo]<=read){ |
208 | 77.2k | oggpack_adv(b, book->dec_codelengths[lo]); |
209 | 77.2k | return(lo); |
210 | 77.2k | } |
211 | 78.4k | } |
212 | | |
213 | 1.20k | oggpack_adv(b, read+1); |
214 | 1.20k | return(-1); |
215 | 78.4k | } |
216 | | |
217 | | /* Decode side is specced and easier, because we don't need to find |
218 | | matches using different criteria; we simply read and map. There are |
219 | | two things we need to do 'depending': |
220 | | |
221 | | We may need to support interleave. We don't really, but it's |
222 | | convenient to do it here rather than rebuild the vector later. |
223 | | |
224 | | Cascades may be additive or multiplicitive; this is not inherent in |
225 | | the codebook, but set in the code using the codebook. Like |
226 | | interleaving, it's easiest to do it here. |
227 | | addmul==0 -> declarative (set the value) |
228 | | addmul==1 -> additive |
229 | | addmul==2 -> multiplicitive */ |
230 | | |
231 | | /* returns the [original, not compacted] entry number or -1 on eof *********/ |
232 | 60.6k | long vorbis_book_decode(codebook *book, oggpack_buffer *b){ |
233 | 60.6k | if(book->used_entries>0){ |
234 | 60.3k | long packed_entry=decode_packed_entry_number(book,b); |
235 | 60.3k | if(packed_entry>=0) |
236 | 57.9k | return(book->dec_index[packed_entry]); |
237 | 60.3k | } |
238 | | |
239 | | /* if there's no dec_index, the codebook unpacking isn't collapsed */ |
240 | 2.75k | return(-1); |
241 | 60.6k | } |
242 | | |
243 | | /* returns 0 on OK or -1 on eof *************************************/ |
244 | | /* decode vector / dim granularity gaurding is done in the upper layer */ |
245 | | long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, |
246 | 50.1k | oggpack_buffer *b,int n,int point){ |
247 | 50.1k | if(book->used_entries>0){ |
248 | 49.8k | int step=n/book->dim; |
249 | 49.8k | long *entry = (long *)alloca(sizeof(*entry)*step); |
250 | 49.8k | ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step); |
251 | 49.8k | int i,j,o; |
252 | 49.8k | int shift=point-book->binarypoint; |
253 | | |
254 | 49.8k | if(shift>=0){ |
255 | 32.7k | for (i = 0; i < step; i++) { |
256 | 12.5k | entry[i]=decode_packed_entry_number(book,b); |
257 | 12.5k | if(entry[i]==-1)return(-1); |
258 | 12.2k | t[i] = book->valuelist+entry[i]*book->dim; |
259 | 12.2k | } |
260 | 714M | for(i=0,o=0;i<book->dim;i++,o+=step) |
261 | 714M | for (j=0;o+j<n && j<step;j++) |
262 | 242k | a[o+j]+=t[j][i]>>shift; |
263 | 29.3k | }else{ |
264 | 40.9k | for (i = 0; i < step; i++) { |
265 | 11.8k | entry[i]=decode_packed_entry_number(book,b); |
266 | 11.8k | if(entry[i]==-1)return(-1); |
267 | 11.5k | t[i] = book->valuelist+entry[i]*book->dim; |
268 | 11.5k | } |
269 | 760M | for(i=0,o=0;i<book->dim;i++,o+=step) |
270 | 760M | for (j=0;o+j<n && j<step;j++) |
271 | 46.3k | a[o+j]+=t[j][i]<<-shift; |
272 | 29.1k | } |
273 | 49.8k | } |
274 | 49.6k | return(0); |
275 | 50.1k | } |
276 | | |
277 | | /* decode vector / dim granularity gaurding is done in the upper layer */ |
278 | | long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a, |
279 | 1.75k | oggpack_buffer *b,int n,int point){ |
280 | 1.75k | if(book->used_entries>0){ |
281 | 1.54k | int i,j,entry; |
282 | 1.54k | ogg_int32_t *t; |
283 | 1.54k | int shift=point-book->binarypoint; |
284 | | |
285 | 1.54k | if(shift>=0){ |
286 | 3.89k | for(i=0;i<n;){ |
287 | 3.32k | entry = decode_packed_entry_number(book,b); |
288 | 3.32k | if(entry==-1)return(-1); |
289 | 3.05k | t = book->valuelist+entry*book->dim; |
290 | 102k | for (j=0;i<n && j<book->dim;) |
291 | 99.6k | a[i++]+=t[j++]>>shift; |
292 | 3.05k | } |
293 | 836 | }else{ |
294 | 2.79k | for(i=0;i<n;){ |
295 | 2.34k | entry = decode_packed_entry_number(book,b); |
296 | 2.34k | if(entry==-1)return(-1); |
297 | 2.08k | t = book->valuelist+entry*book->dim; |
298 | 108k | for (j=0;i<n && j<book->dim;) |
299 | 106k | a[i++]+=t[j++]<<-shift; |
300 | 2.08k | } |
301 | 711 | } |
302 | 1.54k | } |
303 | 1.21k | return(0); |
304 | 1.75k | } |
305 | | |
306 | | /* unlike the others, we guard against n not being an integer number |
307 | | of <dim> internally rather than in the upper layer (called only by |
308 | | floor0) */ |
309 | | long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, |
310 | 9.65k | oggpack_buffer *b,int n,int point){ |
311 | 9.65k | if(book->used_entries>0){ |
312 | 8.85k | int i,j,entry; |
313 | 8.85k | ogg_int32_t *t; |
314 | 8.85k | int shift=point-book->binarypoint; |
315 | | |
316 | 8.85k | if(shift>=0){ |
317 | | |
318 | 20.0k | for(i=0;i<n;){ |
319 | 15.9k | entry = decode_packed_entry_number(book,b); |
320 | 15.9k | if(entry==-1)return(-1); |
321 | 15.2k | t = book->valuelist+entry*book->dim; |
322 | 538k | for (j=0;i<n && j<book->dim;){ |
323 | 523k | a[i++]=t[j++]>>shift; |
324 | 523k | } |
325 | 15.2k | } |
326 | 4.76k | }else{ |
327 | | |
328 | 14.2k | for(i=0;i<n;){ |
329 | 10.5k | entry = decode_packed_entry_number(book,b); |
330 | 10.5k | if(entry==-1)return(-1); |
331 | 10.1k | t = book->valuelist+entry*book->dim; |
332 | 295k | for (j=0;i<n && j<book->dim;){ |
333 | 285k | a[i++]=t[j++]<<-shift; |
334 | 285k | } |
335 | 10.1k | } |
336 | 4.08k | } |
337 | 8.85k | }else{ |
338 | | |
339 | 807 | int i,j; |
340 | 93.5k | for(i=0;i<n;){ |
341 | 92.7k | a[i++]=0; |
342 | 92.7k | } |
343 | 807 | } |
344 | 8.59k | return(0); |
345 | 9.65k | } |
346 | | |
347 | | /* decode vector / dim granularity gaurding is done in the upper layer */ |
348 | | long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,\ |
349 | | long offset,int ch, |
350 | 193k | oggpack_buffer *b,int n,int point){ |
351 | 193k | if(book->used_entries>0){ |
352 | 193k | long i,j,entry; |
353 | 193k | int chptr=0; |
354 | 193k | int shift=point-book->binarypoint; |
355 | 193k | int m=offset+n; |
356 | 193k | if(shift>=0){ |
357 | | |
358 | 22.0k | for(i=offset;i<m;){ |
359 | 10.7k | entry = decode_packed_entry_number(book,b); |
360 | 10.7k | if(entry==-1)return(-1); |
361 | 10.4k | { |
362 | 10.4k | const ogg_int32_t *t = book->valuelist+entry*book->dim; |
363 | 850k | for (j=0;i<m && j<book->dim;j++){ |
364 | 840k | a[chptr++][i]+=t[j]>>shift; |
365 | 840k | if(chptr==ch){ |
366 | 67.5k | chptr=0; |
367 | 67.5k | i++; |
368 | 67.5k | } |
369 | 840k | } |
370 | 10.4k | } |
371 | 10.4k | } |
372 | 181k | }else{ |
373 | | |
374 | 220k | for(i=offset;i<m;){ |
375 | 39.1k | entry = decode_packed_entry_number(book,b); |
376 | 39.1k | if(entry==-1)return(-1); |
377 | 38.7k | { |
378 | 38.7k | const ogg_int32_t *t = book->valuelist+entry*book->dim; |
379 | 1.36M | for (j=0;i<m && j<book->dim;j++){ |
380 | 1.32M | a[chptr++][i]+=t[j]<<-shift; |
381 | 1.32M | if(chptr==ch){ |
382 | 51.7k | chptr=0; |
383 | 51.7k | i++; |
384 | 51.7k | } |
385 | 1.32M | } |
386 | 38.7k | } |
387 | 38.7k | } |
388 | 181k | } |
389 | 193k | } |
390 | 192k | return(0); |
391 | 193k | } |