summaryrefslogtreecommitdiff
path: root/apps/codecs
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/codecs
parent9af42897706548a400a8444066b6ee4900c284f4 (diff)
downloadrockbox-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.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 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: