summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMagnus Holmgren <magnushol@gmail.com>2007-07-01 17:58:49 +0000
committerMagnus Holmgren <magnushol@gmail.com>2007-07-01 17:58:49 +0000
commit932b20ec622ad743fc9dd9a523f7cbe3a7c0e04d (patch)
treeef0ec3c681386fa376c5902bd165d1372ba8a0e8 /apps
parent9af42897706548a400a8444066b6ee4900c284f4 (diff)
downloadrockbox-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
Diffstat (limited to 'apps')
-rw-r--r--apps/codecs/Tremor/codebook.c230
-rw-r--r--apps/codecs/Tremor/floor1.c10
-rw-r--r--apps/codecs/Tremor/framing.c10
-rw-r--r--apps/codecs/Tremor/info.c11
-rw-r--r--apps/codecs/Tremor/res012.c147
-rw-r--r--apps/codecs/Tremor/sharedbook.c140
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
151static inline long decode_packed_entry_number(codebook *book, 151STIN 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 *********/
285long vorbis_book_decode(codebook *book, oggpack_buffer *b){ 289long 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 *************************************/
295long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, 301long 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
325long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a, 333long 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
352long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, 362long 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,
382long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, 402long 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
289static void render_line(int x0,register int x1,int y0,int y1,ogg_int32_t *d){ 289static 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 */
261int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl, 262int 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: