summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/codecs/Tremor/codebook.c103
-rw-r--r--apps/codecs/Tremor/misc.h10
2 files changed, 101 insertions, 12 deletions
diff --git a/apps/codecs/Tremor/codebook.c b/apps/codecs/Tremor/codebook.c
index f03b5efb04..cad4e8141f 100644
--- a/apps/codecs/Tremor/codebook.c
+++ b/apps/codecs/Tremor/codebook.c
@@ -154,9 +154,9 @@ static inline long decode_packed_entry_number(codebook *book,
154 long lo,hi; 154 long lo,hi;
155 long lok = oggpack_look(b,book->dec_firsttablen); 155 long lok = oggpack_look(b,book->dec_firsttablen);
156 156
157 if (lok >= 0) { 157 if (EXPECT(lok >= 0, 1)) {
158 long entry = book->dec_firsttable[lok]; 158 long entry = book->dec_firsttable[lok];
159 if(entry&0x80000000UL){ 159 if(EXPECT(entry&0x80000000UL, 0)){
160 lo=(entry>>15)&0x7fff; 160 lo=(entry>>15)&0x7fff;
161 hi=book->used_entries-(entry&0x7fff); 161 hi=book->used_entries-(entry&0x7fff);
162 }else{ 162 }else{
@@ -195,6 +195,78 @@ static inline long decode_packed_entry_number(codebook *book,
195 return(-1); 195 return(-1);
196} 196}
197 197
198static inline long decode_packed_block(codebook *book, oggpack_buffer *b,
199 long *buf, int n){
200 long *bufptr = buf;
201 long *bufend = buf + n;
202
203 while (bufptr<bufend) {
204 if (b->headend > 8) {
205 ogg_uint32_t *ptr;
206 unsigned long bit, bitend;
207 unsigned long adr;
208 ogg_uint32_t cache = 0;
209 int cachesize = 0;
210
211 adr = (unsigned long)b->headptr;
212 bit = (adr&3)*8+b->headbit;
213 ptr = (ogg_uint32_t *)(adr&~3);
214 bitend = ((adr&3)+b->headend)*8;
215 while (bufptr<bufend){
216 long entry, lo, hi;
217 if (EXPECT(cachesize<book->dec_maxlength, 0)) {
218 if (bit-cachesize+32>=bitend)
219 break;
220 bit-=cachesize;
221 cache=letoh32(ptr[bit>>5]) >> (bit&31);
222 if (bit&31)
223 cache|=letoh32(ptr[(bit>>5)+1]) << (32-(bit&31));
224 cachesize=32;
225 bit+=32;
226 }
227
228 entry=book->dec_firsttable[cache&((1<<book->dec_firsttablen)-1)];
229 if(EXPECT(entry&0x80000000UL, 0)){
230 lo=(entry>>15)&0x7fff;
231 hi=book->used_entries-(entry&0x7fff);
232 {
233 ogg_uint32_t testword=bitreverse((ogg_uint32_t)cache);
234
235 while(EXPECT(hi-lo>1, 1)){
236 long p=(hi-lo)>>1;
237 if (book->codelist[lo+p]>testword)
238 hi-=p;
239 else
240 lo+=p;
241 }
242 entry=lo;
243 }
244 }else
245 entry--;
246
247 *bufptr++=entry;
248 {
249 int l=book->dec_codelengths[entry];
250 cachesize-=l;
251 cache>>=l;
252 }
253 }
254
255 adr=(unsigned long)b->headptr;
256 bit-=(adr&3)*8+cachesize;
257 b->headend-=(bit/8);
258 b->headptr+=bit/8;
259 b->headbit=bit%8;
260 } else {
261 long r = decode_packed_entry_number(book, b);
262 if (r == -1) return bufptr-buf;
263 *bufptr++ = r;
264 }
265 }
266 return n;
267}
268
269
198/* Decode side is specced and easier, because we don't need to find 270/* Decode side is specced and easier, because we don't need to find
199 matches using different criteria; we simply read and map. There are 271 matches using different criteria; we simply read and map. There are
200 two things we need to do 'depending': 272 two things we need to do 'depending':
@@ -310,17 +382,20 @@ long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a,
310long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, 382long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,
311 long offset,int ch, 383 long offset,int ch,
312 oggpack_buffer *b,int n,int point){ 384 oggpack_buffer *b,int n,int point){
313 long i,j,entry; 385 long i,j,k,chunk,read;
314 int chptr=0; 386 int chptr=0;
315 int shift=point-book->binarypoint; 387 int shift=point-book->binarypoint;
316 388 long entries[32];
389
317 if(shift>=0){ 390 if(shift>=0){
318 391
319 for(i=offset;i<offset+n;){ 392 for(i=offset;i<offset+n;){
320 entry = decode_packed_entry_number(book,b); 393 chunk=32;
321 if(entry==-1)return(-1); 394 if (chunk*book->dim>(offset+n-i)*ch)
322 { 395 chunk=((offset+n-i)*ch+book->dim-1)/book->dim;
323 const ogg_int32_t *t = book->valuelist+entry*book->dim; 396 read = decode_packed_block(book,b,entries,chunk);
397 for(k=0;k<read;k++){
398 const ogg_int32_t *t = book->valuelist+entries[k]*book->dim;
324 for (j=0;j<book->dim;j++){ 399 for (j=0;j<book->dim;j++){
325 a[chptr++][i]+=t[j]>>shift; 400 a[chptr++][i]+=t[j]>>shift;
326 if(chptr==ch){ 401 if(chptr==ch){
@@ -329,14 +404,17 @@ long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,
329 } 404 }
330 } 405 }
331 } 406 }
407 if (read<chunk)return-1;
332 } 408 }
333 }else{ 409 }else{
334 shift = -shift; 410 shift = -shift;
335 for(i=offset;i<offset+n;){ 411 for(i=offset;i<offset+n;){
336 entry = decode_packed_entry_number(book,b); 412 chunk=32;
337 if(entry==-1)return(-1); 413 if (chunk*book->dim>(offset+n-i)*ch)
338 { 414 chunk=((offset+n-i)*ch+book->dim-1)/book->dim;
339 const ogg_int32_t *t = book->valuelist+entry*book->dim; 415 read = decode_packed_block(book,b,entries,chunk);
416 for(k=0;k<read;k++){
417 const ogg_int32_t *t = book->valuelist+entries[k]*book->dim;
340 for (j=0;j<book->dim;j++){ 418 for (j=0;j<book->dim;j++){
341 a[chptr++][i]+=t[j]<<shift; 419 a[chptr++][i]+=t[j]<<shift;
342 if(chptr==ch){ 420 if(chptr==ch){
@@ -345,6 +423,7 @@ long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,
345 } 423 }
346 } 424 }
347 } 425 }
426 if (read<chunk)return-1;
348 } 427 }
349 } 428 }
350 return(0); 429 return(0);
diff --git a/apps/codecs/Tremor/misc.h b/apps/codecs/Tremor/misc.h
index a6eb0fa04a..7d8b846381 100644
--- a/apps/codecs/Tremor/misc.h
+++ b/apps/codecs/Tremor/misc.h
@@ -275,6 +275,16 @@ static inline ogg_int32_t VFLOAT_ADD(ogg_int32_t a,ogg_int32_t ap,
275 return(a); 275 return(a);
276} 276}
277 277
278#ifdef __GNUC__
279#if __GNUC__ >= 3
280#define EXPECT(a, b) __builtin_expect((a), (b))
281#else
282#define EXPECT(a, b) (a)
283#endif
284#else
285#define EXPECT(a, b) (a)
286#endif
287
278#endif 288#endif
279 289
280 290