diff options
author | Magnus Holmgren <magnushol@gmail.com> | 2007-07-01 17:58:49 +0000 |
---|---|---|
committer | Magnus Holmgren <magnushol@gmail.com> | 2007-07-01 17:58:49 +0000 |
commit | 932b20ec622ad743fc9dd9a523f7cbe3a7c0e04d (patch) | |
tree | ef0ec3c681386fa376c5902bd165d1372ba8a0e8 | |
parent | 9af42897706548a400a8444066b6ee4900c284f4 (diff) | |
download | rockbox-932b20ec622ad743fc9dd9a523f7cbe3a7c0e04d.tar.gz rockbox-932b20ec622ad743fc9dd9a523f7cbe3a7c0e04d.zip |
Vorbis: Apply various bugfixes from upstream Tremor.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13756 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/codecs/Tremor/codebook.c | 230 | ||||
-rw-r--r-- | apps/codecs/Tremor/floor1.c | 10 | ||||
-rw-r--r-- | apps/codecs/Tremor/framing.c | 10 | ||||
-rw-r--r-- | apps/codecs/Tremor/info.c | 11 | ||||
-rw-r--r-- | apps/codecs/Tremor/res012.c | 147 | ||||
-rw-r--r-- | apps/codecs/Tremor/sharedbook.c | 140 |
6 files changed, 289 insertions, 259 deletions
diff --git a/apps/codecs/Tremor/codebook.c b/apps/codecs/Tremor/codebook.c index cad4e8141f..1287a95011 100644 --- a/apps/codecs/Tremor/codebook.c +++ b/apps/codecs/Tremor/codebook.c | |||
@@ -148,7 +148,7 @@ static inline ogg_uint32_t bitreverse(register ogg_uint32_t x){ | |||
148 | return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa); | 148 | return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa); |
149 | } | 149 | } |
150 | 150 | ||
151 | static inline long decode_packed_entry_number(codebook *book, | 151 | STIN long decode_packed_entry_number(codebook *book, |
152 | oggpack_buffer *b){ | 152 | oggpack_buffer *b){ |
153 | int read=book->dec_maxlength; | 153 | int read=book->dec_maxlength; |
154 | long lo,hi; | 154 | long lo,hi; |
@@ -172,7 +172,11 @@ static inline long decode_packed_entry_number(codebook *book, | |||
172 | 172 | ||
173 | while(lok<0 && read>1) | 173 | while(lok<0 && read>1) |
174 | lok = oggpack_look(b, --read); | 174 | lok = oggpack_look(b, --read); |
175 | if(lok<0)return -1; | 175 | |
176 | if(lok<0){ | ||
177 | oggpack_adv(b,1); /* force eop */ | ||
178 | return -1; | ||
179 | } | ||
176 | 180 | ||
177 | /* bisect search for the codeword in the ordered list */ | 181 | /* bisect search for the codeword in the ordered list */ |
178 | { | 182 | { |
@@ -191,7 +195,7 @@ static inline long decode_packed_entry_number(codebook *book, | |||
191 | } | 195 | } |
192 | } | 196 | } |
193 | 197 | ||
194 | oggpack_adv(b, read); | 198 | oggpack_adv(b, read+1); |
195 | return(-1); | 199 | return(-1); |
196 | } | 200 | } |
197 | 201 | ||
@@ -283,67 +287,73 @@ static inline long decode_packed_block(codebook *book, oggpack_buffer *b, | |||
283 | 287 | ||
284 | /* returns the [original, not compacted] entry number or -1 on eof *********/ | 288 | /* returns the [original, not compacted] entry number or -1 on eof *********/ |
285 | long vorbis_book_decode(codebook *book, oggpack_buffer *b){ | 289 | long vorbis_book_decode(codebook *book, oggpack_buffer *b){ |
286 | long packed_entry=decode_packed_entry_number(book,b); | 290 | if(book->used_entries>0){ |
287 | if(packed_entry>=0) | 291 | long packed_entry=decode_packed_entry_number(book,b); |
288 | return(book->dec_index[packed_entry]); | 292 | if(packed_entry>=0) |
289 | 293 | return(book->dec_index[packed_entry]); | |
294 | } | ||
295 | |||
290 | /* if there's no dec_index, the codebook unpacking isn't collapsed */ | 296 | /* if there's no dec_index, the codebook unpacking isn't collapsed */ |
291 | return(packed_entry); | 297 | return(-1); |
292 | } | 298 | } |
293 | 299 | ||
294 | /* returns 0 on OK or -1 on eof *************************************/ | 300 | /* returns 0 on OK or -1 on eof *************************************/ |
295 | long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, | 301 | long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, |
296 | oggpack_buffer *b,int n,int point){ | 302 | oggpack_buffer *b,int n,int point){ |
297 | int step=n/book->dim; | 303 | if(book->used_entries>0){ |
298 | long *entry = (long *)alloca(sizeof(*entry)*step); | 304 | int step=n/book->dim; |
299 | ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step); | 305 | long *entry = (long *)alloca(sizeof(*entry)*step); |
300 | int i,j,o; | 306 | ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step); |
301 | int shift=point-book->binarypoint; | 307 | int i,j,o; |
302 | 308 | int shift=point-book->binarypoint; | |
303 | if(shift>=0){ | 309 | |
304 | for (i = 0; i < step; i++) { | 310 | if(shift>=0){ |
305 | entry[i]=decode_packed_entry_number(book,b); | 311 | for (i = 0; i < step; i++) { |
306 | if(entry[i]==-1)return(-1); | 312 | entry[i]=decode_packed_entry_number(book,b); |
307 | t[i] = book->valuelist+entry[i]*book->dim; | 313 | if(entry[i]==-1)return(-1); |
308 | } | 314 | t[i] = book->valuelist+entry[i]*book->dim; |
309 | for(i=0,o=0;i<book->dim;i++,o+=step) | 315 | } |
310 | for (j=0;j<step;j++) | 316 | for(i=0,o=0;i<book->dim;i++,o+=step) |
311 | a[o+j]+=t[j][i]>>shift; | 317 | for (j=0;j<step;j++) |
312 | }else{ | 318 | a[o+j]+=t[j][i]>>shift; |
313 | for (i = 0; i < step; i++) { | 319 | }else{ |
314 | entry[i]=decode_packed_entry_number(book,b); | 320 | for (i = 0; i < step; i++) { |
315 | if(entry[i]==-1)return(-1); | 321 | entry[i]=decode_packed_entry_number(book,b); |
316 | t[i] = book->valuelist+entry[i]*book->dim; | 322 | if(entry[i]==-1)return(-1); |
323 | t[i] = book->valuelist+entry[i]*book->dim; | ||
324 | } | ||
325 | for(i=0,o=0;i<book->dim;i++,o+=step) | ||
326 | for (j=0;j<step;j++) | ||
327 | a[o+j]+=t[j][i]<<-shift; | ||
317 | } | 328 | } |
318 | for(i=0,o=0;i<book->dim;i++,o+=step) | ||
319 | for (j=0;j<step;j++) | ||
320 | a[o+j]+=t[j][i]<<-shift; | ||
321 | } | 329 | } |
322 | return(0); | 330 | return(0); |
323 | } | 331 | } |
324 | 332 | ||
325 | long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a, | 333 | long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a, |
326 | oggpack_buffer *b,int n,int point){ | 334 | oggpack_buffer *b,int n,int point){ |
327 | int i,j,entry; | 335 | if(book->used_entries>0){ |
328 | ogg_int32_t *t; | 336 | int i,j,entry; |
329 | int shift=point-book->binarypoint; | 337 | ogg_int32_t *t; |
330 | 338 | int shift=point-book->binarypoint; | |
331 | if(shift>=0){ | 339 | |
332 | for(i=0;i<n;){ | 340 | if(shift>=0){ |
333 | entry = decode_packed_entry_number(book,b); | 341 | for(i=0;i<n;){ |
334 | if(entry==-1)return(-1); | 342 | entry = decode_packed_entry_number(book,b); |
335 | t = book->valuelist+entry*book->dim; | 343 | if(entry==-1)return(-1); |
336 | for (j=0;j<book->dim;) | 344 | t = book->valuelist+entry*book->dim; |
337 | a[i++]+=t[j++]>>shift; | 345 | for (j=0;j<book->dim;) |
338 | } | 346 | a[i++]+=t[j++]>>shift; |
339 | }else{ | 347 | } |
340 | shift = -shift; | 348 | }else{ |
341 | for(i=0;i<n;){ | 349 | shift = -shift; |
342 | entry = decode_packed_entry_number(book,b); | 350 | for(i=0;i<n;){ |
343 | if(entry==-1)return(-1); | 351 | entry = decode_packed_entry_number(book,b); |
344 | t = book->valuelist+entry*book->dim; | 352 | if(entry==-1)return(-1); |
345 | for (j=0;j<book->dim;) | 353 | t = book->valuelist+entry*book->dim; |
346 | a[i++]+=t[j++]<<shift; | 354 | for (j=0;j<book->dim;) |
355 | a[i++]+=t[j++]<<shift; | ||
356 | } | ||
347 | } | 357 | } |
348 | } | 358 | } |
349 | return(0); | 359 | return(0); |
@@ -351,28 +361,38 @@ long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a, | |||
351 | 361 | ||
352 | long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, | 362 | long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, |
353 | oggpack_buffer *b,int n,int point){ | 363 | oggpack_buffer *b,int n,int point){ |
354 | int i,j,entry; | 364 | if(book->used_entries>0){ |
355 | ogg_int32_t *t; | 365 | int i,j,entry; |
356 | int shift=point-book->binarypoint; | 366 | ogg_int32_t *t; |
357 | 367 | int shift=point-book->binarypoint; | |
358 | if(shift>=0){ | 368 | |
359 | 369 | if(shift>=0){ | |
360 | for(i=0;i<n;){ | 370 | |
361 | entry = decode_packed_entry_number(book,b); | 371 | for(i=0;i<n;){ |
362 | if(entry==-1)return(-1); | 372 | entry = decode_packed_entry_number(book,b); |
363 | t = book->valuelist+entry*book->dim; | 373 | if(entry==-1)return(-1); |
364 | for (j=0;j<book->dim;){ | 374 | t = book->valuelist+entry*book->dim; |
365 | a[i++]=t[j++]>>shift; | 375 | for (j=0;j<book->dim;){ |
376 | a[i++]=t[j++]>>shift; | ||
377 | } | ||
378 | } | ||
379 | }else{ | ||
380 | shift = -shift; | ||
381 | for(i=0;i<n;){ | ||
382 | entry = decode_packed_entry_number(book,b); | ||
383 | if(entry==-1)return(-1); | ||
384 | t = book->valuelist+entry*book->dim; | ||
385 | for (j=0;j<book->dim;){ | ||
386 | a[i++]=t[j++]<<shift; | ||
387 | } | ||
366 | } | 388 | } |
367 | } | 389 | } |
368 | }else{ | 390 | }else{ |
369 | shift = -shift; | 391 | |
392 | int i,j; | ||
370 | for(i=0;i<n;){ | 393 | for(i=0;i<n;){ |
371 | entry = decode_packed_entry_number(book,b); | ||
372 | if(entry==-1)return(-1); | ||
373 | t = book->valuelist+entry*book->dim; | ||
374 | for (j=0;j<book->dim;){ | 394 | for (j=0;j<book->dim;){ |
375 | a[i++]=t[j++]<<shift; | 395 | a[i++]=0; |
376 | } | 396 | } |
377 | } | 397 | } |
378 | } | 398 | } |
@@ -382,48 +402,50 @@ long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, | |||
382 | long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, | 402 | long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, |
383 | long offset,int ch, | 403 | long offset,int ch, |
384 | oggpack_buffer *b,int n,int point){ | 404 | oggpack_buffer *b,int n,int point){ |
385 | long i,j,k,chunk,read; | 405 | if(book->used_entries>0){ |
386 | int chptr=0; | 406 | long i,j,k,chunk,read; |
387 | int shift=point-book->binarypoint; | 407 | int chptr=0; |
388 | long entries[32]; | 408 | int shift=point-book->binarypoint; |
409 | long entries[32]; | ||
389 | 410 | ||
390 | if(shift>=0){ | 411 | if(shift>=0){ |
391 | 412 | ||
392 | for(i=offset;i<offset+n;){ | 413 | for(i=offset;i<offset+n;){ |
393 | chunk=32; | 414 | chunk=32; |
394 | if (chunk*book->dim>(offset+n-i)*ch) | 415 | if (chunk*book->dim>(offset+n-i)*ch) |
395 | chunk=((offset+n-i)*ch+book->dim-1)/book->dim; | 416 | chunk=((offset+n-i)*ch+book->dim-1)/book->dim; |
396 | read = decode_packed_block(book,b,entries,chunk); | 417 | read = decode_packed_block(book,b,entries,chunk); |
397 | for(k=0;k<read;k++){ | 418 | for(k=0;k<read;k++){ |
398 | const ogg_int32_t *t = book->valuelist+entries[k]*book->dim; | 419 | const ogg_int32_t *t = book->valuelist+entries[k]*book->dim; |
399 | for (j=0;j<book->dim;j++){ | 420 | for (j=0;j<book->dim;j++){ |
400 | a[chptr++][i]+=t[j]>>shift; | 421 | a[chptr++][i]+=t[j]>>shift; |
401 | if(chptr==ch){ | 422 | if(chptr==ch){ |
402 | chptr=0; | 423 | chptr=0; |
403 | i++; | 424 | i++; |
425 | } | ||
404 | } | 426 | } |
405 | } | 427 | } |
428 | if (read<chunk)return-1; | ||
406 | } | 429 | } |
407 | if (read<chunk)return-1; | 430 | }else{ |
408 | } | 431 | shift = -shift; |
409 | }else{ | 432 | for(i=offset;i<offset+n;){ |
410 | shift = -shift; | 433 | chunk=32; |
411 | for(i=offset;i<offset+n;){ | 434 | if (chunk*book->dim>(offset+n-i)*ch) |
412 | chunk=32; | 435 | chunk=((offset+n-i)*ch+book->dim-1)/book->dim; |
413 | if (chunk*book->dim>(offset+n-i)*ch) | 436 | read = decode_packed_block(book,b,entries,chunk); |
414 | chunk=((offset+n-i)*ch+book->dim-1)/book->dim; | 437 | for(k=0;k<read;k++){ |
415 | read = decode_packed_block(book,b,entries,chunk); | 438 | const ogg_int32_t *t = book->valuelist+entries[k]*book->dim; |
416 | for(k=0;k<read;k++){ | 439 | for (j=0;j<book->dim;j++){ |
417 | const ogg_int32_t *t = book->valuelist+entries[k]*book->dim; | 440 | a[chptr++][i]+=t[j]<<shift; |
418 | for (j=0;j<book->dim;j++){ | 441 | if(chptr==ch){ |
419 | a[chptr++][i]+=t[j]<<shift; | 442 | chptr=0; |
420 | if(chptr==ch){ | 443 | i++; |
421 | chptr=0; | 444 | } |
422 | i++; | ||
423 | } | 445 | } |
424 | } | 446 | } |
447 | if (read<chunk)return-1; | ||
425 | } | 448 | } |
426 | if (read<chunk)return-1; | ||
427 | } | 449 | } |
428 | } | 450 | } |
429 | return(0); | 451 | return(0); |
diff --git a/apps/codecs/Tremor/floor1.c b/apps/codecs/Tremor/floor1.c index 5f43d563f0..4ee58c18ca 100644 --- a/apps/codecs/Tremor/floor1.c +++ b/apps/codecs/Tremor/floor1.c | |||
@@ -286,7 +286,7 @@ static const ogg_int32_t FLOOR_fromdB_LOOKUP[256] ICONST_ATTR = { | |||
286 | XdB(0x69f80e9a), XdB(0x70dafda8), XdB(0x78307d76), XdB(0x7fffffff), | 286 | XdB(0x69f80e9a), XdB(0x70dafda8), XdB(0x78307d76), XdB(0x7fffffff), |
287 | }; | 287 | }; |
288 | 288 | ||
289 | static void render_line(int x0,register int x1,int y0,int y1,ogg_int32_t *d){ | 289 | static void render_line(int n, int x0,register int x1,int y0,int y1,ogg_int32_t *d){ |
290 | int dy=y1-y0; | 290 | int dy=y1-y0; |
291 | register int x=x0; | 291 | register int x=x0; |
292 | register int y=y0; | 292 | register int y=y0; |
@@ -296,11 +296,13 @@ static void render_line(int x0,register int x1,int y0,int y1,ogg_int32_t *d){ | |||
296 | register int sy=(dy<0?base-1:base+1); | 296 | register int sy=(dy<0?base-1:base+1); |
297 | int err=0; | 297 | int err=0; |
298 | 298 | ||
299 | if(n>x1)n=x1; | ||
299 | ady-=abs(base*adx); | 300 | ady-=abs(base*adx); |
300 | 301 | ||
301 | d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]); | 302 | if(x<n) |
303 | d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]); | ||
302 | 304 | ||
303 | while(++x<x1){ | 305 | while(++x<n){ |
304 | err=err+ady; | 306 | err=err+ady; |
305 | if(err>=adx){ | 307 | if(err>=adx){ |
306 | err-=adx; | 308 | err-=adx; |
@@ -424,7 +426,7 @@ static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo, | |||
424 | hy*=info->mult; | 426 | hy*=info->mult; |
425 | hx=info->postlist[current]; | 427 | hx=info->postlist[current]; |
426 | 428 | ||
427 | render_line(lx,hx,ly,hy,out); | 429 | render_line(n,lx,hx,ly,hy,out); |
428 | 430 | ||
429 | lx=hx; | 431 | lx=hx; |
430 | ly=hy; | 432 | ly=hy; |
diff --git a/apps/codecs/Tremor/framing.c b/apps/codecs/Tremor/framing.c index e444514901..1cd5c1eb50 100644 --- a/apps/codecs/Tremor/framing.c +++ b/apps/codecs/Tremor/framing.c | |||
@@ -53,11 +53,6 @@ static void _ogg_buffer_destroy(ogg_buffer_state *bs){ | |||
53 | bt=bs->unused_buffers; | 53 | bt=bs->unused_buffers; |
54 | rt=bs->unused_references; | 54 | rt=bs->unused_references; |
55 | 55 | ||
56 | if(!bs->outstanding){ | ||
57 | _ogg_free(bs); | ||
58 | return; | ||
59 | } | ||
60 | |||
61 | while(bt){ | 56 | while(bt){ |
62 | ogg_buffer *b=bt; | 57 | ogg_buffer *b=bt; |
63 | bt=b->ptr.next; | 58 | bt=b->ptr.next; |
@@ -71,6 +66,10 @@ static void _ogg_buffer_destroy(ogg_buffer_state *bs){ | |||
71 | _ogg_free(r); | 66 | _ogg_free(r); |
72 | } | 67 | } |
73 | bs->unused_references=0; | 68 | bs->unused_references=0; |
69 | |||
70 | if(!bs->outstanding) | ||
71 | _ogg_free(bs); | ||
72 | |||
74 | } | 73 | } |
75 | } | 74 | } |
76 | 75 | ||
@@ -836,6 +835,7 @@ int ogg_stream_destroy(ogg_stream_state *os){ | |||
836 | ogg_buffer_release(os->header_tail); | 835 | ogg_buffer_release(os->header_tail); |
837 | ogg_buffer_release(os->body_tail); | 836 | ogg_buffer_release(os->body_tail); |
838 | memset(os,0,sizeof(*os)); | 837 | memset(os,0,sizeof(*os)); |
838 | _ogg_free(os); | ||
839 | } | 839 | } |
840 | return OGG_SUCCESS; | 840 | return OGG_SUCCESS; |
841 | } | 841 | } |
diff --git a/apps/codecs/Tremor/info.c b/apps/codecs/Tremor/info.c index e750c8b647..c8d9651bd4 100644 --- a/apps/codecs/Tremor/info.c +++ b/apps/codecs/Tremor/info.c | |||
@@ -97,8 +97,8 @@ void vorbis_comment_clear(vorbis_comment *vc){ | |||
97 | if(vc->user_comments)_ogg_free(vc->user_comments); | 97 | if(vc->user_comments)_ogg_free(vc->user_comments); |
98 | if(vc->comment_lengths)_ogg_free(vc->comment_lengths); | 98 | if(vc->comment_lengths)_ogg_free(vc->comment_lengths); |
99 | if(vc->vendor)_ogg_free(vc->vendor); | 99 | if(vc->vendor)_ogg_free(vc->vendor); |
100 | memset(vc,0,sizeof(*vc)); | ||
100 | } | 101 | } |
101 | memset(vc,0,sizeof(*vc)); | ||
102 | } | 102 | } |
103 | 103 | ||
104 | /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. | 104 | /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. |
@@ -124,13 +124,16 @@ void vorbis_info_clear(vorbis_info *vi){ | |||
124 | if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); | 124 | if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); |
125 | 125 | ||
126 | for(i=0;i<ci->maps;i++) /* unpack does the range checking */ | 126 | for(i=0;i<ci->maps;i++) /* unpack does the range checking */ |
127 | _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); | 127 | if(ci->map_param[i]) |
128 | _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); | ||
128 | 129 | ||
129 | for(i=0;i<ci->floors;i++) /* unpack does the range checking */ | 130 | for(i=0;i<ci->floors;i++) /* unpack does the range checking */ |
130 | _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); | 131 | if(ci->floor_param[i]) |
132 | _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); | ||
131 | 133 | ||
132 | for(i=0;i<ci->residues;i++) /* unpack does the range checking */ | 134 | for(i=0;i<ci->residues;i++) /* unpack does the range checking */ |
133 | _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); | 135 | if(ci->residue_param[i]) |
136 | _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); | ||
134 | 137 | ||
135 | for(i=0;i<ci->books;i++){ | 138 | for(i=0;i<ci->books;i++){ |
136 | if(ci->book_param[i]){ | 139 | if(ci->book_param[i]){ |
diff --git a/apps/codecs/Tremor/res012.c b/apps/codecs/Tremor/res012.c index fe0cf2e50a..2104c068e6 100644 --- a/apps/codecs/Tremor/res012.c +++ b/apps/codecs/Tremor/res012.c | |||
@@ -187,45 +187,48 @@ static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl, | |||
187 | /* move all this setup out later */ | 187 | /* move all this setup out later */ |
188 | int samples_per_partition=info->grouping; | 188 | int samples_per_partition=info->grouping; |
189 | int partitions_per_word=look->phrasebook->dim; | 189 | int partitions_per_word=look->phrasebook->dim; |
190 | int n=info->end-info->begin; | 190 | int max=vb->pcmend>>1; |
191 | int end=(info->end<max?info->end:max); | ||
192 | int n=end-info->begin; | ||
193 | |||
194 | if(n>0){ | ||
195 | int partvals=n/samples_per_partition; | ||
196 | int partwords=(partvals+partitions_per_word-1)/partitions_per_word; | ||
197 | int ***partword=(int ***)alloca(ch*sizeof(*partword)); | ||
191 | 198 | ||
192 | int partvals=n/samples_per_partition; | 199 | for(j=0;j<ch;j++) |
193 | int partwords=(partvals+partitions_per_word-1)/partitions_per_word; | 200 | partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j])); |
194 | int ***partword=(int ***)alloca(ch*sizeof(*partword)); | 201 | |
195 | 202 | for(s=0;s<look->stages;s++){ | |
196 | for(j=0;j<ch;j++) | 203 | |
197 | partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j])); | 204 | /* each loop decodes on partition codeword containing |
198 | 205 | partitions_pre_word partitions */ | |
199 | for(s=0;s<look->stages;s++){ | 206 | for(i=0,l=0;i<partvals;l++){ |
200 | 207 | if(s==0){ | |
201 | /* each loop decodes on partition codeword containing | 208 | /* fetch the partition word for each channel */ |
202 | partitions_pre_word partitions */ | 209 | for(j=0;j<ch;j++){ |
203 | for(i=0,l=0;i<partvals;l++){ | 210 | int temp=vorbis_book_decode(look->phrasebook,&vb->opb); |
204 | if(s==0){ | 211 | if(temp==-1)goto eopbreak; |
205 | /* fetch the partition word for each channel */ | 212 | partword[j][l]=look->decodemap[temp]; |
206 | for(j=0;j<ch;j++){ | 213 | if(partword[j][l]==NULL)goto errout; |
207 | int temp=vorbis_book_decode(look->phrasebook,&vb->opb); | 214 | } |
208 | if(temp==-1)goto eopbreak; | ||
209 | partword[j][l]=look->decodemap[temp]; | ||
210 | if(partword[j][l]==NULL)goto errout; | ||
211 | } | 215 | } |
212 | } | 216 | |
213 | 217 | /* now we decode residual values for the partitions */ | |
214 | /* now we decode residual values for the partitions */ | 218 | for(k=0;k<partitions_per_word && i<partvals;k++,i++) |
215 | for(k=0;k<partitions_per_word && i<partvals;k++,i++) | 219 | for(j=0;j<ch;j++){ |
216 | for(j=0;j<ch;j++){ | 220 | long offset=info->begin+i*samples_per_partition; |
217 | long offset=info->begin+i*samples_per_partition; | 221 | if(info->secondstages[partword[j][l][k]]&(1<<s)){ |
218 | if(info->secondstages[partword[j][l][k]]&(1<<s)){ | 222 | codebook *stagebook=look->partbooks[partword[j][l][k]][s]; |
219 | codebook *stagebook=look->partbooks[partword[j][l][k]][s]; | 223 | if(stagebook){ |
220 | if(stagebook){ | 224 | if(decodepart(stagebook,in[j]+offset,&vb->opb, |
221 | if(decodepart(stagebook,in[j]+offset,&vb->opb, | 225 | samples_per_partition,-8)==-1)goto eopbreak; |
222 | samples_per_partition,-8)==-1)goto eopbreak; | 226 | } |
223 | } | 227 | } |
224 | } | 228 | } |
225 | } | 229 | } |
226 | } | 230 | } |
227 | } | 231 | } |
228 | |||
229 | errout: | 232 | errout: |
230 | eopbreak: | 233 | eopbreak: |
231 | return(0); | 234 | return(0); |
@@ -255,8 +258,6 @@ int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl, | |||
255 | return(0); | 258 | return(0); |
256 | } | 259 | } |
257 | 260 | ||
258 | |||
259 | |||
260 | /* duplicate code here as speed is somewhat more important */ | 261 | /* duplicate code here as speed is somewhat more important */ |
261 | int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl, | 262 | int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl, |
262 | ogg_int32_t **in,int *nonzero,int ch) | 263 | ogg_int32_t **in,int *nonzero,int ch) |
@@ -270,44 +271,48 @@ int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl, | |||
270 | /* move all this setup out later */ | 271 | /* move all this setup out later */ |
271 | int samples_per_partition=info->grouping; | 272 | int samples_per_partition=info->grouping; |
272 | int partitions_per_word=look->phrasebook->dim; | 273 | int partitions_per_word=look->phrasebook->dim; |
273 | int n=info->end-info->begin; | 274 | int max=(vb->pcmend*ch)>>1; |
274 | 275 | int end=(info->end<max?info->end:max); | |
275 | int partvals=n/samples_per_partition; | 276 | int n=end-info->begin; |
276 | int partwords=(partvals+partitions_per_word-1)/partitions_per_word; | 277 | |
277 | int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword)); | 278 | if(n>0){ |
278 | int beginoff=info->begin/ch; | 279 | |
279 | 280 | int partvals=n/samples_per_partition; | |
280 | for(i=0;i<ch;i++)if(nonzero[i])break; | 281 | int partwords=(partvals+partitions_per_word-1)/partitions_per_word; |
281 | if(i==ch)return(0); /* no nonzero vectors */ | 282 | int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword)); |
282 | 283 | int beginoff=info->begin/ch; | |
283 | samples_per_partition/=ch; | 284 | |
284 | 285 | for(i=0;i<ch;i++)if(nonzero[i])break; | |
285 | for(s=0;s<look->stages;s++){ | 286 | if(i==ch)return(0); /* no nonzero vectors */ |
286 | for(i=0,l=0;i<partvals;l++){ | 287 | |
287 | 288 | samples_per_partition/=ch; | |
288 | if(s==0){ | 289 | |
289 | /* fetch the partition word */ | 290 | for(s=0;s<look->stages;s++){ |
290 | int temp=vorbis_book_decode(look->phrasebook,&vb->opb); | 291 | for(i=0,l=0;i<partvals;l++){ |
291 | if(temp==-1)goto eopbreak; | 292 | |
292 | partword[l]=look->decodemap[temp]; | 293 | if(s==0){ |
293 | if(partword[l]==NULL)goto errout; | 294 | /* fetch the partition word */ |
294 | } | 295 | int temp=vorbis_book_decode(look->phrasebook,&vb->opb); |
295 | 296 | if(temp==-1)goto eopbreak; | |
296 | /* now we decode residual values for the partitions */ | 297 | partword[l]=look->decodemap[temp]; |
297 | for(k=0;k<partitions_per_word && i<partvals;k++,i++) | 298 | if(partword[l]==NULL)goto errout; |
298 | if(info->secondstages[partword[l][k]]&(1<<s)){ | ||
299 | codebook *stagebook=look->partbooks[partword[l][k]][s]; | ||
300 | if(stagebook){ | ||
301 | if(vorbis_book_decodevv_add(stagebook,in, | ||
302 | i*samples_per_partition+beginoff,ch, | ||
303 | &vb->opb, | ||
304 | samples_per_partition,-8)==-1) | ||
305 | goto eopbreak; | ||
306 | } | ||
307 | } | 299 | } |
308 | } | 300 | |
301 | /* now we decode residual values for the partitions */ | ||
302 | for(k=0;k<partitions_per_word && i<partvals;k++,i++) | ||
303 | if(info->secondstages[partword[l][k]]&(1<<s)){ | ||
304 | codebook *stagebook=look->partbooks[partword[l][k]][s]; | ||
305 | if(stagebook){ | ||
306 | if(vorbis_book_decodevv_add(stagebook,in, | ||
307 | i*samples_per_partition+beginoff,ch, | ||
308 | &vb->opb, | ||
309 | samples_per_partition,-8)==-1) | ||
310 | goto eopbreak; | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | } | ||
309 | } | 315 | } |
310 | |||
311 | errout: | 316 | errout: |
312 | eopbreak: | 317 | eopbreak: |
313 | return(0); | 318 | return(0); |
diff --git a/apps/codecs/Tremor/sharedbook.c b/apps/codecs/Tremor/sharedbook.c index c58ae55984..6d1226e044 100644 --- a/apps/codecs/Tremor/sharedbook.c +++ b/apps/codecs/Tremor/sharedbook.c | |||
@@ -337,24 +337,21 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ | |||
337 | c->used_entries=n; | 337 | c->used_entries=n; |
338 | c->dim=s->dim; | 338 | c->dim=s->dim; |
339 | 339 | ||
340 | c->q_min=s->q_min; | 340 | if(n>0){ |
341 | c->q_delta=s->q_delta; | 341 | /* two different remappings go on here. |
342 | 342 | ||
343 | /* two different remappings go on here. | 343 | First, we collapse the likely sparse codebook down only to |
344 | 344 | actually represented values/words. This collapsing needs to be | |
345 | First, we collapse the likely sparse codebook down only to | 345 | indexed as map-valueless books are used to encode original entry |
346 | actually represented values/words. This collapsing needs to be | 346 | positions as integers. |
347 | indexed as map-valueless books are used to encode original entry | 347 | |
348 | positions as integers. | 348 | Second, we reorder all vectors, including the entry index above, |
349 | 349 | by sorted bitreversed codeword to allow treeless decode. */ | |
350 | Second, we reorder all vectors, including the entry index above, | 350 | |
351 | by sorted bitreversed codeword to allow treeless decode. */ | ||
352 | |||
353 | { | ||
354 | /* perform sort */ | 351 | /* perform sort */ |
355 | ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); | 352 | ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); |
356 | ogg_uint32_t **codep=(ogg_uint32_t **)ogg_tmpmalloc(sizeof(*codep)*n); | 353 | ogg_uint32_t **codep=(ogg_uint32_t **)ogg_tmpmalloc(sizeof(*codep)*n); |
357 | 354 | ||
358 | if(codes==NULL||codep==NULL)goto err_out; | 355 | if(codes==NULL||codep==NULL)goto err_out; |
359 | 356 | ||
360 | for(i=0;i<n;i++){ | 357 | for(i=0;i<n;i++){ |
@@ -375,67 +372,68 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ | |||
375 | for(i=0;i<n;i++) | 372 | for(i=0;i<n;i++) |
376 | c->codelist[sortindex[i]]=codes[i]; | 373 | c->codelist[sortindex[i]]=codes[i]; |
377 | /* _ogg_free(codes); */ | 374 | /* _ogg_free(codes); */ |
378 | } | 375 | |
379 | 376 | ||
380 | 377 | ||
381 | c->valuelist=_book_unquantize(s,n,sortindex,&c->binarypoint); | 378 | c->valuelist=_book_unquantize(s,n,sortindex,&c->binarypoint); |
382 | c->dec_index=(int *)_ogg_malloc(n*sizeof(*c->dec_index)); | 379 | c->dec_index=(int *)_ogg_malloc(n*sizeof(*c->dec_index)); |
383 | 380 | ||
384 | for(n=0,i=0;i<s->entries;i++) | 381 | for(n=0,i=0;i<s->entries;i++) |
385 | if(s->lengthlist[i]>0) | 382 | if(s->lengthlist[i]>0) |
386 | c->dec_index[sortindex[n++]]=i; | 383 | c->dec_index[sortindex[n++]]=i; |
387 | 384 | ||
388 | c->dec_codelengths=(char *)_ogg_malloc(n*sizeof(*c->dec_codelengths)); | 385 | c->dec_codelengths=(char *)_ogg_malloc(n*sizeof(*c->dec_codelengths)); |
389 | for(n=0,i=0;i<s->entries;i++) | 386 | for(n=0,i=0;i<s->entries;i++) |
390 | if(s->lengthlist[i]>0) | 387 | if(s->lengthlist[i]>0) |
391 | c->dec_codelengths[sortindex[n++]]=s->lengthlist[i]; | 388 | c->dec_codelengths[sortindex[n++]]=s->lengthlist[i]; |
392 | 389 | ||
393 | c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */ | 390 | c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */ |
394 | if(c->dec_firsttablen<5)c->dec_firsttablen=5; | 391 | if(c->dec_firsttablen<5)c->dec_firsttablen=5; |
395 | if(c->dec_firsttablen>8)c->dec_firsttablen=8; | 392 | if(c->dec_firsttablen>8)c->dec_firsttablen=8; |
396 | 393 | ||
397 | tabn=1<<c->dec_firsttablen; | 394 | tabn=1<<c->dec_firsttablen; |
398 | c->dec_firsttable=(ogg_uint32_t *)_ogg_calloc(tabn,sizeof(*c->dec_firsttable)); | 395 | c->dec_firsttable=(ogg_uint32_t *)_ogg_calloc(tabn,sizeof(*c->dec_firsttable)); |
399 | c->dec_maxlength=0; | 396 | c->dec_maxlength=0; |
400 | 397 | ||
401 | for(i=0;i<n;i++){ | 398 | for(i=0;i<n;i++){ |
402 | if(c->dec_maxlength<c->dec_codelengths[i]) | 399 | if(c->dec_maxlength<c->dec_codelengths[i]) |
403 | c->dec_maxlength=c->dec_codelengths[i]; | 400 | c->dec_maxlength=c->dec_codelengths[i]; |
404 | if(c->dec_codelengths[i]<=c->dec_firsttablen){ | 401 | if(c->dec_codelengths[i]<=c->dec_firsttablen){ |
405 | ogg_uint32_t orig=bitreverse(c->codelist[i]); | 402 | ogg_uint32_t orig=bitreverse(c->codelist[i]); |
406 | for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++) | 403 | for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++) |
407 | c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1; | 404 | c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1; |
405 | } | ||
408 | } | 406 | } |
409 | } | 407 | |
410 | 408 | /* now fill in 'unused' entries in the firsttable with hi/lo search | |
411 | /* now fill in 'unused' entries in the firsttable with hi/lo search | 409 | hints for the non-direct-hits */ |
412 | hints for the non-direct-hits */ | 410 | { |
413 | { | 411 | ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen); |
414 | ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen); | 412 | long lo=0,hi=0; |
415 | long lo=0,hi=0; | 413 | |
416 | 414 | for(i=0;i<tabn;i++){ | |
417 | for(i=0;i<tabn;i++){ | 415 | ogg_uint32_t word=i<<(32-c->dec_firsttablen); |
418 | ogg_uint32_t word=i<<(32-c->dec_firsttablen); | 416 | if(c->dec_firsttable[bitreverse(word)]==0){ |
419 | if(c->dec_firsttable[bitreverse(word)]==0){ | 417 | while((lo+1)<n && c->codelist[lo+1]<=word)lo++; |
420 | while((lo+1)<n && c->codelist[lo+1]<=word)lo++; | 418 | while( hi<n && word>=(c->codelist[hi]&mask))hi++; |
421 | while( hi<n && word>=(c->codelist[hi]&mask))hi++; | 419 | |
422 | 420 | /* we only actually have 15 bits per hint to play with here. | |
423 | /* we only actually have 15 bits per hint to play with here. | 421 | In order to overflow gracefully (nothing breaks, efficiency |
424 | In order to overflow gracefully (nothing breaks, efficiency | 422 | just drops), encode as the difference from the extremes. */ |
425 | just drops), encode as the difference from the extremes. */ | 423 | { |
426 | { | 424 | unsigned long loval=lo; |
427 | unsigned long loval=lo; | 425 | unsigned long hival=n-hi; |
428 | unsigned long hival=n-hi; | 426 | |
429 | 427 | if(loval>0x7fff)loval=0x7fff; | |
430 | if(loval>0x7fff)loval=0x7fff; | 428 | if(hival>0x7fff)hival=0x7fff; |
431 | if(hival>0x7fff)hival=0x7fff; | 429 | c->dec_firsttable[bitreverse(word)]= |
432 | c->dec_firsttable[bitreverse(word)]= | 430 | 0x80000000UL | (loval<<15) | hival; |
433 | 0x80000000UL | (loval<<15) | hival; | 431 | } |
434 | } | 432 | } |
435 | } | 433 | } |
436 | } | 434 | } |
437 | } | 435 | } |
438 | 436 | ||
439 | ogg_tmpmalloc_free(pos); | 437 | ogg_tmpmalloc_free(pos); |
440 | return(0); | 438 | return(0); |
441 | err_out: | 439 | err_out: |