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 /apps/codecs | |
| parent | 9af42897706548a400a8444066b6ee4900c284f4 (diff) | |
| download | rockbox-932b20ec622ad743fc9dd9a523f7cbe3a7c0e04d.zip rockbox-932b20ec622ad743fc9dd9a523f7cbe3a7c0e04d.tar.gz rockbox-932b20ec622ad743fc9dd9a523f7cbe3a7c0e04d.tar.bz2 rockbox-932b20ec622ad743fc9dd9a523f7cbe3a7c0e04d.tar.xz | |
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/codecs')
| -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 cad4e81..1287a95 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){ return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa); } -static inline long decode_packed_entry_number(codebook *book, +STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){ int read=book->dec_maxlength; long lo,hi; @@ -172,7 +172,11 @@ static inline long decode_packed_entry_number(codebook *book, while(lok<0 && read>1) lok = oggpack_look(b, --read); - if(lok<0)return -1; + + if(lok<0){ + oggpack_adv(b,1); /* force eop */ + return -1; + } /* bisect search for the codeword in the ordered list */ { @@ -191,7 +195,7 @@ static inline long decode_packed_entry_number(codebook *book, } } - oggpack_adv(b, read); + oggpack_adv(b, read+1); return(-1); } @@ -283,67 +287,73 @@ static inline long decode_packed_block(codebook *book, oggpack_buffer *b, /* returns the [original, not compacted] entry number or -1 on eof *********/ long vorbis_book_decode(codebook *book, oggpack_buffer *b){ - long packed_entry=decode_packed_entry_number(book,b); - if(packed_entry>=0) - return(book->dec_index[packed_entry]); - + if(book->used_entries>0){ + long packed_entry=decode_packed_entry_number(book,b); + if(packed_entry>=0) + return(book->dec_index[packed_entry]); + } + /* if there's no dec_index, the codebook unpacking isn't collapsed */ - return(packed_entry); + return(-1); } /* returns 0 on OK or -1 on eof *************************************/ long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, oggpack_buffer *b,int n,int point){ - int step=n/book->dim; - long *entry = (long *)alloca(sizeof(*entry)*step); - ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step); - int i,j,o; - int shift=point-book->binarypoint; - - if(shift>=0){ - for (i = 0; i < step; i++) { - entry[i]=decode_packed_entry_number(book,b); - if(entry[i]==-1)return(-1); - t[i] = book->valuelist+entry[i]*book->dim; - } - for(i=0,o=0;i<book->dim;i++,o+=step) - for (j=0;j<step;j++) - a[o+j]+=t[j][i]>>shift; - }else{ - for (i = 0; i < step; i++) { - entry[i]=decode_packed_entry_number(book,b); - if(entry[i]==-1)return(-1); - t[i] = book->valuelist+entry[i]*book->dim; + if(book->used_entries>0){ + int step=n/book->dim; + long *entry = (long *)alloca(sizeof(*entry)*step); + ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step); + int i,j,o; + int shift=point-book->binarypoint; + + if(shift>=0){ + for (i = 0; i < step; i++) { + entry[i]=decode_packed_entry_number(book,b); + if(entry[i]==-1)return(-1); + t[i] = book->valuelist+entry[i]*book->dim; + } + for(i=0,o=0;i<book->dim;i++,o+=step) + for (j=0;j<step;j++) + a[o+j]+=t[j][i]>>shift; + }else{ + for (i = 0; i < step; i++) { + entry[i]=decode_packed_entry_number(book,b); + if(entry[i]==-1)return(-1); + t[i] = book->valuelist+entry[i]*book->dim; + } + for(i=0,o=0;i<book->dim;i++,o+=step) + for (j=0;j<step;j++) + a[o+j]+=t[j][i]<<-shift; } - for(i=0,o=0;i<book->dim;i++,o+=step) - for (j=0;j<step;j++) - a[o+j]+=t[j][i]<<-shift; } return(0); } long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a, oggpack_buffer *b,int n,int point){ - int i,j,entry; - ogg_int32_t *t; - int shift=point-book->binarypoint; - - if(shift>=0){ - for(i=0;i<n;){ - entry = decode_packed_entry_number(book,b); - if(entry==-1)return(-1); - t = book->valuelist+entry*book->dim; - for (j=0;j<book->dim;) - a[i++]+=t[j++]>>shift; - } - }else{ - shift = -shift; - for(i=0;i<n;){ - entry = decode_packed_entry_number(book,b); - if(entry==-1)return(-1); - t = book->valuelist+entry*book->dim; - for (j=0;j<book->dim;) - a[i++]+=t[j++]<<shift; + if(book->used_entries>0){ + int i,j,entry; + ogg_int32_t *t; + int shift=point-book->binarypoint; + + if(shift>=0){ + for(i=0;i<n;){ + entry = decode_packed_entry_number(book,b); + if(entry==-1)return(-1); + t = book->valuelist+entry*book->dim; + for (j=0;j<book->dim;) + a[i++]+=t[j++]>>shift; + } + }else{ + shift = -shift; + for(i=0;i<n;){ + entry = decode_packed_entry_number(book,b); + if(entry==-1)return(-1); + t = book->valuelist+entry*book->dim; + for (j=0;j<book->dim;) + a[i++]+=t[j++]<<shift; + } } } return(0); @@ -351,28 +361,38 @@ long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a, long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, oggpack_buffer *b,int n,int point){ - int i,j,entry; - ogg_int32_t *t; - int shift=point-book->binarypoint; - - if(shift>=0){ - - for(i=0;i<n;){ - entry = decode_packed_entry_number(book,b); - if(entry==-1)return(-1); - t = book->valuelist+entry*book->dim; - for (j=0;j<book->dim;){ - a[i++]=t[j++]>>shift; + if(book->used_entries>0){ + int i,j,entry; + ogg_int32_t *t; + int shift=point-book->binarypoint; + + if(shift>=0){ + + for(i=0;i<n;){ + entry = decode_packed_entry_number(book,b); + if(entry==-1)return(-1); + t = book->valuelist+entry*book->dim; + for (j=0;j<book->dim;){ + a[i++]=t[j++]>>shift; + } + } + }else{ + shift = -shift; + for(i=0;i<n;){ + entry = decode_packed_entry_number(book,b); + if(entry==-1)return(-1); + t = book->valuelist+entry*book->dim; + for (j=0;j<book->dim;){ + a[i++]=t[j++]<<shift; + } } } }else{ - shift = -shift; + + int i,j; for(i=0;i<n;){ - entry = decode_packed_entry_number(book,b); - if(entry==-1)return(-1); - t = book->valuelist+entry*book->dim; for (j=0;j<book->dim;){ - a[i++]=t[j++]<<shift; + a[i++]=0; } } } @@ -382,48 +402,50 @@ long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, long offset,int ch, oggpack_buffer *b,int n,int point){ - long i,j,k,chunk,read; - int chptr=0; - int shift=point-book->binarypoint; - long entries[32]; + if(book->used_entries>0){ + long i,j,k,chunk,read; + int chptr=0; + int shift=point-book->binarypoint; + long entries[32]; - if(shift>=0){ + if(shift>=0){ - for(i=offset;i<offset+n;){ - chunk=32; - if (chunk*book->dim>(offset+n-i)*ch) - chunk=((offset+n-i)*ch+book->dim-1)/book->dim; - read = decode_packed_block(book,b,entries,chunk); - for(k=0;k<read;k++){ - const ogg_int32_t *t = book->valuelist+entries[k]*book->dim; - for (j=0;j<book->dim;j++){ - a[chptr++][i]+=t[j]>>shift; - if(chptr==ch){ - chptr=0; - i++; + for(i=offset;i<offset+n;){ + chunk=32; + if (chunk*book->dim>(offset+n-i)*ch) + chunk=((offset+n-i)*ch+book->dim-1)/book->dim; + read = decode_packed_block(book,b,entries,chunk); + for(k=0;k<read;k++){ + const ogg_int32_t *t = book->valuelist+entries[k]*book->dim; + for (j=0;j<book->dim;j++){ + a[chptr++][i]+=t[j]>>shift; + if(chptr==ch){ + chptr=0; + i++; + } } - } + } + if (read<chunk)return-1; } - if (read<chunk)return-1; - } - }else{ - shift = -shift; - for(i=offset;i<offset+n;){ - chunk=32; - if (chunk*book->dim>(offset+n-i)*ch) - chunk=((offset+n-i)*ch+book->dim-1)/book->dim; - read = decode_packed_block(book,b,entries,chunk); - for(k=0;k<read;k++){ - const ogg_int32_t *t = book->valuelist+entries[k]*book->dim; - for (j=0;j<book->dim;j++){ - a[chptr++][i]+=t[j]<<shift; - if(chptr==ch){ - chptr=0; - i++; + }else{ + shift = -shift; + for(i=offset;i<offset+n;){ + chunk=32; + if (chunk*book->dim>(offset+n-i)*ch) + chunk=((offset+n-i)*ch+book->dim-1)/book->dim; + read = decode_packed_block(book,b,entries,chunk); + for(k=0;k<read;k++){ + const ogg_int32_t *t = book->valuelist+entries[k]*book->dim; + for (j=0;j<book->dim;j++){ + a[chptr++][i]+=t[j]<<shift; + if(chptr==ch){ + chptr=0; + i++; + } } - } + } + if (read<chunk)return-1; } - if (read<chunk)return-1; } } return(0); diff --git a/apps/codecs/Tremor/floor1.c b/apps/codecs/Tremor/floor1.c index 5f43d56..4ee58c1 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 = { XdB(0x69f80e9a), XdB(0x70dafda8), XdB(0x78307d76), XdB(0x7fffffff), }; -static void render_line(int x0,register int x1,int y0,int y1,ogg_int32_t *d){ +static void render_line(int n, int x0,register int x1,int y0,int y1,ogg_int32_t *d){ int dy=y1-y0; register int x=x0; 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){ register int sy=(dy<0?base-1:base+1); int err=0; + if(n>x1)n=x1; ady-=abs(base*adx); - d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]); + if(x<n) + d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]); - while(++x<x1){ + while(++x<n){ err=err+ady; if(err>=adx){ err-=adx; @@ -424,7 +426,7 @@ static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo, hy*=info->mult; hx=info->postlist[current]; - render_line(lx,hx,ly,hy,out); + render_line(n,lx,hx,ly,hy,out); lx=hx; ly=hy; diff --git a/apps/codecs/Tremor/framing.c b/apps/codecs/Tremor/framing.c index e444514..1cd5c1e 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){ bt=bs->unused_buffers; rt=bs->unused_references; - if(!bs->outstanding){ - _ogg_free(bs); - return; - } - while(bt){ ogg_buffer *b=bt; bt=b->ptr.next; @@ -71,6 +66,10 @@ static void _ogg_buffer_destroy(ogg_buffer_state *bs){ _ogg_free(r); } bs->unused_references=0; + + if(!bs->outstanding) + _ogg_free(bs); + } } @@ -836,6 +835,7 @@ int ogg_stream_destroy(ogg_stream_state *os){ ogg_buffer_release(os->header_tail); ogg_buffer_release(os->body_tail); memset(os,0,sizeof(*os)); + _ogg_free(os); } return OGG_SUCCESS; } diff --git a/apps/codecs/Tremor/info.c b/apps/codecs/Tremor/info.c index e750c8b..c8d9651 100644 --- a/apps/codecs/Tremor/info.c +++ b/apps/codecs/Tremor/info.c @@ -97,8 +97,8 @@ void vorbis_comment_clear(vorbis_comment *vc){ if(vc->user_comments)_ogg_free(vc->user_comments); if(vc->comment_lengths)_ogg_free(vc->comment_lengths); if(vc->vendor)_ogg_free(vc->vendor); + memset(vc,0,sizeof(*vc)); } - memset(vc,0,sizeof(*vc)); } /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. @@ -124,13 +124,16 @@ void vorbis_info_clear(vorbis_info *vi){ if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); for(i=0;i<ci->maps;i++) /* unpack does the range checking */ - _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); + if(ci->map_param[i]) + _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); for(i=0;i<ci->floors;i++) /* unpack does the range checking */ - _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); + if(ci->floor_param[i]) + _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); for(i=0;i<ci->residues;i++) /* unpack does the range checking */ - _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); + if(ci->residue_param[i]) + _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); for(i=0;i<ci->books;i++){ if(ci->book_param[i]){ diff --git a/apps/codecs/Tremor/res012.c b/apps/codecs/Tremor/res012.c index fe0cf2e..2104c06 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, /* move all this setup out later */ int samples_per_partition=info->grouping; int partitions_per_word=look->phrasebook->dim; - int n=info->end-info->begin; + int max=vb->pcmend>>1; + int end=(info->end<max?info->end:max); + int n=end-info->begin; + + if(n>0){ + int partvals=n/samples_per_partition; + int partwords=(partvals+partitions_per_word-1)/partitions_per_word; + int ***partword=(int ***)alloca(ch*sizeof(*partword)); - int partvals=n/samples_per_partition; - int partwords=(partvals+partitions_per_word-1)/partitions_per_word; - int ***partword=(int ***)alloca(ch*sizeof(*partword)); - - for(j=0;j<ch;j++) - partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j])); - - for(s=0;s<look->stages;s++){ - - /* each loop decodes on partition codeword containing - partitions_pre_word partitions */ - for(i=0,l=0;i<partvals;l++){ - if(s==0){ - /* fetch the partition word for each channel */ - for(j=0;j<ch;j++){ - int temp=vorbis_book_decode(look->phrasebook,&vb->opb); - if(temp==-1)goto eopbreak; - partword[j][l]=look->decodemap[temp]; - if(partword[j][l]==NULL)goto errout; + for(j=0;j<ch;j++) + partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j])); + + for(s=0;s<look->stages;s++){ + + /* each loop decodes on partition codeword containing + partitions_pre_word partitions */ + for(i=0,l=0;i<partvals;l++){ + if(s==0){ + /* fetch the partition word for each channel */ + for(j=0;j<ch;j++){ + int temp=vorbis_book_decode(look->phrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[j][l]=look->decodemap[temp]; + if(partword[j][l]==NULL)goto errout; + } } - } - - /* now we decode residual values for the partitions */ - for(k=0;k<partitions_per_word && i<partvals;k++,i++) - for(j=0;j<ch;j++){ - long offset=info->begin+i*samples_per_partition; - if(info->secondstages[partword[j][l][k]]&(1<<s)){ - codebook *stagebook=look->partbooks[partword[j][l][k]][s]; - if(stagebook){ - if(decodepart(stagebook,in[j]+offset,&vb->opb, - samples_per_partition,-8)==-1)goto eopbreak; + + /* now we decode residual values for the partitions */ + for(k=0;k<partitions_per_word && i<partvals;k++,i++) + for(j=0;j<ch;j++){ + long offset=info->begin+i*samples_per_partition; + if(info->secondstages[partword[j][l][k]]&(1<<s)){ + codebook *stagebook=look->partbooks[partword[j][l][k]][s]; + if(stagebook){ + if(decodepart(stagebook,in[j]+offset,&vb->opb, + samples_per_partition,-8)==-1)goto eopbreak; + } } } - } + } } } - errout: eopbreak: return(0); @@ -255,8 +258,6 @@ int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl, return(0); } - - /* duplicate code here as speed is somewhat more important */ int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl, ogg_int32_t **in,int *nonzero,int ch) @@ -270,44 +271,48 @@ int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl, /* move all this setup out later */ int samples_per_partition=info->grouping; int partitions_per_word=look->phrasebook->dim; - int n=info->end-info->begin; - - int partvals=n/samples_per_partition; - int partwords=(partvals+partitions_per_word-1)/partitions_per_word; - int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword)); - int beginoff=info->begin/ch; - - for(i=0;i<ch;i++)if(nonzero[i])break; - if(i==ch)return(0); /* no nonzero vectors */ - - samples_per_partition/=ch; - - for(s=0;s<look->stages;s++){ - for(i=0,l=0;i<partvals;l++){ - - if(s==0){ - /* fetch the partition word */ - int temp=vorbis_book_decode(look->phrasebook,&vb->opb); - if(temp==-1)goto eopbreak; - partword[l]=look->decodemap[temp]; - if(partword[l]==NULL)goto errout; - } - - /* now we decode residual values for the partitions */ - for(k=0;k<partitions_per_word && i<partvals;k++,i++) - if(info->secondstages[partword[l][k]]&(1<<s)){ - codebook *stagebook=look->partbooks[partword[l][k]][s]; - if(stagebook){ - if(vorbis_book_decodevv_add(stagebook,in, - i*samples_per_partition+beginoff,ch, - &vb->opb, - samples_per_partition,-8)==-1) - goto eopbreak; - } + int max=(vb->pcmend*ch)>>1; + int end=(info->end<max?info->end:max); + int n=end-info->begin; + + if(n>0){ + + int partvals=n/samples_per_partition; + int partwords=(partvals+partitions_per_word-1)/partitions_per_word; + int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword)); + int beginoff=info->begin/ch; + + for(i=0;i<ch;i++)if(nonzero[i])break; + if(i==ch)return(0); /* no nonzero vectors */ + + samples_per_partition/=ch; + + for(s=0;s<look->stages;s++){ + for(i=0,l=0;i<partvals;l++){ + + if(s==0){ + /* fetch the partition word */ + int temp=vorbis_book_decode(look->phrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[l]=look->decodemap[temp]; + if(partword[l]==NULL)goto errout; } - } + + /* now we decode residual values for the partitions */ + for(k=0;k<partitions_per_word && i<partvals;k++,i++) + if(info->secondstages[partword[l][k]]&(1<<s)){ + codebook *stagebook=look->partbooks[partword[l][k]][s]; + if(stagebook){ + if(vorbis_book_decodevv_add(stagebook,in, + i*samples_per_partition+beginoff,ch, + &vb->opb, + samples_per_partition,-8)==-1) + goto eopbreak; + } + } + } + } } - errout: eopbreak: return(0); diff --git a/apps/codecs/Tremor/sharedbook.c b/apps/codecs/Tremor/sharedbook.c index c58ae55..6d1226e 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){ c->used_entries=n; c->dim=s->dim; - c->q_min=s->q_min; - c->q_delta=s->q_delta; - - /* two different remappings go on here. - - First, we collapse the likely sparse codebook down only to - actually represented values/words. This collapsing needs to be - indexed as map-valueless books are used to encode original entry - positions as integers. - - Second, we reorder all vectors, including the entry index above, - by sorted bitreversed codeword to allow treeless decode. */ - - { + if(n>0){ + /* two different remappings go on here. + + First, we collapse the likely sparse codebook down only to + actually represented values/words. This collapsing needs to be + indexed as map-valueless books are used to encode original entry + positions as integers. + + Second, we reorder all vectors, including the entry index above, + by sorted bitreversed codeword to allow treeless decode. */ + /* perform sort */ ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); ogg_uint32_t **codep=(ogg_uint32_t **)ogg_tmpmalloc(sizeof(*codep)*n); - + if(codes==NULL||codep==NULL)goto err_out; for(i=0;i<n;i++){ @@ -375,67 +372,68 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ for(i=0;i<n;i++) c->codelist[sortindex[i]]=codes[i]; /* _ogg_free(codes); */ - } - - - c->valuelist=_book_unquantize(s,n,sortindex,&c->binarypoint); - c->dec_index=(int *)_ogg_malloc(n*sizeof(*c->dec_index)); - - for(n=0,i=0;i<s->entries;i++) - if(s->lengthlist[i]>0) - c->dec_index[sortindex[n++]]=i; - - c->dec_codelengths=(char *)_ogg_malloc(n*sizeof(*c->dec_codelengths)); - for(n=0,i=0;i<s->entries;i++) - if(s->lengthlist[i]>0) - c->dec_codelengths[sortindex[n++]]=s->lengthlist[i]; - - c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */ - if(c->dec_firsttablen<5)c->dec_firsttablen=5; - if(c->dec_firsttablen>8)c->dec_firsttablen=8; - - tabn=1<<c->dec_firsttablen; - c->dec_firsttable=(ogg_uint32_t *)_ogg_calloc(tabn,sizeof(*c->dec_firsttable)); - c->dec_maxlength=0; - - for(i=0;i<n;i++){ - if(c->dec_maxlength<c->dec_codelengths[i]) - c->dec_maxlength=c->dec_codelengths[i]; - if(c->dec_codelengths[i]<=c->dec_firsttablen){ - ogg_uint32_t orig=bitreverse(c->codelist[i]); - for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++) - c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1; + + + + c->valuelist=_book_unquantize(s,n,sortindex,&c->binarypoint); + c->dec_index=(int *)_ogg_malloc(n*sizeof(*c->dec_index)); + + for(n=0,i=0;i<s->entries;i++) + if(s->lengthlist[i]>0) + c->dec_index[sortindex[n++]]=i; + + c->dec_codelengths=(char *)_ogg_malloc(n*sizeof(*c->dec_codelengths)); + for(n=0,i=0;i<s->entries;i++) + if(s->lengthlist[i]>0) + c->dec_codelengths[sortindex[n++]]=s->lengthlist[i]; + + c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */ + if(c->dec_firsttablen<5)c->dec_firsttablen=5; + if(c->dec_firsttablen>8)c->dec_firsttablen=8; + + tabn=1<<c->dec_firsttablen; + c->dec_firsttable=(ogg_uint32_t *)_ogg_calloc(tabn,sizeof(*c->dec_firsttable)); + c->dec_maxlength=0; + + for(i=0;i<n;i++){ + if(c->dec_maxlength<c->dec_codelengths[i]) + c->dec_maxlength=c->dec_codelengths[i]; + if(c->dec_codelengths[i]<=c->dec_firsttablen){ + ogg_uint32_t orig=bitreverse(c->codelist[i]); + for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++) + c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1; + } } - } - - /* now fill in 'unused' entries in the firsttable with hi/lo search - hints for the non-direct-hits */ - { - ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen); - long lo=0,hi=0; - - for(i=0;i<tabn;i++){ - ogg_uint32_t word=i<<(32-c->dec_firsttablen); - if(c->dec_firsttable[bitreverse(word)]==0){ - while((lo+1)<n && c->codelist[lo+1]<=word)lo++; - while( hi<n && word>=(c->codelist[hi]&mask))hi++; - - /* we only actually have 15 bits per hint to play with here. - In order to overflow gracefully (nothing breaks, efficiency - just drops), encode as the difference from the extremes. */ - { - unsigned long loval=lo; - unsigned long hival=n-hi; - - if(loval>0x7fff)loval=0x7fff; - if(hival>0x7fff)hival=0x7fff; - c->dec_firsttable[bitreverse(word)]= - 0x80000000UL | (loval<<15) | hival; + + /* now fill in 'unused' entries in the firsttable with hi/lo search + hints for the non-direct-hits */ + { + ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen); + long lo=0,hi=0; + + for(i=0;i<tabn;i++){ + ogg_uint32_t word=i<<(32-c->dec_firsttablen); + if(c->dec_firsttable[bitreverse(word)]==0){ + while((lo+1)<n && c->codelist[lo+1]<=word)lo++; + while( hi<n && word>=(c->codelist[hi]&mask))hi++; + + /* we only actually have 15 bits per hint to play with here. + In order to overflow gracefully (nothing breaks, efficiency + just drops), encode as the difference from the extremes. */ + { + unsigned long loval=lo; + unsigned long hival=n-hi; + + if(loval>0x7fff)loval=0x7fff; + if(hival>0x7fff)hival=0x7fff; + c->dec_firsttable[bitreverse(word)]= + 0x80000000UL | (loval<<15) | hival; + } } } } } - + ogg_tmpmalloc_free(pos); return(0); err_out: |