diff options
Diffstat (limited to 'apps/codecs')
-rw-r--r-- | apps/codecs/Tremor/codebook.c | 103 | ||||
-rw-r--r-- | apps/codecs/Tremor/misc.h | 10 |
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 | ||
198 | static 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, | |||
310 | long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, | 382 | long 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 | ||