diff options
Diffstat (limited to 'lib/rbcodec/codecs/libtremor/codebook.c')
-rw-r--r-- | lib/rbcodec/codecs/libtremor/codebook.c | 587 |
1 files changed, 587 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libtremor/codebook.c b/lib/rbcodec/codecs/libtremor/codebook.c new file mode 100644 index 0000000000..7087f0a323 --- /dev/null +++ b/lib/rbcodec/codecs/libtremor/codebook.c | |||
@@ -0,0 +1,587 @@ | |||
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 "config-tremor.h" | ||
19 | #include <string.h> | ||
20 | #include <math.h> | ||
21 | #include "ogg.h" | ||
22 | #include "ivorbiscodec.h" | ||
23 | #include "codebook.h" | ||
24 | #include "misc.h" | ||
25 | #include "os.h" | ||
26 | |||
27 | /* unpacks a codebook from the packet buffer into the codebook struct, | ||
28 | readies the codebook auxiliary structures for decode *************/ | ||
29 | static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){ | ||
30 | long i,j; | ||
31 | static_codebook *s=_ogg_calloc(1,sizeof(*s)); | ||
32 | |||
33 | /* make sure alignment is correct */ | ||
34 | if(oggpack_read(opb,24)!=0x564342)goto _eofout; | ||
35 | |||
36 | /* first the basic parameters */ | ||
37 | s->dim=oggpack_read(opb,16); | ||
38 | s->entries=oggpack_read(opb,24); | ||
39 | if(s->entries==-1)goto _eofout; | ||
40 | |||
41 | if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout; | ||
42 | |||
43 | /* codeword ordering.... length ordered or unordered? */ | ||
44 | switch((int)oggpack_read(opb,1)){ | ||
45 | case 0:{ | ||
46 | long unused; | ||
47 | /* allocated but unused entries? */ | ||
48 | unused=oggpack_read(opb,1); | ||
49 | if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb)) | ||
50 | goto _eofout; | ||
51 | /* unordered */ | ||
52 | s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); | ||
53 | |||
54 | /* allocated but unused entries? */ | ||
55 | if(unused){ | ||
56 | /* yes, unused entries */ | ||
57 | |||
58 | for(i=0;i<s->entries;i++){ | ||
59 | if(oggpack_read(opb,1)){ | ||
60 | long num=oggpack_read(opb,5); | ||
61 | if(num==-1)goto _eofout; | ||
62 | s->lengthlist[i]=num+1; | ||
63 | }else | ||
64 | s->lengthlist[i]=0; | ||
65 | } | ||
66 | }else{ | ||
67 | /* all entries used; no tagging */ | ||
68 | for(i=0;i<s->entries;i++){ | ||
69 | long num=oggpack_read(opb,5); | ||
70 | if(num==-1)goto _eofout; | ||
71 | s->lengthlist[i]=num+1; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | break; | ||
76 | } | ||
77 | case 1: | ||
78 | /* ordered */ | ||
79 | { | ||
80 | long length=oggpack_read(opb,5)+1; | ||
81 | if(length==0)goto _eofout; | ||
82 | s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); | ||
83 | |||
84 | for(i=0;i<s->entries;){ | ||
85 | long num=oggpack_read(opb,_ilog(s->entries-i)); | ||
86 | if(num==-1)goto _eofout; | ||
87 | if(length>32 || num>s->entries-i || | ||
88 | (num>0 && (num-1)>>(length>>1)>>((length+1)>>1))>0){ | ||
89 | goto _errout; | ||
90 | } | ||
91 | for(j=0;j<num;j++,i++) | ||
92 | s->lengthlist[i]=length; | ||
93 | length++; | ||
94 | } | ||
95 | } | ||
96 | break; | ||
97 | default: | ||
98 | /* EOF */ | ||
99 | goto _eofout; | ||
100 | } | ||
101 | |||
102 | /* Do we have a mapping to unpack? */ | ||
103 | switch((s->maptype=oggpack_read(opb,4))){ | ||
104 | case 0: | ||
105 | /* no mapping */ | ||
106 | break; | ||
107 | case 1: case 2: | ||
108 | /* implicitly populated value mapping */ | ||
109 | /* explicitly populated value mapping */ | ||
110 | |||
111 | s->q_min=oggpack_read(opb,32); | ||
112 | s->q_delta=oggpack_read(opb,32); | ||
113 | s->q_quant=oggpack_read(opb,4)+1; | ||
114 | s->q_sequencep=oggpack_read(opb,1); | ||
115 | if(s->q_sequencep==-1)goto _eofout; | ||
116 | |||
117 | { | ||
118 | int quantvals=0; | ||
119 | switch(s->maptype){ | ||
120 | case 1: | ||
121 | quantvals=(s->dim==0?0:_book_maptype1_quantvals(s)); | ||
122 | break; | ||
123 | case 2: | ||
124 | quantvals=s->entries*s->dim; | ||
125 | break; | ||
126 | } | ||
127 | |||
128 | /* quantized values */ | ||
129 | if((quantvals*s->q_quant+7)>>3>opb->storage-oggpack_bytes(opb)) | ||
130 | goto _eofout; | ||
131 | s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals); | ||
132 | for(i=0;i<quantvals;i++) | ||
133 | s->quantlist[i]=oggpack_read(opb,s->q_quant); | ||
134 | |||
135 | if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout; | ||
136 | } | ||
137 | break; | ||
138 | default: | ||
139 | goto _errout; | ||
140 | } | ||
141 | |||
142 | /* all set */ | ||
143 | return(s); | ||
144 | |||
145 | _errout: | ||
146 | _eofout: | ||
147 | vorbis_staticbook_destroy(s); | ||
148 | return(NULL); | ||
149 | } | ||
150 | |||
151 | /* the 'eliminate the decode tree' optimization actually requires the | ||
152 | codewords to be MSb first, not LSb. This is an annoying inelegancy | ||
153 | (and one of the first places where carefully thought out design | ||
154 | turned out to be wrong; Vorbis II and future Ogg codecs should go | ||
155 | to an MSb bitpacker), but not actually the huge hit it appears to | ||
156 | be. The first-stage decode table catches most words so that | ||
157 | bitreverse is not in the main execution path. */ | ||
158 | |||
159 | static inline ogg_uint32_t bitreverse(register ogg_uint32_t x) | ||
160 | { | ||
161 | unsigned tmp, ret; | ||
162 | #ifdef _ARM_ASSEM_ | ||
163 | #if ARM_ARCH >= 6 | ||
164 | unsigned mask = 0x0f0f0f0f; | ||
165 | #else | ||
166 | unsigned mask = 0x00ff00ff; | ||
167 | #endif | ||
168 | asm ( | ||
169 | #if ARM_ARCH >= 6 | ||
170 | "rev %[r], %[x] \n" /* swap halfwords and bytes */ | ||
171 | "and %[t], %[m], %[r] \n" /* Sequence is one instruction */ | ||
172 | "eor %[r], %[t], %[r] \n" /* longer than on <= ARMv5, but */ | ||
173 | "mov %[t], %[t], lsl #4 \n" /* interlock free */ | ||
174 | "orr %[r], %[t], %[r], lsr #4\n" /* nibbles swapped */ | ||
175 | "eor %[m], %[m], %[m], lsl #2\n" /* mask = 0x33333333 */ | ||
176 | "and %[t], %[m], %[r] \n" | ||
177 | "eor %[r], %[t], %[r] \n" | ||
178 | "mov %[t], %[t], lsl #2 \n" | ||
179 | "orr %[r], %[t], %[r], lsr #2\n" /* dibits swapped */ | ||
180 | "eor %[m], %[m], %[m], lsl #1\n" /* mask = 0x55555555 */ | ||
181 | "and %[t], %[m], %[r] \n" | ||
182 | "eor %[r], %[t], %[r] \n" | ||
183 | "mov %[t], %[t], lsl #1 \n" | ||
184 | "orr %[r], %[t], %[r], lsr #1\n" /* bits swapped */ | ||
185 | #else /* ARM_ARCH <= 5 */ | ||
186 | "mov %[r], %[x], ror #16 \n" /* swap halfwords */ | ||
187 | "and %[t], %[m], %[r], lsr #8\n" | ||
188 | "eor %[r], %[r], %[t], lsl #8\n" | ||
189 | "orr %[r], %[t], %[r], lsl #8\n" /* bytes swapped */ | ||
190 | "eor %[m], %[m], %[m], lsl #4\n" /* mask = 0x0f0f0f0f */ | ||
191 | "and %[t], %[m], %[r], lsr #4\n" | ||
192 | "eor %[r], %[r], %[t], lsl #4\n" | ||
193 | "orr %[r], %[t], %[r], lsl #4\n" /* nibbles swapped */ | ||
194 | "eor %[m], %[m], %[m], lsl #2\n" /* mask = 0x33333333 */ | ||
195 | "and %[t], %[m], %[r], lsr #2\n" | ||
196 | "eor %[r], %[r], %[t], lsl #2\n" | ||
197 | "orr %[r], %[t], %[r], lsl #2\n" /* dibits swapped */ | ||
198 | "eor %[m], %[m], %[m], lsl #1\n" /* mask = 0x55555555 */ | ||
199 | "and %[t], %[m], %[r], lsr #1\n" | ||
200 | "eor %[r], %[r], %[t], lsl #1\n" | ||
201 | "orr %[r], %[t], %[r], lsl #1\n" /* bits swapped */ | ||
202 | #endif /* ARM_ARCH */ | ||
203 | : /* outputs */ | ||
204 | [m]"+r"(mask), | ||
205 | [r]"=r"(ret), | ||
206 | [t]"=r"(tmp) | ||
207 | : /* inputs */ | ||
208 | [x]"r"(x) | ||
209 | ); | ||
210 | #else /* !_ARM_ASSEM_ */ | ||
211 | |||
212 | ret = (x>>16) | (x<<16); | ||
213 | tmp = ret & 0x00ff00ff; | ||
214 | ret ^= tmp; | ||
215 | ret = (ret >> 8) | (tmp << 8); /* bytes swapped */ | ||
216 | tmp = ret & 0x0f0f0f0f; | ||
217 | ret ^= tmp; | ||
218 | ret = (ret >> 4) | (tmp << 4); /* 4-bit units swapped */ | ||
219 | tmp = ret & 0x33333333; | ||
220 | ret ^= tmp; | ||
221 | ret = (ret >> 2) | (tmp << 2); /* 2-bit units swapped */ | ||
222 | tmp = ret & 0x55555555; | ||
223 | ret ^= tmp; | ||
224 | ret = (ret >> 1) | (tmp << 1); /* done */ | ||
225 | #endif /* !_ARM_ASSEM_ */ | ||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | static inline long bisect_codelist(long lo, long hi, ogg_uint32_t cache, | ||
230 | const ogg_uint32_t *codelist) | ||
231 | { | ||
232 | ogg_uint32_t testword=bitreverse(cache); | ||
233 | long p; | ||
234 | while(LIKELY(p = (hi-lo) >> 1) > 0){ | ||
235 | if(codelist[lo+p] > testword) | ||
236 | hi -= p; | ||
237 | else | ||
238 | lo += p; | ||
239 | } | ||
240 | return lo; | ||
241 | } | ||
242 | |||
243 | STIN long decode_packed_entry_number(codebook *book, | ||
244 | oggpack_buffer *b){ | ||
245 | int read=book->dec_maxlength; | ||
246 | long lo,hi; | ||
247 | long lok = oggpack_look(b,book->dec_firsttablen); | ||
248 | |||
249 | if (LIKELY(lok >= 0)) { | ||
250 | ogg_int32_t entry = book->dec_firsttable[lok]; | ||
251 | if(UNLIKELY(entry < 0)){ | ||
252 | lo=(entry>>15)&0x7fff; | ||
253 | hi=book->used_entries-(entry&0x7fff); | ||
254 | }else{ | ||
255 | oggpack_adv(b, book->dec_codelengths[entry-1]); | ||
256 | return(entry-1); | ||
257 | } | ||
258 | }else{ | ||
259 | lo=0; | ||
260 | hi=book->used_entries; | ||
261 | } | ||
262 | |||
263 | lok = oggpack_look(b, read); | ||
264 | |||
265 | while(lok<0 && read>1) | ||
266 | lok = oggpack_look(b, --read); | ||
267 | |||
268 | if(lok<0){ | ||
269 | oggpack_adv(b,1); /* force eop */ | ||
270 | return -1; | ||
271 | } | ||
272 | |||
273 | /* bisect search for the codeword in the ordered list */ | ||
274 | { | ||
275 | lo = bisect_codelist(lo, hi, lok, book->codelist); | ||
276 | |||
277 | if(book->dec_codelengths[lo]<=read){ | ||
278 | oggpack_adv(b, book->dec_codelengths[lo]); | ||
279 | return(lo); | ||
280 | } | ||
281 | } | ||
282 | |||
283 | oggpack_adv(b, read+1); | ||
284 | return(-1); | ||
285 | } | ||
286 | |||
287 | static long decode_packed_block(codebook *book, oggpack_buffer *b, | ||
288 | long *buf, int n){ | ||
289 | long *bufptr = buf; | ||
290 | long *bufend = buf + n; | ||
291 | |||
292 | while (bufptr<bufend) { | ||
293 | if(b->endbyte < b->storage - 8) { | ||
294 | ogg_uint32_t *ptr; | ||
295 | unsigned long bit, bitend; | ||
296 | unsigned long adr; | ||
297 | ogg_uint32_t cache = 0; | ||
298 | int cachesize = 0; | ||
299 | const unsigned int cachemask = (1<<book->dec_firsttablen)-1; | ||
300 | const int book_dec_maxlength = book->dec_maxlength; | ||
301 | const ogg_uint32_t *book_dec_firsttable = book->dec_firsttable; | ||
302 | const long book_used_entries = book->used_entries; | ||
303 | const ogg_uint32_t *book_codelist = book->codelist; | ||
304 | const char *book_dec_codelengths = book->dec_codelengths; | ||
305 | |||
306 | adr = (unsigned long)b->ptr; | ||
307 | bit = (adr&3)*8+b->endbit; | ||
308 | ptr = (ogg_uint32_t*)(adr&~3); | ||
309 | bitend = ((adr&3)+(b->storage-b->endbyte))*8; | ||
310 | while (bufptr<bufend){ | ||
311 | if (UNLIKELY(cachesize<book_dec_maxlength)) { | ||
312 | if (bit-cachesize+32>=bitend) | ||
313 | break; | ||
314 | bit-=cachesize; | ||
315 | cache = letoh32(ptr[bit>>5]); | ||
316 | if (bit&31) { | ||
317 | cache >>= (bit&31); | ||
318 | cache |= letoh32(ptr[(bit>>5)+1]) << (32-(bit&31)); | ||
319 | } | ||
320 | cachesize=32; | ||
321 | bit+=32; | ||
322 | } | ||
323 | |||
324 | ogg_int32_t entry = book_dec_firsttable[cache&cachemask]; | ||
325 | if(UNLIKELY(entry < 0)){ | ||
326 | const long lo = (entry>>15)&0x7fff, hi = book_used_entries-(entry&0x7fff); | ||
327 | entry = bisect_codelist(lo, hi, cache, book_codelist); | ||
328 | }else | ||
329 | entry--; | ||
330 | |||
331 | *bufptr++ = entry; | ||
332 | int l = book_dec_codelengths[entry]; | ||
333 | cachesize -= l; | ||
334 | cache >>= l; | ||
335 | } | ||
336 | |||
337 | adr=(unsigned long)b->ptr; | ||
338 | bit-=(adr&3)*8+cachesize; | ||
339 | b->endbyte+=bit/8; | ||
340 | b->ptr+=bit/8; | ||
341 | b->endbit=bit&7; | ||
342 | } else { | ||
343 | long r = decode_packed_entry_number(book, b); | ||
344 | if (r == -1) return bufptr-buf; | ||
345 | *bufptr++ = r; | ||
346 | } | ||
347 | } | ||
348 | return n; | ||
349 | } | ||
350 | |||
351 | /* Decode side is specced and easier, because we don't need to find | ||
352 | matches using different criteria; we simply read and map. There are | ||
353 | two things we need to do 'depending': | ||
354 | |||
355 | We may need to support interleave. We don't really, but it's | ||
356 | convenient to do it here rather than rebuild the vector later. | ||
357 | |||
358 | Cascades may be additive or multiplicitive; this is not inherent in | ||
359 | the codebook, but set in the code using the codebook. Like | ||
360 | interleaving, it's easiest to do it here. | ||
361 | addmul==0 -> declarative (set the value) | ||
362 | addmul==1 -> additive | ||
363 | addmul==2 -> multiplicitive */ | ||
364 | |||
365 | /* returns the [original, not compacted] entry number or -1 on eof *********/ | ||
366 | long vorbis_book_decode(codebook *book, oggpack_buffer *b){ | ||
367 | if(book->used_entries>0){ | ||
368 | long packed_entry=decode_packed_entry_number(book,b); | ||
369 | if(packed_entry>=0) | ||
370 | return(book->dec_index[packed_entry]); | ||
371 | } | ||
372 | |||
373 | /* if there's no dec_index, the codebook unpacking isn't collapsed */ | ||
374 | return(-1); | ||
375 | } | ||
376 | |||
377 | /* returns 0 on OK or -1 on eof *************************************/ | ||
378 | /* decode vector / dim granularity gaurding is done in the upper layer */ | ||
379 | long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, | ||
380 | oggpack_buffer *b,int n,int point){ | ||
381 | if(book->used_entries>0){ | ||
382 | int step=n/book->dim; | ||
383 | long *entry = (long *)alloca(sizeof(*entry)*step); | ||
384 | ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step); | ||
385 | int i,j,o; | ||
386 | int shift=point-book->binarypoint; | ||
387 | |||
388 | if(shift>=0){ | ||
389 | for (i = 0; i < step; i++) { | ||
390 | entry[i]=decode_packed_entry_number(book,b); | ||
391 | if(entry[i]==-1)return(-1); | ||
392 | t[i] = book->valuelist+entry[i]*book->dim; | ||
393 | } | ||
394 | for(i=0,o=0;i<book->dim;i++,o+=step) | ||
395 | for (j=0;j<step;j++) | ||
396 | a[o+j]+=t[j][i]>>shift; | ||
397 | }else{ | ||
398 | for (i = 0; i < step; i++) { | ||
399 | entry[i]=decode_packed_entry_number(book,b); | ||
400 | if(entry[i]==-1)return(-1); | ||
401 | t[i] = book->valuelist+entry[i]*book->dim; | ||
402 | } | ||
403 | for(i=0,o=0;i<book->dim;i++,o+=step) | ||
404 | for (j=0;j<step;j++) | ||
405 | a[o+j]+=t[j][i]<<-shift; | ||
406 | } | ||
407 | } | ||
408 | return(0); | ||
409 | } | ||
410 | |||
411 | /* decode vector / dim granularity gaurding is done in the upper layer */ | ||
412 | long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a, | ||
413 | oggpack_buffer *b,int n,int point){ | ||
414 | if(book->used_entries>0){ | ||
415 | int i,j,entry; | ||
416 | ogg_int32_t *t; | ||
417 | int shift=point-book->binarypoint; | ||
418 | |||
419 | if(shift>=0){ | ||
420 | for(i=0;i<n;){ | ||
421 | entry = decode_packed_entry_number(book,b); | ||
422 | if(entry==-1)return(-1); | ||
423 | t = book->valuelist+entry*book->dim; | ||
424 | for (j=0;j<book->dim;) | ||
425 | a[i++]+=t[j++]>>shift; | ||
426 | } | ||
427 | }else{ | ||
428 | shift = -shift; | ||
429 | for(i=0;i<n;){ | ||
430 | entry = decode_packed_entry_number(book,b); | ||
431 | if(entry==-1)return(-1); | ||
432 | t = book->valuelist+entry*book->dim; | ||
433 | for (j=0;j<book->dim;) | ||
434 | a[i++]+=t[j++]<<shift; | ||
435 | } | ||
436 | } | ||
437 | } | ||
438 | return(0); | ||
439 | } | ||
440 | |||
441 | /* unlike the others, we guard against n not being an integer number | ||
442 | of <dim> internally rather than in the upper layer (called only by | ||
443 | floor0) */ | ||
444 | long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, | ||
445 | oggpack_buffer *b,int n,int point){ | ||
446 | if(book->used_entries>0){ | ||
447 | int i,j,entry; | ||
448 | ogg_int32_t *t; | ||
449 | int shift=point-book->binarypoint; | ||
450 | |||
451 | if(shift>=0){ | ||
452 | |||
453 | for(i=0;i<n;){ | ||
454 | entry = decode_packed_entry_number(book,b); | ||
455 | if(entry==-1)return(-1); | ||
456 | t = book->valuelist+entry*book->dim; | ||
457 | for (j=0;i<n && j<book->dim;){ | ||
458 | a[i++]=t[j++]>>shift; | ||
459 | } | ||
460 | } | ||
461 | }else{ | ||
462 | shift = -shift; | ||
463 | for(i=0;i<n;){ | ||
464 | entry = decode_packed_entry_number(book,b); | ||
465 | if(entry==-1)return(-1); | ||
466 | t = book->valuelist+entry*book->dim; | ||
467 | for (j=0;i<n && j<book->dim;){ | ||
468 | a[i++]=t[j++]<<shift; | ||
469 | } | ||
470 | } | ||
471 | } | ||
472 | }else{ | ||
473 | |||
474 | int i; | ||
475 | for(i=0;i<n;){ | ||
476 | a[i++]=0; | ||
477 | } | ||
478 | } | ||
479 | return(0); | ||
480 | } | ||
481 | |||
482 | /* decode vector / dim granularity gaurding is done in the upper layer */ | ||
483 | static long vorbis_book_decodevv_add_2ch_even(codebook *book,ogg_int32_t **a, | ||
484 | long offset,oggpack_buffer *b, | ||
485 | unsigned int n,int point){ | ||
486 | long k,chunk,read; | ||
487 | int shift=point-book->binarypoint; | ||
488 | long entries[32]; | ||
489 | ogg_int32_t *p0 = &(a[0][offset]); | ||
490 | ogg_int32_t *p1 = &(a[1][offset]); | ||
491 | const unsigned long dim = book->dim; | ||
492 | const ogg_int32_t * const vlist = book->valuelist; | ||
493 | |||
494 | if(shift>=0){ | ||
495 | while(n>0){ | ||
496 | chunk=32; | ||
497 | if (16*dim>n) | ||
498 | chunk=(n*2-1)/dim + 1; | ||
499 | read = decode_packed_block(book,b,entries,chunk); | ||
500 | for(k=0;k<read;k++){ | ||
501 | const ogg_int32_t *t = vlist+entries[k]*dim; | ||
502 | const ogg_int32_t *u = t+dim; | ||
503 | do{ | ||
504 | *p0++ += *t++>>shift; | ||
505 | *p1++ += *t++>>shift; | ||
506 | }while(t<u); | ||
507 | } | ||
508 | if (read<chunk)return-1; | ||
509 | n -= read*dim/2; | ||
510 | } | ||
511 | }else{ | ||
512 | shift = -shift; | ||
513 | while(n>0){ | ||
514 | chunk=32; | ||
515 | if (16*dim>n) | ||
516 | chunk=(n*2-1)/dim + 1; | ||
517 | read = decode_packed_block(book,b,entries,chunk); | ||
518 | for(k=0;k<read;k++){ | ||
519 | const ogg_int32_t *t = vlist+entries[k]*dim; | ||
520 | const ogg_int32_t *u = t+dim; | ||
521 | do{ | ||
522 | *p0++ += *t++<<shift; | ||
523 | *p1++ += *t++<<shift; | ||
524 | }while(t<u); | ||
525 | } | ||
526 | if (read<chunk)return-1; | ||
527 | n -= read*dim/2; | ||
528 | } | ||
529 | } | ||
530 | return(0); | ||
531 | } | ||
532 | |||
533 | long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, | ||
534 | long offset,int ch, | ||
535 | oggpack_buffer *b,int n,int point){ | ||
536 | if(LIKELY(book->used_entries>0)){ | ||
537 | long i,j,k,chunk,read; | ||
538 | int chptr=0; | ||
539 | int shift=point-book->binarypoint; | ||
540 | long entries[32]; | ||
541 | |||
542 | if (!(book->dim&1) && ch==2) | ||
543 | return vorbis_book_decodevv_add_2ch_even(book,a,offset,b,n,point); | ||
544 | |||
545 | if(shift>=0){ | ||
546 | |||
547 | for(i=offset;i<offset+n;){ | ||
548 | chunk=32; | ||
549 | if (chunk*book->dim>(offset+n-i)*ch) | ||
550 | chunk=((offset+n-i)*ch+book->dim-1)/book->dim; | ||
551 | read = decode_packed_block(book,b,entries,chunk); | ||
552 | for(k=0;k<read;k++){ | ||
553 | const ogg_int32_t *t = book->valuelist+entries[k]*book->dim; | ||
554 | for (j=0;j<book->dim;j++){ | ||
555 | a[chptr++][i]+=t[j]>>shift; | ||
556 | if(chptr==ch){ | ||
557 | chptr=0; | ||
558 | i++; | ||
559 | } | ||
560 | } | ||
561 | } | ||
562 | if (read<chunk)return-1; | ||
563 | } | ||
564 | }else{ | ||
565 | shift = -shift; | ||
566 | for(i=offset;i<offset+n;){ | ||
567 | chunk=32; | ||
568 | if (chunk*book->dim>(offset+n-i)*ch) | ||
569 | chunk=((offset+n-i)*ch+book->dim-1)/book->dim; | ||
570 | read = decode_packed_block(book,b,entries,chunk); | ||
571 | for(k=0;k<read;k++){ | ||
572 | const ogg_int32_t *t = book->valuelist+entries[k]*book->dim; | ||
573 | for (j=0;j<book->dim;j++){ | ||
574 | a[chptr++][i]+=t[j]<<shift; | ||
575 | if(chptr==ch){ | ||
576 | chptr=0; | ||
577 | i++; | ||
578 | } | ||
579 | } | ||
580 | } | ||
581 | if (read<chunk)return-1; | ||
582 | } | ||
583 | } | ||
584 | } | ||
585 | return(0); | ||
586 | } | ||
587 | |||