examples/sfexamples/oggvorbiscodec/src/tremor/sharedbook.c

00001 /********************************************************************
00002  *                                                                  *
00003  * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *
00004  *                                                                  *
00005  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
00006  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
00007  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
00008  *                                                                  *
00009  * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
00010  * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
00011  *                                                                  *
00012  ********************************************************************
00013 
00014  function: basic shared codebook operations
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 /**** pack/unpack helpers ******************************************/
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 /* 32 bit float (not IEEE; nonnormalized mantissa +
00038    biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm 
00039    Why not IEEE?  It's just not that important here. */
00040 
00041 #define VQ_FEXP 10
00042 #define VQ_FMAN 21
00043 #define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */
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 /* given a list of word lengths, generate a list of codewords.  Works
00069    for length ordered or unordered, always assigns the lowest valued
00070    codewords first.  Extended to handle unused entries (length 0) */
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       /* when we claim a node for an entry, we also claim the nodes
00083          below it (pruning off the imagined tree that may have dangled
00084          from it) as well as blocking the use of any nodes directly
00085          above for leaves */
00086       
00087       /* update ourself */
00088       if(length<32 && (entry>>length)){
00089         /* error condition; the lengths must specify an overpopulated tree */
00090         _ogg_free(r);
00091         return(NULL);
00092       }
00093       r[count++]=entry;
00094     
00095       /* Look to see if the next shorter marker points to the node
00096          above. if so, update it and repeat.  */
00097       {
00098         for(j=length;j>0;j--){
00099           
00100           if(marker[j]&1){
00101             /* have to jump branches */
00102             if(j==1)
00103               marker[1]++;
00104             else
00105               marker[j]=marker[j-1]<<1;
00106             break; /* invariant says next upper marker would already
00107                       have been moved if it was on the same path */
00108           }
00109           marker[j]++;
00110         }
00111       }
00112       
00113       /* prune the tree; the implicit invariant says all the longer
00114          markers were dangling from our just-taken node.  Dangle them
00115          from our *new* node. */
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   /* bitreverse the words because our bitwise packer/unpacker is LSb
00127      endian */
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 /* there might be a straightforward one-line way to do the below
00146    that's portable and totally safe against roundoff, but I haven't
00147    thought of it.  Therefore, we opt on the side of caution */
00148 long _book_maptype1_quantvals(const static_codebook *b){
00149   /* get us a starting hint, we'll polish it below */
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 /* different than what _book_unquantize does for mainline:
00174    we repack the book in a fixed point format that shares the same
00175    binary point.  Upon first use, we can shift point if needed */
00176 
00177 /* we need to deal with two map types: in map type 1, the values are
00178    generated algorithmically (each column of the vector counts through
00179    the values in the quant vector). in map type 2, all the values came
00180    in in an explicit list.  Both value lists must be unpacked */
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     /* maptype 1 and 2 both use a quantized value vector, but
00196        different sizes */
00197     switch(b->maptype){
00198     case 1:
00199       /* most of the time, entries%dimensions == 0, but we need to be
00200          well defined.  We define that the possible vales at each
00201          scalar is values == entries/dim.  If entries%dim != 0, we'll
00202          have 'too few' values (values*dim<entries), which means that
00203          we'll have 'left over' entries; left over entries use zeroed
00204          values (and are wasted).  So don't generate codebooks like
00205          that */
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   /* static book is not cleared; we're likely called on the lookup and
00299      the static codebook belongs to the info struct */
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 /* decode codebook arrangement is more heavily optimized than encode */
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   /* count actually used entries */
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   /* two different remappings go on here.  
00342 
00343      First, we collapse the likely sparse codebook down only to
00344      actually represented values/words.  This collapsing needs to be
00345      indexed as map-valueless books are used to encode original entry
00346      positions as integers.
00347 
00348      Second, we reorder all vectors, including the entry index above,
00349      by sorted bitreversed codeword to allow treeless decode. */
00350 
00351   {
00352     /* perform sort */
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     /* the index is a reverse index */
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; /* this is magic */
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   /* now fill in 'unused' entries in the firsttable with hi/lo search
00410      hints for the non-direct-hits */
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         /* we only actually have 15 bits per hint to play with here.
00422            In order to overflow gracefully (nothing breaks, efficiency
00423            just drops), encode as the difference from the extremes. */
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 

Generated by  doxygen 1.6.2