00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <math.h>
00020 #include <string.h>
00021 #include "ogg.h"
00022 #include "os.h"
00023 #include "misc.h"
00024 #include "ivorbiscodec.h"
00025 #include "codebook.h"
00026
00027
00028 int _ilog(unsigned int v){
00029 int ret=0;
00030 while(v){
00031 ret++;
00032 v>>=1;
00033 }
00034 return(ret);
00035 }
00036
00037
00038
00039
00040
00041 #define VQ_FEXP 10
00042 #define VQ_FMAN 21
00043 #define VQ_FEXP_BIAS 768
00044
00045 static ogg_int32_t _float32_unpack(long val,int *point){
00046 long mant=val&0x1fffff;
00047 int sign=val&0x80000000;
00048 long exp =(val&0x7fe00000L)>>VQ_FMAN;
00049
00050 exp-=(VQ_FMAN-1)+VQ_FEXP_BIAS;
00051
00052 if(mant){
00053 while(!(mant&0x40000000)){
00054 mant<<=1;
00055 exp-=1;
00056 }
00057
00058 if(sign)mant= -mant;
00059 }else{
00060 sign=0;
00061 exp=-9999;
00062 }
00063
00064 *point=exp;
00065 return mant;
00066 }
00067
00068
00069
00070
00071 ogg_uint32_t *_make_words(long *l,long n,long sparsecount){
00072 long i,j,count=0;
00073 ogg_uint32_t marker[33];
00074 ogg_uint32_t *r=(ogg_uint32_t *)_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r));
00075 memset(marker,0,sizeof(marker));
00076
00077 for(i=0;i<n;i++){
00078 long length=l[i];
00079 if(length>0){
00080 ogg_uint32_t entry=marker[length];
00081
00082
00083
00084
00085
00086
00087
00088 if(length<32 && (entry>>length)){
00089
00090 _ogg_free(r);
00091 return(NULL);
00092 }
00093 r[count++]=entry;
00094
00095
00096
00097 {
00098 for(j=length;j>0;j--){
00099
00100 if(marker[j]&1){
00101
00102 if(j==1)
00103 marker[1]++;
00104 else
00105 marker[j]=marker[j-1]<<1;
00106 break;
00107
00108 }
00109 marker[j]++;
00110 }
00111 }
00112
00113
00114
00115
00116 for(j=length+1;j<33;j++)
00117 if((marker[j]>>1) == entry){
00118 entry=marker[j];
00119 marker[j]=marker[j-1]<<1;
00120 }else
00121 break;
00122 }else
00123 if(sparsecount==0)count++;
00124 }
00125
00126
00127
00128 for(i=0,count=0;i<n;i++){
00129 ogg_uint32_t temp=0;
00130 for(j=0;j<l[i];j++){
00131 temp<<=1;
00132 temp|=(r[count]>>j)&1;
00133 }
00134
00135 if(sparsecount){
00136 if(l[i])
00137 r[count++]=temp;
00138 }else
00139 r[count++]=temp;
00140 }
00141
00142 return(r);
00143 }
00144
00145
00146
00147
00148 long _book_maptype1_quantvals(const static_codebook *b){
00149
00150 int bits=_ilog(b->entries);
00151 int vals=b->entries>>((bits-1)*(b->dim-1)/b->dim);
00152
00153 while(1){
00154 long acc=1;
00155 long acc1=1;
00156 int i;
00157 for(i=0;i<b->dim;i++){
00158 acc*=vals;
00159 acc1*=vals+1;
00160 }
00161 if(acc<=b->entries && acc1>b->entries){
00162 return(vals);
00163 }else{
00164 if(acc>b->entries){
00165 vals--;
00166 }else{
00167 vals++;
00168 }
00169 }
00170 }
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 ogg_int32_t *_book_unquantize(const static_codebook *b,int n,int *sparsemap,
00183 int *maxpoint){
00184 long j,k,count=0;
00185 if(b->maptype==1 || b->maptype==2){
00186 int quantvals;
00187 int minpoint,delpoint;
00188 ogg_int32_t mindel=_float32_unpack(b->q_min,&minpoint);
00189 ogg_int32_t delta=_float32_unpack(b->q_delta,&delpoint);
00190 ogg_int32_t *r=(ogg_int32_t *)_ogg_calloc(n*b->dim,sizeof(*r));
00191 int *rp=(int *)_ogg_calloc(n*b->dim,sizeof(*rp));
00192
00193 *maxpoint=minpoint;
00194
00195
00196
00197 switch(b->maptype){
00198 case 1:
00199
00200
00201
00202
00203
00204
00205
00206 quantvals=_book_maptype1_quantvals(b);
00207 for(j=0;j<b->entries;j++){
00208 if((sparsemap && b->lengthlist[j]) || !sparsemap){
00209 ogg_int32_t last=0;
00210 int lastpoint=0;
00211 int indexdiv=1;
00212 for(k=0;k<b->dim;k++){
00213 int index= (j/indexdiv)%quantvals;
00214 int point;
00215 int val=VFLOAT_MULTI(delta,delpoint,
00216 abs(b->quantlist[index]),&point);
00217
00218 val=VFLOAT_ADD(mindel,minpoint,val,point,&point);
00219 val=VFLOAT_ADD(last,lastpoint,val,point,&point);
00220
00221 if(b->q_sequencep){
00222 last=val;
00223 lastpoint=point;
00224 }
00225
00226 if(sparsemap){
00227 r[sparsemap[count]*b->dim+k]=val;
00228 rp[sparsemap[count]*b->dim+k]=point;
00229 }else{
00230 r[count*b->dim+k]=val;
00231 rp[count*b->dim+k]=point;
00232 }
00233 if(*maxpoint<point)*maxpoint=point;
00234 indexdiv*=quantvals;
00235 }
00236 count++;
00237 }
00238
00239 }
00240 break;
00241 case 2:
00242 for(j=0;j<b->entries;j++){
00243 if((sparsemap && b->lengthlist[j]) || !sparsemap){
00244 ogg_int32_t last=0;
00245 int lastpoint=0;
00246
00247 for(k=0;k<b->dim;k++){
00248 int point;
00249 int val=VFLOAT_MULTI(delta,delpoint,
00250 abs(b->quantlist[j*b->dim+k]),&point);
00251
00252 val=VFLOAT_ADD(mindel,minpoint,val,point,&point);
00253 val=VFLOAT_ADD(last,lastpoint,val,point,&point);
00254
00255 if(b->q_sequencep){
00256 last=val;
00257 lastpoint=point;
00258 }
00259
00260 if(sparsemap){
00261 r[sparsemap[count]*b->dim+k]=val;
00262 rp[sparsemap[count]*b->dim+k]=point;
00263 }else{
00264 r[count*b->dim+k]=val;
00265 rp[count*b->dim+k]=point;
00266 }
00267 if(*maxpoint<point)*maxpoint=point;
00268 }
00269 count++;
00270 }
00271 }
00272 break;
00273 }
00274
00275 for(j=0;j<n*b->dim;j++)
00276 if(rp[j]<*maxpoint)
00277 r[j]>>=*maxpoint-rp[j];
00278
00279 _ogg_free(rp);
00280 return(r);
00281 }
00282 return(NULL);
00283 }
00284
00285 void vorbis_staticbook_clear(static_codebook *b){
00286 if(b->quantlist)_ogg_free(b->quantlist);
00287 if(b->lengthlist)_ogg_free(b->lengthlist);
00288 memset(b,0,sizeof(*b));
00289
00290 }
00291
00292 void vorbis_staticbook_destroy(static_codebook *b){
00293 vorbis_staticbook_clear(b);
00294 _ogg_free(b);
00295 }
00296
00297 void vorbis_book_clear(codebook *b){
00298
00299
00300 if(b->valuelist)_ogg_free(b->valuelist);
00301 if(b->codelist)_ogg_free(b->codelist);
00302
00303 if(b->dec_index)_ogg_free(b->dec_index);
00304 if(b->dec_codelengths)_ogg_free(b->dec_codelengths);
00305 if(b->dec_firsttable)_ogg_free(b->dec_firsttable);
00306
00307 memset(b,0,sizeof(*b));
00308 }
00309
00310 static ogg_uint32_t bitreverse(ogg_uint32_t x){
00311 x= ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL);
00312 x= ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL);
00313 x= ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL);
00314 x= ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL);
00315 return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL);
00316 }
00317
00318 static int sort32a(const void *a,const void *b){
00319 return (**(ogg_uint32_t **)a>**(ogg_uint32_t **)b)-
00320 (**(ogg_uint32_t **)a<**(ogg_uint32_t **)b);
00321 }
00322
00323
00324 int vorbis_book_init_decode(codebook *c,const static_codebook *s){
00325 int i,j,n=0,tabn;
00326 int *sortindex = NULL;
00327 memset(c,0,sizeof(*c));
00328
00329
00330 for(i=0;i<s->entries;i++)
00331 if(s->lengthlist[i]>0)
00332 n++;
00333
00334 c->entries=s->entries;
00335 c->used_entries=n;
00336 c->dim=s->dim;
00337
00338 c->q_min=s->q_min;
00339 c->q_delta=s->q_delta;
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 {
00352
00353 ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries);
00354 ogg_uint32_t **codep=(ogg_uint32_t **)_ogg_malloc(sizeof(*codep)*n);
00355 if(codes==NULL)goto err_out;
00356
00357 for(i=0;i<n;i++){
00358 codes[i]=bitreverse(codes[i]);
00359 codep[i]=codes+i;
00360 }
00361
00362 qsort(codep,n,sizeof(*codep),sort32a);
00363
00364 sortindex=(int *)_ogg_malloc(n*sizeof(*sortindex));
00365 c->codelist=(ogg_uint32_t *)_ogg_malloc(n*sizeof(*c->codelist));
00366
00367 for(i=0;i<n;i++){
00368 int position=codep[i]-codes;
00369 sortindex[position]=i;
00370 }
00371
00372 for(i=0;i<n;i++)
00373 c->codelist[sortindex[i]]=codes[i];
00374 _ogg_free(codep);
00375 _ogg_free(codes);
00376 }
00377
00378
00379 c->valuelist=_book_unquantize(s,n,sortindex,&c->binarypoint);
00380 c->dec_index=(int *)_ogg_malloc(n*sizeof(*c->dec_index));
00381
00382 for(n=0,i=0;i<s->entries;i++)
00383 if(s->lengthlist[i]>0)
00384 c->dec_index[sortindex[n++]]=i;
00385
00386 c->dec_codelengths=(char *)_ogg_malloc(n*sizeof(*c->dec_codelengths));
00387 for(n=0,i=0;i<s->entries;i++)
00388 if(s->lengthlist[i]>0)
00389 c->dec_codelengths[sortindex[n++]]=s->lengthlist[i];
00390
00391 c->dec_firsttablen=_ilog(c->used_entries)-4;
00392 if(c->dec_firsttablen<5)c->dec_firsttablen=5;
00393 if(c->dec_firsttablen>8)c->dec_firsttablen=8;
00394
00395 tabn=1<<c->dec_firsttablen;
00396 c->dec_firsttable=(ogg_uint32_t *)_ogg_calloc(tabn,sizeof(*c->dec_firsttable));
00397 c->dec_maxlength=0;
00398
00399 for(i=0;i<n;i++){
00400 if(c->dec_maxlength<c->dec_codelengths[i])
00401 c->dec_maxlength=c->dec_codelengths[i];
00402 if(c->dec_codelengths[i]<=c->dec_firsttablen){
00403 ogg_uint32_t orig=bitreverse(c->codelist[i]);
00404 for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++)
00405 c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1;
00406 }
00407 }
00408
00409
00410
00411 {
00412 ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen);
00413 long lo=0,hi=0;
00414
00415 for(i=0;i<tabn;i++){
00416 ogg_uint32_t word=i<<(32-c->dec_firsttablen);
00417 if(c->dec_firsttable[bitreverse(word)]==0){
00418 while((lo+1)<n && c->codelist[lo+1]<=word)lo++;
00419 while( hi<n && word>=(c->codelist[hi]&mask))hi++;
00420
00421
00422
00423
00424 {
00425 unsigned long loval=lo;
00426 unsigned long hival=n-hi;
00427
00428 if(loval>0x7fff)loval=0x7fff;
00429 if(hival>0x7fff)hival=0x7fff;
00430 c->dec_firsttable[bitreverse(word)]=
00431 0x80000000UL | (loval<<15) | hival;
00432 }
00433 }
00434 }
00435 }
00436
00437 _ogg_free(sortindex);
00438 return(0);
00439 err_out:
00440 vorbis_book_clear(c);
00441 _ogg_free(sortindex);
00442 return(-1);
00443 }
00444