00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #include <math.h>
00021 #include "ogg.h"
00022 #include "ivorbiscodec.h"
00023 #include "codebook.h"
00024 #include "misc.h"
00025 #include "os.h"
00026
00027
00028
00029 int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
00030 long i,j;
00031 memset(s,0,sizeof(*s));
00032
00033
00034 if(oggpack_read(opb,24)!=0x564342)goto _eofout;
00035
00036
00037 s->dim=oggpack_read(opb,16);
00038 s->entries=oggpack_read(opb,24);
00039 if(s->entries==-1)goto _eofout;
00040
00041
00042 switch((int)oggpack_read(opb,1)){
00043 case 0:
00044
00045 s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
00046
00047
00048 if(oggpack_read(opb,1)){
00049
00050
00051 for(i=0;i<s->entries;i++){
00052 if(oggpack_read(opb,1)){
00053 long num=oggpack_read(opb,5);
00054 if(num==-1)goto _eofout;
00055 s->lengthlist[i]=num+1;
00056 }else
00057 s->lengthlist[i]=0;
00058 }
00059 }else{
00060
00061 for(i=0;i<s->entries;i++){
00062 long num=oggpack_read(opb,5);
00063 if(num==-1)goto _eofout;
00064 s->lengthlist[i]=num+1;
00065 }
00066 }
00067
00068 break;
00069 case 1:
00070
00071 {
00072 long length=oggpack_read(opb,5)+1;
00073 s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
00074
00075 for(i=0;i<s->entries;){
00076 long num=oggpack_read(opb,_ilog(s->entries-i));
00077 if(num==-1)goto _eofout;
00078 for(j=0;j<num && i<s->entries;j++,i++)
00079 s->lengthlist[i]=length;
00080 length++;
00081 }
00082 }
00083 break;
00084 default:
00085
00086 return(-1);
00087 }
00088
00089
00090 switch((s->maptype=oggpack_read(opb,4))){
00091 case 0:
00092
00093 break;
00094 case 1: case 2:
00095
00096
00097
00098 s->q_min=oggpack_read(opb,32);
00099 s->q_delta=oggpack_read(opb,32);
00100 s->q_quant=oggpack_read(opb,4)+1;
00101 s->q_sequencep=oggpack_read(opb,1);
00102
00103 {
00104 int quantvals=0;
00105 switch(s->maptype){
00106 case 1:
00107 quantvals=_book_maptype1_quantvals(s);
00108 break;
00109 case 2:
00110 quantvals=s->entries*s->dim;
00111 break;
00112 }
00113
00114
00115 s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
00116 for(i=0;i<quantvals;i++)
00117 s->quantlist[i]=oggpack_read(opb,s->q_quant);
00118
00119 if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
00120 }
00121 break;
00122 default:
00123 goto _errout;
00124 }
00125
00126
00127 return(0);
00128
00129 _errout:
00130 _eofout:
00131 vorbis_staticbook_clear(s);
00132 return(-1);
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 static ogg_uint32_t bitreverse(ogg_uint32_t x){
00144 x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
00145 x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
00146 x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
00147 x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
00148 return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
00149 }
00150
00151 static long decode_packed_entry_number(codebook *book,
00152 oggpack_buffer *b){
00153 int read=book->dec_maxlength;
00154 long lo,hi;
00155 long lok = oggpack_look(b,book->dec_firsttablen);
00156
00157 if (lok >= 0) {
00158 long entry = book->dec_firsttable[lok];
00159 if(entry&0x80000000UL){
00160 lo=(entry>>15)&0x7fff;
00161 hi=book->used_entries-(entry&0x7fff);
00162 }else{
00163 oggpack_adv(b, book->dec_codelengths[entry-1]);
00164 return(entry-1);
00165 }
00166 }else{
00167 lo=0;
00168 hi=book->used_entries;
00169 }
00170
00171 lok = oggpack_look(b, read);
00172
00173 while(lok<0 && read>1)
00174 lok = oggpack_look(b, --read);
00175 if(lok<0)return -1;
00176
00177
00178 {
00179 ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
00180
00181 while(hi-lo>1){
00182 long p=(hi-lo)>>1;
00183 long test=book->codelist[lo+p]>testword;
00184 lo+=p&(test-1);
00185 hi-=p&(-test);
00186 }
00187
00188 if(book->dec_codelengths[lo]<=read){
00189 oggpack_adv(b, book->dec_codelengths[lo]);
00190 return(lo);
00191 }
00192 }
00193
00194 oggpack_adv(b, read);
00195 return(-1);
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 long vorbis_book_decode(codebook *book, oggpack_buffer *b){
00214 long packed_entry=decode_packed_entry_number(book,b);
00215 if(packed_entry>=0)
00216 return(book->dec_index[packed_entry]);
00217
00218
00219 return(packed_entry);
00220 }
00221
00222
00223 long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a,
00224 oggpack_buffer *b,int n,int point){
00225 int step=n/book->dim;
00226 long *entry = (long *)_ogg_malloc(sizeof(*entry)*step);
00227 ogg_int32_t **t = (ogg_int32_t **)_ogg_malloc(sizeof(*t)*step);
00228 int i,j,o;
00229 int shift=point-book->binarypoint;
00230
00231 if(shift>=0){
00232 for (i = 0; i < step; i++) {
00233 entry[i]=decode_packed_entry_number(book,b);
00234 if(entry[i]==-1)
00235 {
00236 _ogg_free(entry);
00237 _ogg_free(t);
00238 return(-1);
00239 }
00240 t[i] = book->valuelist+entry[i]*book->dim;
00241 }
00242 for(i=0,o=0;i<book->dim;i++,o+=step)
00243 for (j=0;j<step;j++)
00244 a[o+j]+=t[j][i]>>shift;
00245 }else{
00246 for (i = 0; i < step; i++) {
00247 entry[i]=decode_packed_entry_number(book,b);
00248 if(entry[i]==-1)return(-1);
00249 t[i] = book->valuelist+entry[i]*book->dim;
00250 }
00251 for(i=0,o=0;i<book->dim;i++,o+=step)
00252 for (j=0;j<step;j++)
00253 a[o+j]+=t[j][i]<<-shift;
00254 }
00255 _ogg_free(entry);
00256 _ogg_free(t);
00257 return(0);
00258 }
00259
00260 long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a,
00261 oggpack_buffer *b,int n,int point){
00262 int i,j,entry;
00263 ogg_int32_t *t;
00264 int shift=point-book->binarypoint;
00265
00266 if(shift>=0){
00267 for(i=0;i<n;){
00268 entry = decode_packed_entry_number(book,b);
00269 if(entry==-1)return(-1);
00270 t = book->valuelist+entry*book->dim;
00271 for (j=0;j<book->dim;)
00272 a[i++]+=t[j++]>>shift;
00273 }
00274 }else{
00275 for(i=0;i<n;){
00276 entry = decode_packed_entry_number(book,b);
00277 if(entry==-1)return(-1);
00278 t = book->valuelist+entry*book->dim;
00279 for (j=0;j<book->dim;)
00280 a[i++]+=t[j++]<<-shift;
00281 }
00282 }
00283 return(0);
00284 }
00285
00286 long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a,
00287 oggpack_buffer *b,int n,int point){
00288 int i,j,entry;
00289 ogg_int32_t *t;
00290 int shift=point-book->binarypoint;
00291
00292 if(shift>=0){
00293
00294 for(i=0;i<n;){
00295 entry = decode_packed_entry_number(book,b);
00296 if(entry==-1)return(-1);
00297 t = book->valuelist+entry*book->dim;
00298 for (j=0;j<book->dim;){
00299 a[i++]=t[j++]>>shift;
00300 }
00301 }
00302 }else{
00303
00304 for(i=0;i<n;){
00305 entry = decode_packed_entry_number(book,b);
00306 if(entry==-1)return(-1);
00307 t = book->valuelist+entry*book->dim;
00308 for (j=0;j<book->dim;){
00309 a[i++]=t[j++]<<-shift;
00310 }
00311 }
00312 }
00313 return(0);
00314 }
00315
00316 long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,\
00317 long offset,int ch,
00318 oggpack_buffer *b,int n,int point){
00319 long i,j,entry;
00320 int chptr=0;
00321 int shift=point-book->binarypoint;
00322
00323 if(shift>=0){
00324
00325 for(i=offset;i<offset+n;){
00326 entry = decode_packed_entry_number(book,b);
00327 if(entry==-1)return(-1);
00328 {
00329 const ogg_int32_t *t = book->valuelist+entry*book->dim;
00330 for (j=0;j<book->dim;j++){
00331 a[chptr++][i]+=t[j]>>shift;
00332 if(chptr==ch){
00333 chptr=0;
00334 i++;
00335 }
00336 }
00337 }
00338 }
00339 }else{
00340
00341 for(i=offset;i<offset+n;){
00342 entry = decode_packed_entry_number(book,b);
00343 if(entry==-1)return(-1);
00344 {
00345 const ogg_int32_t *t = book->valuelist+entry*book->dim;
00346 for (j=0;j<book->dim;j++){
00347 a[chptr++][i]+=t[j]<<-shift;
00348 if(chptr==ch){
00349 chptr=0;
00350 i++;
00351 }
00352 }
00353 }
00354 }
00355 }
00356 return(0);
00357 }