summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/codecs/libtremor/codebook.c46
1 files changed, 21 insertions, 25 deletions
diff --git a/apps/codecs/libtremor/codebook.c b/apps/codecs/libtremor/codebook.c
index c938f2f73d..772a81c7f9 100644
--- a/apps/codecs/libtremor/codebook.c
+++ b/apps/codecs/libtremor/codebook.c
@@ -215,6 +215,20 @@ static inline ogg_uint32_t bitreverse(register ogg_uint32_t x)
215 return ret; 215 return ret;
216} 216}
217 217
218static inline long bisect_codelist(long lo, long hi, ogg_uint32_t cache,
219 const ogg_uint32_t *codelist)
220{
221 ogg_uint32_t testword=bitreverse(cache);
222 long p;
223 while(LIKELY(p = (hi-lo) >> 1) > 0){
224 if(codelist[lo+p] > testword)
225 hi -= p;
226 else
227 lo += p;
228 }
229 return lo;
230}
231
218STIN long decode_packed_entry_number(codebook *book, 232STIN long decode_packed_entry_number(codebook *book,
219 oggpack_buffer *b){ 233 oggpack_buffer *b){
220 int read=book->dec_maxlength; 234 int read=book->dec_maxlength;
@@ -222,8 +236,8 @@ STIN long decode_packed_entry_number(codebook *book,
222 long lok = oggpack_look(b,book->dec_firsttablen); 236 long lok = oggpack_look(b,book->dec_firsttablen);
223 237
224 if (LIKELY(lok >= 0)) { 238 if (LIKELY(lok >= 0)) {
225 long entry = book->dec_firsttable[lok]; 239 ogg_int32_t entry = book->dec_firsttable[lok];
226 if(UNLIKELY(entry&0x80000000UL)){ 240 if(UNLIKELY(entry < 0)){
227 lo=(entry>>15)&0x7fff; 241 lo=(entry>>15)&0x7fff;
228 hi=book->used_entries-(entry&0x7fff); 242 hi=book->used_entries-(entry&0x7fff);
229 }else{ 243 }else{
@@ -247,14 +261,7 @@ STIN long decode_packed_entry_number(codebook *book,
247 261
248 /* bisect search for the codeword in the ordered list */ 262 /* bisect search for the codeword in the ordered list */
249 { 263 {
250 ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok); 264 lo = bisect_codelist(lo, hi, lok, book->codelist);
251
252 while(hi-lo>1){
253 long p=(hi-lo)>>1;
254 long test=book->codelist[lo+p]>testword;
255 lo+=p&(test-1);
256 hi-=p&(-test);
257 }
258 265
259 if(book->dec_codelengths[lo]<=read){ 266 if(book->dec_codelengths[lo]<=read){
260 oggpack_adv(b, book->dec_codelengths[lo]); 267 oggpack_adv(b, book->dec_codelengths[lo]);
@@ -284,7 +291,6 @@ static long decode_packed_block(codebook *book, oggpack_buffer *b,
284 ptr = (ogg_uint32_t *)(adr&~3); 291 ptr = (ogg_uint32_t *)(adr&~3);
285 bitend = ((adr&3)+b->headend)*8; 292 bitend = ((adr&3)+b->headend)*8;
286 while (bufptr<bufend){ 293 while (bufptr<bufend){
287 long entry, lo, hi;
288 if (UNLIKELY(cachesize<book->dec_maxlength)) { 294 if (UNLIKELY(cachesize<book->dec_maxlength)) {
289 if (bit-cachesize+32>=bitend) 295 if (bit-cachesize+32>=bitend)
290 break; 296 break;
@@ -296,20 +302,10 @@ static long decode_packed_block(codebook *book, oggpack_buffer *b,
296 bit+=32; 302 bit+=32;
297 } 303 }
298 304
299 entry=book->dec_firsttable[cache&((1<<book->dec_firsttablen)-1)]; 305 ogg_int32_t entry = book->dec_firsttable[cache&((1<<book->dec_firsttablen)-1)];
300 if(UNLIKELY(entry&0x80000000UL)){ 306 if(UNLIKELY(entry < 0)){
301 lo=(entry>>15)&0x7fff; 307 const long lo = (entry>>15)&0x7fff, hi = book->used_entries-(entry&0x7fff);
302 hi=book->used_entries-(entry&0x7fff); 308 entry = bisect_codelist(lo, hi, cache, book->codelist);
303 ogg_uint32_t testword=bitreverse((ogg_uint32_t)cache);
304
305 while(LIKELY(hi-lo>1)){
306 long p=(hi-lo)>>1;
307 if (book->codelist[lo+p]>testword)
308 hi-=p;
309 else
310 lo+=p;
311 }
312 entry=lo;
313 }else 309 }else
314 entry--; 310 entry--;
315 311