media/libtremor/lib/tremor_sharedbook.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial