summaryrefslogtreecommitdiff
path: root/lib/codebook.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/codebook.c')
-rw-r--r--lib/codebook.c179
1 files changed, 99 insertions, 80 deletions
diff --git a/lib/codebook.c b/lib/codebook.c
index ea360320..01f23249 100644
--- a/lib/codebook.c
+++ b/lib/codebook.c
@@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
- * by the XIPHOPHORUS Company http://www.xiph.org/ *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: basic codebook pack/unpack/code/decode operations
- last mod: $Id: codebook.c,v 1.39 2002/06/28 22:19:35 xiphmont Exp $
+ last mod: $Id$
********************************************************************/
@@ -255,6 +255,7 @@ int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
/* returns the number of bits ************************************************/
int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){
+ if(a<0 || a>=book->c->entries)return(0);
oggpack_write(b,book->codelist[a],book->c->lengthlist[a]);
return(book->c->lengthlist[a]);
}
@@ -310,7 +311,7 @@ STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){
int read=book->dec_maxlength;
long lo,hi;
long lok = oggpack_look(b,book->dec_firsttablen);
-
+
if (lok >= 0) {
long entry = book->dec_firsttable[lok];
if(entry&0x80000000UL){
@@ -324,24 +325,24 @@ STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){
lo=0;
hi=book->used_entries;
}
-
+
lok = oggpack_look(b, read);
-
+
while(lok<0 && read>1)
lok = oggpack_look(b, --read);
if(lok<0)return -1;
-
+
/* bisect search for the codeword in the ordered list */
{
ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
-
+
while(hi-lo>1){
long p=(hi-lo)>>1;
long test=book->codelist[lo+p]>testword;
lo+=p&(test-1);
hi-=p&(-test);
- }
-
+ }
+
if(book->dec_codelengths[lo]<=read){
oggpack_adv(b, book->dec_codelengths[lo]);
return(lo);
@@ -349,6 +350,7 @@ STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){
}
oggpack_adv(b, read);
+
return(-1);
}
@@ -368,104 +370,121 @@ STIN long decode_packed_entry_number(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,float *a,oggpack_buffer *b,int n){
- int step=n/book->dim;
- long *entry = alloca(sizeof(*entry)*step);
- float **t = alloca(sizeof(*t)*step);
- int i,j,o;
-
- 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 = alloca(sizeof(*entry)*step);
+ float **t = alloca(sizeof(*t)*step);
+ int i,j,o;
+
+ 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];
}
- for(i=0,o=0;i<book->dim;i++,o+=step)
- for (j=0;j<step;j++)
- a[o+j]+=t[j][i];
return(0);
}
long vorbis_book_decodev_add(codebook *book,float *a,oggpack_buffer *b,int n){
- int i,j,entry;
- float *t;
+ if(book->used_entries>0){
+ int i,j,entry;
+ float *t;
+
+ if(book->dim>8){
+ 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++];
+ }
+ }else{
+ for(i=0;i<n;){
+ entry = decode_packed_entry_number(book,b);
+ if(entry==-1)return(-1);
+ t = book->valuelist+entry*book->dim;
+ j=0;
+ switch((int)book->dim){
+ case 8:
+ a[i++]+=t[j++];
+ case 7:
+ a[i++]+=t[j++];
+ case 6:
+ a[i++]+=t[j++];
+ case 5:
+ a[i++]+=t[j++];
+ case 4:
+ a[i++]+=t[j++];
+ case 3:
+ a[i++]+=t[j++];
+ case 2:
+ a[i++]+=t[j++];
+ case 1:
+ a[i++]+=t[j++];
+ case 0:
+ break;
+ }
+ }
+ }
+ }
+ return(0);
+}
- if(book->dim>8){
+long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){
+ if(book->used_entries>0){
+ int i,j,entry;
+ float *t;
+
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++];
+ a[i++]=t[j++];
}
}else{
+ 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;
- j=0;
- switch((int)book->dim){
- case 8:
- a[i++]+=t[j++];
- case 7:
- a[i++]+=t[j++];
- case 6:
- a[i++]+=t[j++];
- case 5:
- a[i++]+=t[j++];
- case 4:
- a[i++]+=t[j++];
- case 3:
- a[i++]+=t[j++];
- case 2:
- a[i++]+=t[j++];
- case 1:
- a[i++]+=t[j++];
- case 0:
- break;
- }
+ for (j=0;j<book->dim;)
+ a[i++]=0.f;
}
- }
- return(0);
-}
-
-long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){
- int i,j,entry;
- float *t;
-
- 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++];
}
return(0);
}
long vorbis_book_decodevv_add(codebook *book,float **a,long offset,int ch,
oggpack_buffer *b,int n){
+
long i,j,entry;
int chptr=0;
-
- for(i=offset/ch;i<(offset+n)/ch;){
- entry = decode_packed_entry_number(book,b);
- if(entry==-1)return(-1);
- {
- const float *t = book->valuelist+entry*book->dim;
- for (j=0;j<book->dim;j++){
- a[chptr++][i]+=t[j];
- if(chptr==ch){
- chptr=0;
- i++;
+ if(book->used_entries>0){
+ for(i=offset/ch;i<(offset+n)/ch;){
+ entry = decode_packed_entry_number(book,b);
+ if(entry==-1)return(-1);
+ {
+ const float *t = book->valuelist+entry*book->dim;
+ for (j=0;j<book->dim;j++){
+ a[chptr++][i]+=t[j];
+ if(chptr==ch){
+ chptr=0;
+ i++;
+ }
}
}
}