media/libtremor/lib/tremor_codebook.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 codebook pack/unpack/code/decode operations
michael@0 15
michael@0 16 ********************************************************************/
michael@0 17
michael@0 18 #include <stdlib.h>
michael@0 19 #include <string.h>
michael@0 20 #include <math.h>
michael@0 21 #include <ogg/ogg.h>
michael@0 22 #include "ivorbiscodec.h"
michael@0 23 #include "codebook.h"
michael@0 24 #include "misc.h"
michael@0 25
michael@0 26 /* unpacks a codebook from the packet buffer into the codebook struct,
michael@0 27 readies the codebook auxiliary structures for decode *************/
michael@0 28 static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
michael@0 29 long i,j;
michael@0 30 static_codebook *s=_ogg_calloc(1,sizeof(*s));
michael@0 31
michael@0 32 /* make sure alignment is correct */
michael@0 33 if(oggpack_read(opb,24)!=0x564342)goto _eofout;
michael@0 34
michael@0 35 /* first the basic parameters */
michael@0 36 s->dim=oggpack_read(opb,16);
michael@0 37 s->entries=oggpack_read(opb,24);
michael@0 38 if(s->entries==-1)goto _eofout;
michael@0 39
michael@0 40 if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
michael@0 41
michael@0 42 /* codeword ordering.... length ordered or unordered? */
michael@0 43 switch((int)oggpack_read(opb,1)){
michael@0 44 case 0:{
michael@0 45 long unused;
michael@0 46 /* allocated but unused entries? */
michael@0 47 unused=oggpack_read(opb,1);
michael@0 48 if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb))
michael@0 49 goto _eofout;
michael@0 50 /* unordered */
michael@0 51 s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
michael@0 52
michael@0 53 /* allocated but unused entries? */
michael@0 54 if(unused){
michael@0 55 /* yes, unused entries */
michael@0 56
michael@0 57 for(i=0;i<s->entries;i++){
michael@0 58 if(oggpack_read(opb,1)){
michael@0 59 long num=oggpack_read(opb,5);
michael@0 60 if(num==-1)goto _eofout;
michael@0 61 s->lengthlist[i]=num+1;
michael@0 62 }else
michael@0 63 s->lengthlist[i]=0;
michael@0 64 }
michael@0 65 }else{
michael@0 66 /* all entries used; no tagging */
michael@0 67 for(i=0;i<s->entries;i++){
michael@0 68 long num=oggpack_read(opb,5);
michael@0 69 if(num==-1)goto _eofout;
michael@0 70 s->lengthlist[i]=num+1;
michael@0 71 }
michael@0 72 }
michael@0 73
michael@0 74 break;
michael@0 75 }
michael@0 76 case 1:
michael@0 77 /* ordered */
michael@0 78 {
michael@0 79 long length=oggpack_read(opb,5)+1;
michael@0 80 if(length==0)goto _eofout;
michael@0 81 s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
michael@0 82
michael@0 83 for(i=0;i<s->entries;){
michael@0 84 long num=oggpack_read(opb,_ilog(s->entries-i));
michael@0 85 if(num==-1)goto _eofout;
michael@0 86 if(length>32 || num>s->entries-i ||
michael@0 87 (num>0 && (num-1)>>(length>>1)>>((length+1)>>1))>0){
michael@0 88 goto _errout;
michael@0 89 }
michael@0 90 for(j=0;j<num;j++,i++)
michael@0 91 s->lengthlist[i]=length;
michael@0 92 length++;
michael@0 93 }
michael@0 94 }
michael@0 95 break;
michael@0 96 default:
michael@0 97 /* EOF */
michael@0 98 goto _eofout;
michael@0 99 }
michael@0 100
michael@0 101 /* Do we have a mapping to unpack? */
michael@0 102 switch((s->maptype=oggpack_read(opb,4))){
michael@0 103 case 0:
michael@0 104 /* no mapping */
michael@0 105 break;
michael@0 106 case 1: case 2:
michael@0 107 /* implicitly populated value mapping */
michael@0 108 /* explicitly populated value mapping */
michael@0 109
michael@0 110 s->q_min=oggpack_read(opb,32);
michael@0 111 s->q_delta=oggpack_read(opb,32);
michael@0 112 s->q_quant=oggpack_read(opb,4)+1;
michael@0 113 s->q_sequencep=oggpack_read(opb,1);
michael@0 114 if(s->q_sequencep==-1)goto _eofout;
michael@0 115
michael@0 116 {
michael@0 117 int quantvals=0;
michael@0 118 switch(s->maptype){
michael@0 119 case 1:
michael@0 120 quantvals=(s->dim==0?0:_book_maptype1_quantvals(s));
michael@0 121 break;
michael@0 122 case 2:
michael@0 123 quantvals=s->entries*s->dim;
michael@0 124 break;
michael@0 125 }
michael@0 126
michael@0 127 /* quantized values */
michael@0 128 if((quantvals*s->q_quant+7)>>3>opb->storage-oggpack_bytes(opb))
michael@0 129 goto _eofout;
michael@0 130 s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
michael@0 131 for(i=0;i<quantvals;i++)
michael@0 132 s->quantlist[i]=oggpack_read(opb,s->q_quant);
michael@0 133
michael@0 134 if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
michael@0 135 }
michael@0 136 break;
michael@0 137 default:
michael@0 138 goto _errout;
michael@0 139 }
michael@0 140
michael@0 141 /* all set */
michael@0 142 return(s);
michael@0 143
michael@0 144 _errout:
michael@0 145 _eofout:
michael@0 146 vorbis_staticbook_destroy(s);
michael@0 147 return(NULL);
michael@0 148 }
michael@0 149
michael@0 150 /* the 'eliminate the decode tree' optimization actually requires the
michael@0 151 codewords to be MSb first, not LSb. This is an annoying inelegancy
michael@0 152 (and one of the first places where carefully thought out design
michael@0 153 turned out to be wrong; Vorbis II and future Ogg codecs should go
michael@0 154 to an MSb bitpacker), but not actually the huge hit it appears to
michael@0 155 be. The first-stage decode table catches most words so that
michael@0 156 bitreverse is not in the main execution path. */
michael@0 157
michael@0 158 static ogg_uint32_t bitreverse(ogg_uint32_t x){
michael@0 159 x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
michael@0 160 x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
michael@0 161 x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
michael@0 162 x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
michael@0 163 return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
michael@0 164 }
michael@0 165
michael@0 166 STIN long decode_packed_entry_number(codebook *book,
michael@0 167 oggpack_buffer *b){
michael@0 168 int read=book->dec_maxlength;
michael@0 169 long lo,hi;
michael@0 170 long lok = oggpack_look(b,book->dec_firsttablen);
michael@0 171
michael@0 172 if (lok >= 0) {
michael@0 173 long entry = book->dec_firsttable[lok];
michael@0 174 if(entry&0x80000000UL){
michael@0 175 lo=(entry>>15)&0x7fff;
michael@0 176 hi=book->used_entries-(entry&0x7fff);
michael@0 177 }else{
michael@0 178 oggpack_adv(b, book->dec_codelengths[entry-1]);
michael@0 179 return(entry-1);
michael@0 180 }
michael@0 181 }else{
michael@0 182 lo=0;
michael@0 183 hi=book->used_entries;
michael@0 184 }
michael@0 185
michael@0 186 lok = oggpack_look(b, read);
michael@0 187
michael@0 188 while(lok<0 && read>1)
michael@0 189 lok = oggpack_look(b, --read);
michael@0 190
michael@0 191 if(lok<0){
michael@0 192 oggpack_adv(b,1); /* force eop */
michael@0 193 return -1;
michael@0 194 }
michael@0 195
michael@0 196 /* bisect search for the codeword in the ordered list */
michael@0 197 {
michael@0 198 ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
michael@0 199
michael@0 200 while(hi-lo>1){
michael@0 201 long p=(hi-lo)>>1;
michael@0 202 long test=book->codelist[lo+p]>testword;
michael@0 203 lo+=p&(test-1);
michael@0 204 hi-=p&(-test);
michael@0 205 }
michael@0 206
michael@0 207 if(book->dec_codelengths[lo]<=read){
michael@0 208 oggpack_adv(b, book->dec_codelengths[lo]);
michael@0 209 return(lo);
michael@0 210 }
michael@0 211 }
michael@0 212
michael@0 213 oggpack_adv(b, read+1);
michael@0 214 return(-1);
michael@0 215 }
michael@0 216
michael@0 217 /* Decode side is specced and easier, because we don't need to find
michael@0 218 matches using different criteria; we simply read and map. There are
michael@0 219 two things we need to do 'depending':
michael@0 220
michael@0 221 We may need to support interleave. We don't really, but it's
michael@0 222 convenient to do it here rather than rebuild the vector later.
michael@0 223
michael@0 224 Cascades may be additive or multiplicitive; this is not inherent in
michael@0 225 the codebook, but set in the code using the codebook. Like
michael@0 226 interleaving, it's easiest to do it here.
michael@0 227 addmul==0 -> declarative (set the value)
michael@0 228 addmul==1 -> additive
michael@0 229 addmul==2 -> multiplicitive */
michael@0 230
michael@0 231 /* returns the [original, not compacted] entry number or -1 on eof *********/
michael@0 232 long vorbis_book_decode(codebook *book, oggpack_buffer *b){
michael@0 233 if(book->used_entries>0){
michael@0 234 long packed_entry=decode_packed_entry_number(book,b);
michael@0 235 if(packed_entry>=0)
michael@0 236 return(book->dec_index[packed_entry]);
michael@0 237 }
michael@0 238
michael@0 239 /* if there's no dec_index, the codebook unpacking isn't collapsed */
michael@0 240 return(-1);
michael@0 241 }
michael@0 242
michael@0 243 /* returns 0 on OK or -1 on eof *************************************/
michael@0 244 /* decode vector / dim granularity gaurding is done in the upper layer */
michael@0 245 long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a,
michael@0 246 oggpack_buffer *b,int n,int point){
michael@0 247 if(book->used_entries>0){
michael@0 248 int step=n/book->dim;
michael@0 249 long *entry = (long *)alloca(sizeof(*entry)*step);
michael@0 250 ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step);
michael@0 251 int i,j,o;
michael@0 252 int shift=point-book->binarypoint;
michael@0 253
michael@0 254 if(shift>=0){
michael@0 255 for (i = 0; i < step; i++) {
michael@0 256 entry[i]=decode_packed_entry_number(book,b);
michael@0 257 if(entry[i]==-1)return(-1);
michael@0 258 t[i] = book->valuelist+entry[i]*book->dim;
michael@0 259 }
michael@0 260 for(i=0,o=0;i<book->dim;i++,o+=step)
michael@0 261 for (j=0;j<step;j++)
michael@0 262 a[o+j]+=t[j][i]>>shift;
michael@0 263 }else{
michael@0 264 for (i = 0; i < step; i++) {
michael@0 265 entry[i]=decode_packed_entry_number(book,b);
michael@0 266 if(entry[i]==-1)return(-1);
michael@0 267 t[i] = book->valuelist+entry[i]*book->dim;
michael@0 268 }
michael@0 269 for(i=0,o=0;i<book->dim;i++,o+=step)
michael@0 270 for (j=0;j<step;j++)
michael@0 271 a[o+j]+=t[j][i]<<-shift;
michael@0 272 }
michael@0 273 }
michael@0 274 return(0);
michael@0 275 }
michael@0 276
michael@0 277 /* decode vector / dim granularity gaurding is done in the upper layer */
michael@0 278 long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a,
michael@0 279 oggpack_buffer *b,int n,int point){
michael@0 280 if(book->used_entries>0){
michael@0 281 int i,j,entry;
michael@0 282 ogg_int32_t *t;
michael@0 283 int shift=point-book->binarypoint;
michael@0 284
michael@0 285 if(shift>=0){
michael@0 286 for(i=0;i<n;){
michael@0 287 entry = decode_packed_entry_number(book,b);
michael@0 288 if(entry==-1)return(-1);
michael@0 289 t = book->valuelist+entry*book->dim;
michael@0 290 for (j=0;j<book->dim;)
michael@0 291 a[i++]+=t[j++]>>shift;
michael@0 292 }
michael@0 293 }else{
michael@0 294 for(i=0;i<n;){
michael@0 295 entry = decode_packed_entry_number(book,b);
michael@0 296 if(entry==-1)return(-1);
michael@0 297 t = book->valuelist+entry*book->dim;
michael@0 298 for (j=0;j<book->dim;)
michael@0 299 a[i++]+=t[j++]<<-shift;
michael@0 300 }
michael@0 301 }
michael@0 302 }
michael@0 303 return(0);
michael@0 304 }
michael@0 305
michael@0 306 /* unlike the others, we guard against n not being an integer number
michael@0 307 of <dim> internally rather than in the upper layer (called only by
michael@0 308 floor0) */
michael@0 309 long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a,
michael@0 310 oggpack_buffer *b,int n,int point){
michael@0 311 if(book->used_entries>0){
michael@0 312 int i,j,entry;
michael@0 313 ogg_int32_t *t;
michael@0 314 int shift=point-book->binarypoint;
michael@0 315
michael@0 316 if(shift>=0){
michael@0 317
michael@0 318 for(i=0;i<n;){
michael@0 319 entry = decode_packed_entry_number(book,b);
michael@0 320 if(entry==-1)return(-1);
michael@0 321 t = book->valuelist+entry*book->dim;
michael@0 322 for (j=0;i<n && j<book->dim;){
michael@0 323 a[i++]=t[j++]>>shift;
michael@0 324 }
michael@0 325 }
michael@0 326 }else{
michael@0 327
michael@0 328 for(i=0;i<n;){
michael@0 329 entry = decode_packed_entry_number(book,b);
michael@0 330 if(entry==-1)return(-1);
michael@0 331 t = book->valuelist+entry*book->dim;
michael@0 332 for (j=0;i<n && j<book->dim;){
michael@0 333 a[i++]=t[j++]<<-shift;
michael@0 334 }
michael@0 335 }
michael@0 336 }
michael@0 337 }else{
michael@0 338
michael@0 339 int i,j;
michael@0 340 for(i=0;i<n;){
michael@0 341 a[i++]=0;
michael@0 342 }
michael@0 343 }
michael@0 344 return(0);
michael@0 345 }
michael@0 346
michael@0 347 /* decode vector / dim granularity gaurding is done in the upper layer */
michael@0 348 long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,\
michael@0 349 long offset,int ch,
michael@0 350 oggpack_buffer *b,int n,int point){
michael@0 351 if(book->used_entries>0){
michael@0 352 long i,j,entry;
michael@0 353 int chptr=0;
michael@0 354 int shift=point-book->binarypoint;
michael@0 355
michael@0 356 if(shift>=0){
michael@0 357
michael@0 358 for(i=offset;i<offset+n;){
michael@0 359 entry = decode_packed_entry_number(book,b);
michael@0 360 if(entry==-1)return(-1);
michael@0 361 {
michael@0 362 const ogg_int32_t *t = book->valuelist+entry*book->dim;
michael@0 363 for (j=0;j<book->dim;j++){
michael@0 364 a[chptr++][i]+=t[j]>>shift;
michael@0 365 if(chptr==ch){
michael@0 366 chptr=0;
michael@0 367 i++;
michael@0 368 }
michael@0 369 }
michael@0 370 }
michael@0 371 }
michael@0 372 }else{
michael@0 373
michael@0 374 for(i=offset;i<offset+n;){
michael@0 375 entry = decode_packed_entry_number(book,b);
michael@0 376 if(entry==-1)return(-1);
michael@0 377 {
michael@0 378 const ogg_int32_t *t = book->valuelist+entry*book->dim;
michael@0 379 for (j=0;j<book->dim;j++){
michael@0 380 a[chptr++][i]+=t[j]<<-shift;
michael@0 381 if(chptr==ch){
michael@0 382 chptr=0;
michael@0 383 i++;
michael@0 384 }
michael@0 385 }
michael@0 386 }
michael@0 387 }
michael@0 388 }
michael@0 389 }
michael@0 390 return(0);
michael@0 391 }

mercurial