Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 244 | chris | 1 | /******************************************************************** |
| 2 | * * |
||
| 3 | * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * |
||
| 4 | * * |
||
| 5 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
||
| 6 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
||
| 7 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
||
| 8 | * * |
||
| 9 | * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * |
||
| 10 | * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * |
||
| 11 | * * |
||
| 12 | ******************************************************************** |
||
| 13 | |||
| 14 | function: basic shared codebook operations |
||
| 15 | |||
| 16 | ********************************************************************/ |
||
| 17 | |||
| 18 | #include <stdlib.h> |
||
| 19 | #include <math.h> |
||
| 20 | #include <string.h> |
||
| 21 | #include "ogg.h" |
||
| 22 | #include "os.h" |
||
| 23 | #include "misc.h" |
||
| 24 | #include "ivorbiscodec.h" |
||
| 25 | #include "codebook.h" |
||
| 26 | |||
| 27 | /**** pack/unpack helpers ******************************************/ |
||
| 28 | int _ilog(unsigned int v){ |
||
| 29 | int ret=0; |
||
| 30 | while(v){ |
||
| 31 | ret++; |
||
| 32 | v>>=1; |
||
| 33 | } |
||
| 34 | return(ret); |
||
| 35 | } |
||
| 36 | |||
| 37 | /* 32 bit float (not IEEE; nonnormalized mantissa + |
||
| 38 | biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm |
||
| 39 | Why not IEEE? It's just not that important here. */ |
||
| 40 | |||
| 41 | #define VQ_FEXP 10 |
||
| 42 | #define VQ_FMAN 21 |
||
| 43 | #define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */ |
||
| 44 | |||
| 45 | static ogg_int32_t _float32_unpack(long val,int *point){ |
||
| 46 | long mant=val&0x1fffff; |
||
| 47 | int sign=val&0x80000000; |
||
| 48 | long exp =(val&0x7fe00000L)>>VQ_FMAN; |
||
| 49 | |||
| 50 | exp-=(VQ_FMAN-1)+VQ_FEXP_BIAS; |
||
| 51 | |||
| 52 | if(mant){ |
||
| 53 | while(!(mant&0x40000000)){ |
||
| 54 | mant<<=1; |
||
| 55 | exp-=1; |
||
| 56 | } |
||
| 57 | |||
| 58 | if(sign)mant= -mant; |
||
| 59 | }else{ |
||
| 60 | sign=0; |
||
| 61 | exp=-9999; |
||
| 62 | } |
||
| 63 | |||
| 64 | *point=exp; |
||
| 65 | return mant; |
||
| 66 | } |
||
| 67 | |||
| 68 | /* given a list of word lengths, generate a list of codewords. Works |
||
| 69 | for length ordered or unordered, always assigns the lowest valued |
||
| 70 | codewords first. Extended to handle unused entries (length 0) */ |
||
| 71 | ogg_uint32_t *_make_words(long *l,long n,long sparsecount){ |
||
| 72 | long i,j,count=0; |
||
| 73 | ogg_uint32_t marker[33]; |
||
| 74 | ogg_uint32_t *r=(ogg_uint32_t *)_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r)); |
||
| 75 | memset(marker,0,sizeof(marker)); |
||
| 76 | |||
| 77 | for(i=0;i<n;i++){ |
||
| 78 | long length=l[i]; |
||
| 79 | if(length>0){ |
||
| 80 | ogg_uint32_t entry=marker[length]; |
||
| 81 | |||
| 82 | /* when we claim a node for an entry, we also claim the nodes |
||
| 83 | below it (pruning off the imagined tree that may have dangled |
||
| 84 | from it) as well as blocking the use of any nodes directly |
||
| 85 | above for leaves */ |
||
| 86 | |||
| 87 | /* update ourself */ |
||
| 88 | if(length<32 && (entry>>length)){ |
||
| 89 | /* error condition; the lengths must specify an overpopulated tree */ |
||
| 90 | _ogg_free(r); |
||
| 91 | return(NULL); |
||
| 92 | } |
||
| 93 | r[count++]=entry; |
||
| 94 | |||
| 95 | /* Look to see if the next shorter marker points to the node |
||
| 96 | above. if so, update it and repeat. */ |
||
| 97 | { |
||
| 98 | for(j=length;j>0;j--){ |
||
| 99 | |||
| 100 | if(marker[j]&1){ |
||
| 101 | /* have to jump branches */ |
||
| 102 | if(j==1) |
||
| 103 | marker[1]++; |
||
| 104 | else |
||
| 105 | marker[j]=marker[j-1]<<1; |
||
| 106 | break; /* invariant says next upper marker would already |
||
| 107 | have been moved if it was on the same path */ |
||
| 108 | } |
||
| 109 | marker[j]++; |
||
| 110 | } |
||
| 111 | } |
||
| 112 | |||
| 113 | /* prune the tree; the implicit invariant says all the longer |
||
| 114 | markers were dangling from our just-taken node. Dangle them |
||
| 115 | from our *new* node. */ |
||
| 116 | for(j=length+1;j<33;j++) |
||
| 117 | if((marker[j]>>1) == entry){ |
||
| 118 | entry=marker[j]; |
||
| 119 | marker[j]=marker[j-1]<<1; |
||
| 120 | }else |
||
| 121 | break; |
||
| 122 | }else |
||
| 123 | if(sparsecount==0)count++; |
||
| 124 | } |
||
| 125 | |||
| 126 | /* bitreverse the words because our bitwise packer/unpacker is LSb |
||
| 127 | endian */ |
||
| 128 | for(i=0,count=0;i<n;i++){ |
||
| 129 | ogg_uint32_t temp=0; |
||
| 130 | for(j=0;j<l[i];j++){ |
||
| 131 | temp<<=1; |
||
| 132 | temp|=(r[count]>>j)&1; |
||
| 133 | } |
||
| 134 | |||
| 135 | if(sparsecount){ |
||
| 136 | if(l[i]) |
||
| 137 | r[count++]=temp; |
||
| 138 | }else |
||
| 139 | r[count++]=temp; |
||
| 140 | } |
||
| 141 | |||
| 142 | return(r); |
||
| 143 | } |
||
| 144 | |||
| 145 | /* there might be a straightforward one-line way to do the below |
||
| 146 | that's portable and totally safe against roundoff, but I haven't |
||
| 147 | thought of it. Therefore, we opt on the side of caution */ |
||
| 148 | long _book_maptype1_quantvals(const static_codebook *b){ |
||
| 149 | /* get us a starting hint, we'll polish it below */ |
||
| 150 | int bits=_ilog(b->entries); |
||
| 151 | int vals=b->entries>>((bits-1)*(b->dim-1)/b->dim); |
||
| 152 | |||
| 153 | while(1){ |
||
| 154 | long acc=1; |
||
| 155 | long acc1=1; |
||
| 156 | int i; |
||
| 157 | for(i=0;i<b->dim;i++){ |
||
| 158 | acc*=vals; |
||
| 159 | acc1*=vals+1; |
||
| 160 | } |
||
| 161 | if(acc<=b->entries && acc1>b->entries){ |
||
| 162 | return(vals); |
||
| 163 | }else{ |
||
| 164 | if(acc>b->entries){ |
||
| 165 | vals--; |
||
| 166 | }else{ |
||
| 167 | vals++; |
||
| 168 | } |
||
| 169 | } |
||
| 170 | } |
||
| 171 | } |
||
| 172 | |||
| 173 | /* different than what _book_unquantize does for mainline: |
||
| 174 | we repack the book in a fixed point format that shares the same |
||
| 175 | binary point. Upon first use, we can shift point if needed */ |
||
| 176 | |||
| 177 | /* we need to deal with two map types: in map type 1, the values are |
||
| 178 | generated algorithmically (each column of the vector counts through |
||
| 179 | the values in the quant vector). in map type 2, all the values came |
||
| 180 | in in an explicit list. Both value lists must be unpacked */ |
||
| 181 | |||
| 182 | ogg_int32_t *_book_unquantize(const static_codebook *b,int n,int *sparsemap, |
||
| 183 | int *maxpoint){ |
||
| 184 | long j,k,count=0; |
||
| 185 | if(b->maptype==1 || b->maptype==2){ |
||
| 186 | int quantvals; |
||
| 187 | int minpoint,delpoint; |
||
| 188 | ogg_int32_t mindel=_float32_unpack(b->q_min,&minpoint); |
||
| 189 | ogg_int32_t delta=_float32_unpack(b->q_delta,&delpoint); |
||
| 190 | ogg_int32_t *r=(ogg_int32_t *)_ogg_calloc(n*b->dim,sizeof(*r)); |
||
| 191 | int *rp=(int *)_ogg_calloc(n*b->dim,sizeof(*rp)); |
||
| 192 | |||
| 193 | *maxpoint=minpoint; |
||
| 194 | |||
| 195 | /* maptype 1 and 2 both use a quantized value vector, but |
||
| 196 | different sizes */ |
||
| 197 | switch(b->maptype){ |
||
| 198 | case 1: |
||
| 199 | /* most of the time, entries%dimensions == 0, but we need to be |
||
| 200 | well defined. We define that the possible vales at each |
||
| 201 | scalar is values == entries/dim. If entries%dim != 0, we'll |
||
| 202 | have 'too few' values (values*dim<entries), which means that |
||
| 203 | we'll have 'left over' entries; left over entries use zeroed |
||
| 204 | values (and are wasted). So don't generate codebooks like |
||
| 205 | that */ |
||
| 206 | quantvals=_book_maptype1_quantvals(b); |
||
| 207 | for(j=0;j<b->entries;j++){ |
||
| 208 | if((sparsemap && b->lengthlist[j]) || !sparsemap){ |
||
| 209 | ogg_int32_t last=0; |
||
| 210 | int lastpoint=0; |
||
| 211 | int indexdiv=1; |
||
| 212 | for(k=0;k<b->dim;k++){ |
||
| 213 | int index= (j/indexdiv)%quantvals; |
||
| 214 | int point; |
||
| 215 | int val=VFLOAT_MULTI(delta,delpoint, |
||
| 216 | abs(b->quantlist[index]),&point); |
||
| 217 | |||
| 218 | val=VFLOAT_ADD(mindel,minpoint,val,point,&point); |
||
| 219 | val=VFLOAT_ADD(last,lastpoint,val,point,&point); |
||
| 220 | |||
| 221 | if(b->q_sequencep){ |
||
| 222 | last=val; |
||
| 223 | lastpoint=point; |
||
| 224 | } |
||
| 225 | |||
| 226 | if(sparsemap){ |
||
| 227 | r[sparsemap[count]*b->dim+k]=val; |
||
| 228 | rp[sparsemap[count]*b->dim+k]=point; |
||
| 229 | }else{ |
||
| 230 | r[count*b->dim+k]=val; |
||
| 231 | rp[count*b->dim+k]=point; |
||
| 232 | } |
||
| 233 | if(*maxpoint<point)*maxpoint=point; |
||
| 234 | indexdiv*=quantvals; |
||
| 235 | } |
||
| 236 | count++; |
||
| 237 | } |
||
| 238 | |||
| 239 | } |
||
| 240 | break; |
||
| 241 | case 2: |
||
| 242 | for(j=0;j<b->entries;j++){ |
||
| 243 | if((sparsemap && b->lengthlist[j]) || !sparsemap){ |
||
| 244 | ogg_int32_t last=0; |
||
| 245 | int lastpoint=0; |
||
| 246 | |||
| 247 | for(k=0;k<b->dim;k++){ |
||
| 248 | int point; |
||
| 249 | int val=VFLOAT_MULTI(delta,delpoint, |
||
| 250 | abs(b->quantlist[j*b->dim+k]),&point); |
||
| 251 | |||
| 252 | val=VFLOAT_ADD(mindel,minpoint,val,point,&point); |
||
| 253 | val=VFLOAT_ADD(last,lastpoint,val,point,&point); |
||
| 254 | |||
| 255 | if(b->q_sequencep){ |
||
| 256 | last=val; |
||
| 257 | lastpoint=point; |
||
| 258 | } |
||
| 259 | |||
| 260 | if(sparsemap){ |
||
| 261 | r[sparsemap[count]*b->dim+k]=val; |
||
| 262 | rp[sparsemap[count]*b->dim+k]=point; |
||
| 263 | }else{ |
||
| 264 | r[count*b->dim+k]=val; |
||
| 265 | rp[count*b->dim+k]=point; |
||
| 266 | } |
||
| 267 | if(*maxpoint<point)*maxpoint=point; |
||
| 268 | } |
||
| 269 | count++; |
||
| 270 | } |
||
| 271 | } |
||
| 272 | break; |
||
| 273 | } |
||
| 274 | |||
| 275 | for(j=0;j<n*b->dim;j++) |
||
| 276 | if(rp[j]<*maxpoint) |
||
| 277 | r[j]>>=*maxpoint-rp[j]; |
||
| 278 | |||
| 279 | _ogg_free(rp); |
||
| 280 | return(r); |
||
| 281 | } |
||
| 282 | return(NULL); |
||
| 283 | } |
||
| 284 | |||
| 285 | void vorbis_staticbook_clear(static_codebook *b){ |
||
| 286 | if(b->quantlist)_ogg_free(b->quantlist); |
||
| 287 | if(b->lengthlist)_ogg_free(b->lengthlist); |
||
| 288 | memset(b,0,sizeof(*b)); |
||
| 289 | |||
| 290 | } |
||
| 291 | |||
| 292 | void vorbis_staticbook_destroy(static_codebook *b){ |
||
| 293 | vorbis_staticbook_clear(b); |
||
| 294 | _ogg_free(b); |
||
| 295 | } |
||
| 296 | |||
| 297 | void vorbis_book_clear(codebook *b){ |
||
| 298 | /* static book is not cleared; we're likely called on the lookup and |
||
| 299 | the static codebook belongs to the info struct */ |
||
| 300 | if(b->valuelist)_ogg_free(b->valuelist); |
||
| 301 | if(b->codelist)_ogg_free(b->codelist); |
||
| 302 | |||
| 303 | if(b->dec_index)_ogg_free(b->dec_index); |
||
| 304 | if(b->dec_codelengths)_ogg_free(b->dec_codelengths); |
||
| 305 | if(b->dec_firsttable)_ogg_free(b->dec_firsttable); |
||
| 306 | |||
| 307 | memset(b,0,sizeof(*b)); |
||
| 308 | } |
||
| 309 | |||
| 310 | static ogg_uint32_t bitreverse(ogg_uint32_t x){ |
||
| 311 | x= ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL); |
||
| 312 | x= ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL); |
||
| 313 | x= ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL); |
||
| 314 | x= ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL); |
||
| 315 | return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL); |
||
| 316 | } |
||
| 317 | |||
| 318 | static int sort32a(const void *a,const void *b){ |
||
| 319 | return (**(ogg_uint32_t **)a>**(ogg_uint32_t **)b)- |
||
| 320 | (**(ogg_uint32_t **)a<**(ogg_uint32_t **)b); |
||
| 321 | } |
||
| 322 | |||
| 323 | /* decode codebook arrangement is more heavily optimized than encode */ |
||
| 324 | int vorbis_book_init_decode(codebook *c,const static_codebook *s){ |
||
| 325 | int i,j,n=0,tabn; |
||
| 326 | int *sortindex; |
||
| 327 | memset(c,0,sizeof(*c)); |
||
| 328 | |||
| 329 | /* count actually used entries */ |
||
| 330 | for(i=0;i<s->entries;i++) |
||
| 331 | if(s->lengthlist[i]>0) |
||
| 332 | n++; |
||
| 333 | |||
| 334 | c->entries=s->entries; |
||
| 335 | c->used_entries=n; |
||
| 336 | c->dim=s->dim; |
||
| 337 | |||
| 338 | c->q_min=s->q_min; |
||
| 339 | c->q_delta=s->q_delta; |
||
| 340 | |||
| 341 | /* two different remappings go on here. |
||
| 342 | |||
| 343 | First, we collapse the likely sparse codebook down only to |
||
| 344 | actually represented values/words. This collapsing needs to be |
||
| 345 | indexed as map-valueless books are used to encode original entry |
||
| 346 | positions as integers. |
||
| 347 | |||
| 348 | Second, we reorder all vectors, including the entry index above, |
||
| 349 | by sorted bitreversed codeword to allow treeless decode. */ |
||
| 350 | |||
| 351 | { |
||
| 352 | /* perform sort */ |
||
| 353 | ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); |
||
| 354 | ogg_uint32_t **codep=(ogg_uint32_t **)alloca(sizeof(*codep)*n); |
||
| 355 | |||
| 356 | if(codes==NULL)goto err_out; |
||
| 357 | |||
| 358 | for(i=0;i<n;i++){ |
||
| 359 | codes[i]=bitreverse(codes[i]); |
||
| 360 | codep[i]=codes+i; |
||
| 361 | } |
||
| 362 | |||
| 363 | qsort(codep,n,sizeof(*codep),sort32a); |
||
| 364 | |||
| 365 | sortindex=(int *)alloca(n*sizeof(*sortindex)); |
||
| 366 | c->codelist=(ogg_uint32_t *)_ogg_malloc(n*sizeof(*c->codelist)); |
||
| 367 | /* the index is a reverse index */ |
||
| 368 | for(i=0;i<n;i++){ |
||
| 369 | int position=codep[i]-codes; |
||
| 370 | sortindex[position]=i; |
||
| 371 | } |
||
| 372 | |||
| 373 | for(i=0;i<n;i++) |
||
| 374 | c->codelist[sortindex[i]]=codes[i]; |
||
| 375 | _ogg_free(codes); |
||
| 376 | } |
||
| 377 | |||
| 378 | |||
| 379 | c->valuelist=_book_unquantize(s,n,sortindex,&c->binarypoint); |
||
| 380 | c->dec_index=(int *)_ogg_malloc(n*sizeof(*c->dec_index)); |
||
| 381 | |||
| 382 | for(n=0,i=0;i<s->entries;i++) |
||
| 383 | if(s->lengthlist[i]>0) |
||
| 384 | c->dec_index[sortindex[n++]]=i; |
||
| 385 | |||
| 386 | c->dec_codelengths=(char *)_ogg_malloc(n*sizeof(*c->dec_codelengths)); |
||
| 387 | for(n=0,i=0;i<s->entries;i++) |
||
| 388 | if(s->lengthlist[i]>0) |
||
| 389 | c->dec_codelengths[sortindex[n++]]=s->lengthlist[i]; |
||
| 390 | |||
| 391 | c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */ |
||
| 392 | if(c->dec_firsttablen<5)c->dec_firsttablen=5; |
||
| 393 | if(c->dec_firsttablen>8)c->dec_firsttablen=8; |
||
| 394 | |||
| 395 | tabn=1<<c->dec_firsttablen; |
||
| 396 | c->dec_firsttable=(ogg_uint32_t *)_ogg_calloc(tabn,sizeof(*c->dec_firsttable)); |
||
| 397 | c->dec_maxlength=0; |
||
| 398 | |||
| 399 | for(i=0;i<n;i++){ |
||
| 400 | if(c->dec_maxlength<c->dec_codelengths[i]) |
||
| 401 | c->dec_maxlength=c->dec_codelengths[i]; |
||
| 402 | if(c->dec_codelengths[i]<=c->dec_firsttablen){ |
||
| 403 | ogg_uint32_t orig=bitreverse(c->codelist[i]); |
||
| 404 | for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++) |
||
| 405 | c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1; |
||
| 406 | } |
||
| 407 | } |
||
| 408 | |||
| 409 | /* now fill in 'unused' entries in the firsttable with hi/lo search |
||
| 410 | hints for the non-direct-hits */ |
||
| 411 | { |
||
| 412 | ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen); |
||
| 413 | long lo=0,hi=0; |
||
| 414 | |||
| 415 | for(i=0;i<tabn;i++){ |
||
| 416 | ogg_uint32_t word=i<<(32-c->dec_firsttablen); |
||
| 417 | if(c->dec_firsttable[bitreverse(word)]==0){ |
||
| 418 | while((lo+1)<n && c->codelist[lo+1]<=word)lo++; |
||
| 419 | while( hi<n && word>=(c->codelist[hi]&mask))hi++; |
||
| 420 | |||
| 421 | /* we only actually have 15 bits per hint to play with here. |
||
| 422 | In order to overflow gracefully (nothing breaks, efficiency |
||
| 423 | just drops), encode as the difference from the extremes. */ |
||
| 424 | { |
||
| 425 | unsigned long loval=lo; |
||
| 426 | unsigned long hival=n-hi; |
||
| 427 | |||
| 428 | if(loval>0x7fff)loval=0x7fff; |
||
| 429 | if(hival>0x7fff)hival=0x7fff; |
||
| 430 | c->dec_firsttable[bitreverse(word)]= |
||
| 431 | 0x80000000UL | (loval<<15) | hival; |
||
| 432 | } |
||
| 433 | } |
||
| 434 | } |
||
| 435 | } |
||
| 436 | |||
| 437 | |||
| 438 | return(0); |
||
| 439 | err_out: |
||
| 440 | vorbis_book_clear(c); |
||
| 441 | return(-1); |
||
| 442 | } |
||
| 443 |